Arduino Uno code uploads, but same code to Wemos D1 Mini fails - RF TRANSMITTER

Hello,
I’m a rather novice to arduino ide coding, but my questions are two-fold.

1. This same code when uploading to Arduino succeeds, but when uploading to Wemos D1 Mini fails. Why?

If I use this code and run from Arduino, my RF controlled ceiling fans respond. I cannot get it to upload to Wemos D1 Mini however in order to control my RF fans via internet.

Here is the shortened code listing only 2 RF signals:

FYI: I Had to chop down some of the binary numbers to meet 9000 character limit. There is total of 266 0’s & 1’s.

//RF Transmitter code
int a;
boolean recordedSignal_fanlow[] =     {1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0};
boolean recordedSignal_lightoffon[] = {1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0};
#define GND 3
#define VCC 4
#define DATA 5
int rfwait = 8000;


void setup() {
  pinMode(GND, OUTPUT);
  pinMode(VCC, OUTPUT);
  pinMode(DATA, OUTPUT);

  digitalWrite(GND, LOW);
  digitalWrite(VCC, HIGH);
}

void fanlow() {
  for (a = 0; a < 8; a++) {
    for (int i = 0; i < sizeof(recordedSignal_fanlow) - 1; i++) {
      digitalWrite(DATA, recordedSignal_fanlow[i]);
      delayMicroseconds(393.9);
    }
[b]    digitalWrite(DATA, recordedSignal_fanlow);
[/b]
    delayMicroseconds(9000);
  }
  delay(rfwait);
}

void lightoffon() {
  for (a = 0; a < 10; a++) {{
    for (int i = 0; i < sizeof(recordedSignal_lightoffon) - 1; i++) {
      digitalWrite(DATA, recordedSignal_lightoffon[i]);
          delayMicroseconds(393.9);
    }
[b]    digitalWrite(DATA, recordedSignal_lightoffon);
[/b] 
    delayMicroseconds(39);
  }
  delay(rfwait);
}}

void loop() {
	lightoffon;
	delay(4000);
}

Here is the failure:

Arduino: 1.8.13 (Windows 7), Board: "WeMos D1 R1, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), v2 Lower Memory, Disabled, None, Only Sketch, 921600"
C:\Users\Admin\Documents\Arduino\RF_TRANSMITTER\RF_TRANSMITTER.ino: In function 'void lightoffon()':
RF_TRANSMITTER:81:49: error: invalid conversion from 'boolean* {aka bool*}' to 'uint8_t {aka unsigned char}' [-fpermissive]

     digitalWrite(DATA, recordedSignal_lightoffon);

                                                 ^
In file included from sketch\RF_TRANSMITTER.ino.cpp:1:0:

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/Arduino.h:179:6: error:   initializing argument 2 of 'void digitalWrite(uint8_t, uint8_t)' [-fpermissive]

 void digitalWrite(uint8_t pin, uint8_t val);

      ^

exit status 1
invalid conversion from 'boolean* {aka bool*}' to 'uint8_t {aka unsigned char}' [-fpermissive]

2. Is there a way I can shorten my code to use the specific fan signal based upon a specific MQTT payload received?

For example, in the final development, this will subscribe to a MQTT topic/payload and upon receiving that payload will transmit the appropriate signal. Currently I have a list of about 10 if/else statements for each topic, but was wondering if I could achieve something like…
"if MQTT Payload X was received, the variable RECORDED_SIGNAL would be assigned to either lightoffon, fanlow, fanmed, etc and then implemented into void function { ).

I hope that makes a somewhat bit of sense.

My Code right now has 6 unique functions:

  • fan off
  • fan low speed
  • fan medium speed
  • fan high speed
  • fan light off
  • fan light on

but because there are 2 rooms, it actually has 12 functions. I was hoping I could shorten this down and make the code a bit ‘cleaner’ / legible.

Example:

// Function called by callback() when a message is received 
// Passes the message topic as the "requestedRoom" parameter and the message payload as the "requestedAction" parameter
// THIS JUST PRINTS OUT THE ACTION AND MESSAGE RECEIVED VIA SERIAL CONNECTION
void triggerBedroomAction(String requestedRoom, String requestedAction) {
  if  (requestedRoom == mqtt_room2_fan_action_topic && requestedAction == "1") {
    Serial.print("Setting ");
    Serial.print(bedroom2_alias);
    Serial.println("'s fan speed to low!");
      client.publish(mqtt_room2_fan_status_topic, "1");
      client.publish(mqtt_room2_fan_status_topic, FanResult1);
        {
        for (a = 0; a < 8; a++) {
        for (int i = 0; i < sizeof(recordedSignal_fanlow2) - 1; i++) {
        digitalWrite(transmitter_pin, recordedSignal_fanlow2[i]);
        delayMicroseconds(393.9);
        }
        delayMicroseconds(9000);  }
        delay(800);
        }
  }
  else if (requestedRoom == mqtt_room2_fan_action_topic && requestedAction == "2") {
    Serial.print("Setting ");
    Serial.print(bedroom2_alias);
    Serial.println("'s fan speed to medium!");
      client.publish(mqtt_room2_fan_status_topic, "2");
      client.publish(mqtt_room2_fan_status_topic, FanResult2);
        {
        for (a = 0; a < 8; a++) {
        for (int i = 0; i < sizeof(recordedSignal_fanmed2) - 1; i++) {
        digitalWrite(transmitter_pin, recordedSignal_fanmed2[i]);
        delayMicroseconds(393.9);
        }
        delayMicroseconds(9000);
        }
        delay(800);
        }
  }
  else if (requestedRoom == mqtt_room2_fan_action_topic && requestedAction == "3") {
    Serial.print("Setting ");
    Serial.print(bedroom2_alias);
    Serial.println("'s fan speed to high!");
      client.publish(mqtt_room2_fan_status_topic, "3");
      client.publish(mqtt_room2_fan_status_topic, FanResult3);
        {
        for (a = 0; a < 8; a++) {
        for (int i = 0; i < sizeof(recordedSignal_fanhigh2) - 1; i++) {
        digitalWrite(transmitter_pin, recordedSignal_fanhigh2[i]);
        delayMicroseconds(393.9);
        }
        delayMicroseconds(9000);
        }
        delay(800);
        }
  }
  else if (requestedRoom == mqtt_room2_fan_action_topic && requestedAction == "0") {
    Serial.print("Setting ");
    Serial.print(bedroom2_alias);
    Serial.println("'s fan off!");
      client.publish(mqtt_room2_fan_status_topic, "0");
      client.publish(mqtt_room2_fan_status_topic, FanResult0);
        {
        for (a = 0; a < 8; a++) {
        for (int i = 0; i < sizeof(recordedSignal_fanoff2) - 1; i++) {
        digitalWrite(transmitter_pin, recordedSignal_fanoff2[i]);
        delayMicroseconds(393.9);
        }
        delayMicroseconds(9000);
        }
        delay(800);
        }
  }
  else if (requestedRoom == mqtt_room2_light_action_topic && requestedAction == "off") {
    Serial.print("Changing ");
    Serial.print(bedroom2_alias);
    Serial.println("'s light status!");
      client.publish(mqtt_room2_light_status_topic, "off");
        {
        for (a = 0; a < 8; a++) {
        for (int i = 0; i < sizeof(recordedSignal_lightoffon2) - 1; i++) {
        digitalWrite(transmitter_pin, recordedSignal_lightoffon2[i]);
        delayMicroseconds(393.9);
        }
        delayMicroseconds(9000);
        }
        delay(600);
        }
  }
  else if (requestedRoom == mqtt_room2_light_action_topic && requestedAction == "on") {
    Serial.print("Changing ");
    Serial.print(bedroom2_alias);
    Serial.println("'s light status!");
      client.publish(mqtt_room2_light_status_topic, "on"); 
        {
        for (a = 0; a < 8; a++) {
        for (int i = 0; i < sizeof(recordedSignal_lightoffon2) - 1; i++) {
        digitalWrite(transmitter_pin, recordedSignal_lightoffon2[i]);
        delayMicroseconds(393.9);
        }
        delayMicroseconds(9000);
        }
        delay(600);
        }
  }  
  else { Serial.println("Unrecognized action payload... taking no action!");
 }
}
//ENDS THE ACTION OF WRITING IN SERIAL WHAT WAS RECEIVED AND WHAT IT WAS TOLD TO DO

I’m attaching also my full code if any of the above is unclear.

So to recap:
What is it in my code that is causing the upload to fail to Wemos but not Arduino that I need to fix?
How can I fix it?
Is it possible to clean/shorten my code?

Any and all input and help is greatly appreciated!!!
I’ve spent so many hours on this already, I think I am in the +60 hours unfortunately…

MQTT_WIFI_MGR2_RF_TRANSMITTER.txt (20.2 KB)

So change 'boolean recordedSignal_lightoffon' to 'uint8_t recordedSignal_lightoffon'.

sadly, that did not allow me to upload.

Arduino: 1.8.13 (Windows 7), Board: "WeMos D1 R1, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), v2 Lower Memory, Disabled, None, Only Sketch, 921600"

C:\Users\Scotty\Documents\Arduino\RF_TRANSMITTER\RF_TRANSMITTER.ino: In function 'void loop()':

RF_TRANSMITTER:129:49: error: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'uint8_t {aka unsigned char}' [-fpermissive]

     digitalWrite(DATA, recordedSignal_lightoffon);

                                                 ^

In file included from sketch\RF_TRANSMITTER.ino.cpp:1:0:

C:\Users\Admin\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/Arduino.h:179:6: error:   initializing argument 2 of 'void digitalWrite(uint8_t, uint8_t)' [-fpermissive]

 void digitalWrite(uint8_t pin, uint8_t val);

      ^

exit status 1

invalid conversion from 'uint8_t* {aka unsigned char*}' to 'uint8_t {aka unsigned char}' [-fpermissive]



This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

I can upload to arduino uno, as is, but if I change my board, port, programmer to the Wemos D1 Mini, it throws out the error

You’re calling digitalWrite() which requires a uint8_t (or unsigned char) as the second argument. But, you’re trying to pass a pointer (in the form of an array name) as the second argument:

digitalWrite(DATA, recordedSignal_lightoffon);

That’s not going to work.

Turn up the compiler warnings under File → Preferences and you’ll see complaints when trying to compile the same thing for an Uno. But for some reason it lets it slide as only a warning for that board.

Either way, what you’re doing is wrong.

wow, thanks @gfvalvo ! So if what I'm doing is wrong, is there any way to have the Wemos Disregard as well? The code seems to be working fine.

If not, do you think you would have a suggestion on how to send high's and low's out the DATA port in the same pattern with a 393.9us delay in between (thus making the same RF signal the fan is looking for)?

This was how I copied the signal:

I don't understand why that line is in there at all. Isn't the 'for' loop above it doing what you want?

Also, the delayMicroseconds() function takes an 'unsigned int' argument, not a float. So, 393.9 gets truncated to 393.

@gfvalvo , thank you, you were right. I don't actually need that and was able to get my code to load and execute just fine. I had to return back to the wemos port layout sheet to get the port numbers right, but it's running it's loop now fine and turning off/on the light just fine.

I know it's remedial, and just for cleanliness but, do you have any ideas on my second question?
Do you think it'd be possible to define a variable outside of a loop to implement into a single function vs. having 12 if/else statements?

For Q#2, if the arrays have the same size, just declare a byte* and assign the pointer of the right array to it and then perform the loop.

Code is incomplete for seeing all the values for requestedRoom and requestedAction. If you have control over it you could ensure the requestedRoom is an index in an array describing your setup and requestedAction would help choose the right array.

@J-M-L, I'm super novice.
I'm not sure I know what you mean.
I have tried previously to run if/else statements that say :
If MQTT payload X received, then recordedSignal = recordedSignal_fanlow, else if MQTT payload Y received, then recordedSignal = recordedSignal_fanmed, and etc etc, but it has not worked.

I created multiple void functions... which.... now that I know my Wemos is working right... couldn't I just call all the 12 functions... and then if MQTT payload = fanlow then 'function' fanlow; ?

That seems like it would work? and it would cut down on my overall program length?
It might be simpler?

I was just hoping that I wouldn't have to define 12+ functions such as:

  • void fanlow1

  • void fanmed1

  • void fanhigh1

  • void lightoffon1

  • void fanoff1

  • void fanlow2

  • void fanmed2

  • void fanhigh2

  • void lightoffon2

  • void fanoff2

etc etc

I'm anticipating buying 2 more fans of the same brand/type. This would make 24 functions, I was just hoping I could use one function, and call the variable defined at the top to be used dependant on the MQTT payload...

Does that make sense? I'm not sure if my understanding of this is well enough that I can communicate my aspirations...

Are you controlling the MQTT communication (Payload) or is that imposed and what you really need to handle?

J-M-L:
Are you controlling the MQTT communication (Payload) or is that imposed and what you really need to handle?

I'm not sure I understand what that means.
In the original post I included my complete code, but basically, I'd like to run a function that if MQTT payload received = X then the boolean string to send to function would also be X.

In that sense, it would greatly cut down on the length and size of the code.

Right now, there are just if/else statements, if received mqtt payload fanlow, then run the fan low function.
I was hoping that it could be something more along the lines of, if mqtt payload is fanlow, then run this general function and use this variable in place.

Hopefully that makes sense.
In that manner it would cut down on defining 12 unique functions and rather just call a function and use the variable define by the payload received.

I'm even getting myself confused trying to articulate my attempts, but maybe seeing the full code would help?

I was trying to ask « where does the MQTT message comes from? Who/what is sending it? »

For example would you be able to send 14 (some number) instead of fanlow?

If so that could be the index in an array of functions to trigger

@J-M-L , the MQTT message is coming from my raspberry PI. The PI, running Home Assistant ( & MQTT) tells the Wemos via MQTT “this payload” which is interpreted by the Wemos to run its void loop… if received “this payload” then run “this function” , else if the payload was “this X” then run “this other function”.

  else if (requestedRoom == mqtt_room2_fan_action_topic && requestedAction == "3") {
    Serial.print("Setting ");
    Serial.print(bedroom2_alias);
    Serial.println("'s fan speed to high!");
      client.publish(mqtt_room2_fan_status_topic, "3");
      client.publish(mqtt_room2_fan_status_topic, FanResult3);
        {
        for (a = 0; a < 8; a++) {
        for (int i = 0; i < sizeof(recordedSignal_fanhigh2) - 1; i++) {
        digitalWrite(transmitter_pin, recordedSignal_fanhigh2[i]);
        delayMicroseconds(393.9);
        }
        delayMicroseconds(9000);
        }
        delay(800);
        }
  }
  else if (requestedRoom == mqtt_room2_fan_action_topic && requestedAction == "0") {
    Serial.print("Setting ");
    Serial.print(bedroom2_alias);
    Serial.println("'s fan off!");
      client.publish(mqtt_room2_fan_status_topic, "0");
      client.publish(mqtt_room2_fan_status_topic, FanResult0);
        {
        for (a = 0; a < 8; a++) {
        for (int i = 0; i < sizeof(recordedSignal_fanoff2) - 1; i++) {
        digitalWrite(transmitter_pin, recordedSignal_fanoff2[i]);
        delayMicroseconds(393.9);
        }
        delayMicroseconds(9000);
        }
        delay(800);
        }
  }

Do you see how each of the two payloads includes the function within?
I’m thinking, by following this other sketch seen here:

I can run one function, and just change the array/string/variable etc accordingly.

But to get back to your statement, I can publish any message I want from the PI. It doesn’t have to be fanlow, fanmed etc.

I think I understand what you’re getting at. If the payload received = 14 (some number) then run function ‘14’.
If I did that, it would cut down some on my code length, but I would still need to have a function defined for each payload (some number) ~ 10, 11, 12,13,14…etc.

Can I define the function generally, then upon the payload received, use “this array” for the function we are calling?

Hope that makes sense, let me know if I need to clarify

Yes you need different functions for different actions/devices obviously (code that are different) but then You can have an array of functions Pointers and thus when you receive a MQTT message for object 14 you trigger the function at index 14 (or 13 depending on how you number things) so you don’t need a bunch of nested comparisons to trigger the right function, just trust whatever was asked. Your MQTT message could even embed parameters other than the function index that you could use to pass to the function call. So for example you would have a generic function « XYZ() » at entry 14 spinning a motor until some limit is detected and the motor and limit switches would be in an array of structs and you would pass the index of that array in MQTT message « 14-7 » would mean trigger Function XYZ(7)

How would it look if I just had one function (since it is all the same anyways) and just changed the array it was using based on the MQTT payload received?

Something like:

if (requestedRoom == mqtt_room2_fan_action_topic && requestedAction == "0") {
    Serial.print("Setting ");
    Serial.print(bedroom2_alias);
    Serial.println("'s fan off!");
      client.publish(mqtt_room2_fan_status_topic, "0");
      client.publish(mqtt_room2_fan_status_topic, FanResult0);
FUNCTION - fanTransmit()
     using "array 0"
}

else if (requestedRoom == mqtt_room2_fan_action_topic && requestedAction == "1") {
    Serial.print("Setting ");
    Serial.print(bedroom2_alias);
    Serial.println("'s fan low!");
      client.publish(mqtt_room2_fan_status_topic, "1");
      client.publish(mqtt_room2_fan_status_topic, FanResult0);
FUNCTION - fanTransmit()
     using "array 1"
}

That make sense?
It would consolidate the number of functions defined, as a general function, and then also consolidate the procedures per MQTT payload received (not stating a function in each payload)

Create a struct type grouping all the relevant information for one target system
Define a constant array of those including all the pins number and information.
If there is only one function (how do you differentiate open versus close?) The MQTT message then would just include the index in that constant array and would be the parameter to the function call.

If there is only one function (how do you differentiate open versus close?)

Well, there’s actually 8 functions technically, because they are all essentially the same function but different string.

I’ll show you:

// here i define all the RF signals
boolean recordedSignal_1fanlow[] =    {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0};
boolean recordedSignal_1fanmed[] =    {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0};
boolean recordedSignal_1high[] =      {0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0};
boolean recordedSignal_1fanoffon[] =  {1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0};
boolean recordedSignal_1lightoffon[] ={0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0};
														   
boolean recordedSignal_2fanlow[] =    {0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0};
boolean recordedSignal_2fanmed[] =    {0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0};
boolean recordedSignal_2high[] =      {1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0};
boolean recordedSignal_2fanoffon[] =  {1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0};
boolean recordedSignal_2lightoffon[] ={0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0};

The function is the same, with the exception of which signal is being used.

void [u]1fanlow/u {
for (a = 0; a < 8; a++) {
** for (int i = 0; i < sizeof(recordedSignal_1fanlow) - 1; i++) {**
digitalWrite(DATA, recordedSignal_1fanlow*);[/b]
__
delayMicroseconds(393.9);__
__
}__
__
delayMicroseconds(9000);__
__
}__
__
delay(rfwait);__
__
}__
void [u]2fanlow/u {
__
for (a = 0; a < 8; a++) {__
** for (int i = 0; i < sizeof(recordedSignal_2fanlow) - 1; i++) {**
digitalWrite(DATA, recordedSignal_2fanlow);[/b]
__ delayMicroseconds(393.9);
}
delayMicroseconds(9000);
}
delay(rfwait);
}
So following your instruction, the MQTT payload and output/function would be something like:
```*__

*int FanRFcodesArray [10] [13] {
  {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},      //fan1low
  {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},      //fan1med
  {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0},      //fan1high
  {0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0},      //fan1offon
  {1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0},      //fan1lightoffon
  {0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0},      //fan2low
  {0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0},      //fan2med
  {0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0},      //fan2high
  {1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0},      //fan2offon
  {1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0}      //fan2lightoffon
};

void fantransmit() {
  for (a = 0; a < 10; a++) {{
    for (int i = 0; i < sizeof(FanRFcodesArray) - 1; i++) {
      digitalWrite(DATA, FanRFcodesArray);
          delayMicroseconds(393);

}

// and then the MQTT payload

void triggerBedroomAction(String requestedRoom, String requestedAction) {
  if (requestedRoom == mqtt_room1_fan_action_topic && requestedAction == “1”) {
    Serial.print(“Setting “);
    Serial.print(bedroom1_alias);
    Serial.println(”'s fan speed to low!”);
      client.publish(mqtt_room1_fan_status_topic, “1”);
      client.publish(mqtt_room1_fan_status_topic, FanResult1);
fantransmit(FanRFcodesArray [1] [13];
  }
  }
  else if (requestedRoom == mqtt_room1_fan_action_topic && requestedAction == “2”) {
    Serial.print(“Setting “);
    Serial.print(bedroom1_alias);
    Serial.println(”'s fan speed to medium!”);
      client.publish(mqtt_room1_fan_status_topic, “2”);
      client.publish(mqtt_room1_fan_status_topic, FanResult2);
fantransmit(FanRFcodesArray [2] [13];              ////////////// [3][13], and so forth
  }

__```*

Do I have that about right?
I’m not sure I actually have the function written correctly?__

there are many things to say, so in random order:

You are not using code tags for your functions, so the [i] that you likely wrote there as an index has been eaten up by the forum formatting for italic.

Your microcontroller does not know how to be that precisedelayMicroseconds(393.9);the function only takes an integer value (and will be ±2 µs precise). so you should just write delayMicroseconds(394);

why do you declare the arrays as boolean? boolean are either true or false. Using 0 and 1 is kinda ugly too, you really mean HIGH and LOW since you use those in digitalWrite(). The correct type for those would be probably const byte arrays.

why would your for loop not read the full array ?     for (int i = 0; i < sizeof(recordedSignal_1fanlow) - 1; i++) {why do you have the -1 there?

All the arrays have 15 bits, do you mean that the last byte is useless and you just added a 0 at the end for the fun of wasting memory space or is there any smart use for this elsewhere in your code ? if there is use for it, you could define your arrays as

// here i define all the RF signals
const byte recordedSignal_1fanlow[]       = {LOW, HIGH, LOW, HIGH, HIGH, LOW, HIGH, LOW, LOW, HIGH, LOW, LOW, HIGH, LOW, 0};
const byte  recordedSignal_1fanmed[]      = {LOW, HIGH, LOW, HIGH, HIGH, LOW, HIGH, LOW, LOW, HIGH, HIGH, LOW, HIGH, LOW, 0};
const byte  recordedSignal_1high[]        = {LOW, HIGH, LOW, HIGH, HIGH, LOW, HIGH, HIGH, LOW, HIGH, HIGH, LOW, HIGH, LOW, 0};
const byte  recordedSignal_1fanoffon[]    = {HIGH, LOW, LOW, HIGH, HIGH, LOW, HIGH, LOW, LOW, HIGH, HIGH, LOW, HIGH, LOW, 0};
const byte  recordedSignal_1lightoffon[]  = {LOW, HIGH, LOW, HIGH, HIGH, LOW, HIGH, HIGH, LOW, HIGH, HIGH, LOW, HIGH, LOW, 0};

const byte  recordedSignal_2fanlow[]      = {LOW, HIGH, LOW, HIGH, LOW, LOW, HIGH, LOW, LOW, HIGH, HIGH, LOW, HIGH, LOW, 0};
const byte  recordedSignal_2fanmed[]      = {LOW, LOW, LOW, HIGH, HIGH, LOW, HIGH, LOW, LOW, HIGH, HIGH, LOW, HIGH, LOW, 0};
const byte  recordedSignal_2high[]        = {HIGH, HIGH, LOW, HIGH, HIGH, LOW, HIGH, HIGH, LOW, HIGH, HIGH, LOW, HIGH, LOW, 0};
const byte  recordedSignal_2fanoffon[]    = {HIGH, LOW, LOW, HIGH, HIGH, LOW, HIGH, LOW, LOW, HIGH, HIGH, LOW, HIGH, LOW, 0};
const byte  recordedSignal_2lightoffon[]  = {LOW, HIGH, LOW, HIGH, HIGH, LOW, HIGH, HIGH, LOW, HIGH, HIGH, HIGH, HIGH, LOW, 0};

that would help show that the last byte is a terminator.

if there is no smart use and you really need only 14 bits, just don’t put it there.

Also as the arrays have the very same size and what you need is binary info, you could store the frame into an uint16_t as bits (0 and 1) and just ignore the two left most (most significant) bits when playing back. that would save lots of memory. For example const byte recordedSignal_1fanlow[]      = {LOW, HIGH, LOW, HIGH, HIGH, LOW, HIGH, LOW, LOW, HIGH, LOW, LOW, HIGH, LOW};would becomeconst uint16_t recordedSignal_1fanlow = 0b01001001011010; // read 14 bits from LSb to MSband will just use 2 bytes in memory instead of 14. As you have 10 of those, you’ll use 20 bytes instead of 140…

// here I define all the RF signals
const uint16_t signals[] = {
  0b01001001011010, // recordedSignal_1fanlow
  0b01011001011010 , // recordedSignal_1fanmed
  0b01011011011010 , // recordedSignal_1high
  0b01011001011001 , // recordedSignal_1fanoffon
  0b01011011011010 , // recordedSignal_1lightoffon
  0b01011001001010 , // recordedSignal_2fanlow
  0b01011001011000 , // recordedSignal_2fanmed
  0b01011011011011 , // recordedSignal_2high
  0b01011001011001 , // recordedSignal_2fanoffon
  0b01111011011010 , // recordedSignal_2lightoffon
};

and you could use the bitRead() function to grab a specific bit in that frame


Now it seems that your function just repeat 8 times the sending of the 14 bits and the only difference between the function is that the array you use differs.

As explained above, your transmit function could have a parameter which would be an index into an array of frames to send.

Open the console at 115200 bauds and run this code.

const byte dataPin = 2;         // whatever it is, just for the sake of compiling
const uint32_t rfwait = 1ul; // whatever it is, just for the sake of compiling
const byte numberOfRepetition = 8;
const byte numberOfMeaningfulBits = 14;

// here I define all the RF signals
const uint16_t signals[] = {
  0b01001001011010, // recordedSignal_1fanlow
  0b01011001011010 , // recordedSignal_1fanmed
  0b01011011011010 , // recordedSignal_1high
  0b01011001011001 , // recordedSignal_1fanoffon
  0b01011011011010 , // recordedSignal_1lightoffon
  0b01011001001010 , // recordedSignal_2fanlow
  0b01011001011000 , // recordedSignal_2fanmed
  0b01011011011011 , // recordedSignal_2high
  0b01011001011001 , // recordedSignal_2fanoffon
  0b01111011011010 , // recordedSignal_2lightoffon
};
const byte numberOfFrames = sizeof(signals) / sizeof(signals[0]);

// this function
void sendFrame(byte frameID)
{
  if (frameID >= numberOfFrames) return; // this frame does not exist, do nothing

  Serial.print(F("Sending Frame #"));
  Serial.println(frameID);

  for (byte rep = 0; rep < numberOfRepetition; rep++) {
    Serial.write('\t');
    for (byte aBit = 0; aBit < numberOfMeaningfulBits; aBit++) {
      Serial.print(bitRead(signals[frameID], aBit) ? F("HIGH  ") : F("LOW  "));

      // ---------------------------------------------------
      // ------- COMMENTED OUT FOR PURPOSE OF SAFETY -------
      // ---------------------------------------------------
      // digitalWrite(dataPin, bitRead(signals[frameID], aBit));  // https://www.arduino.cc/reference/en/language/functions/bits-and-bytes/bitread/
      // ---------------------------------------------------

      delayMicroseconds(394);
    }
    Serial.println();
    delayMicroseconds(9000);
  }
  delay(rfwait);
  Serial.println(F("---------"));
}

void setup()
{
  Serial.begin(115200);
  pinMode(dataPin, OUTPUT);

  // example on how to send all the frames
  for (byte f = 0; f < numberOfFrames; f++) sendFrame(f);
}

void loop() {
  int userInput = Serial.read();
  if (userInput != -1) {  // -1 means nothing was read
    sendFrame((byte) (userInput  - '0')); // send the requested frame
  }
}

You will see all your frames.
Once the setup() has printed all the frames, you can also type in the console a number between 0 and 9 and that frame ID will get printed.

Note that I commented out the actual changes in your data pin// digitalWrite(dataPin, bitRead(signals[frameID], aBit)); as I would not want to really send all those orders to your devices not knowing exactly if they drive something important.


Now with all this, your MQTT message would just need to contain a value between 0 and 9 which would be the index of the signal to send. you would decode it and call the function with the right number (a byte integer, not a string !).

Note also that using the String class on small Arduinos is not recommended.

EDIT: of course as timing is important for your frames, don’t keep the Serial debug info in the function !
using PORT registers would also help you get better accuracy in your timing since digitalWrite() does take some time (~3.4 microseconds on a 16Mhz arduino) to execute and that will thus impact your timing.

Wow, that’s a lot to chew on.

You are not using code tags for your functions, so the that you likely wrote there as an index has been eaten up by the forum formatting for italic.[/quote]
```
*void fantransmit() {
  for (a = 0; a < 10; a++) {{
    for (int i = 0; i < sizeof(FanRFcodesArray) - 1; i++) {
      digitalWrite(DATA, FanRFcodesArray);
          delayMicroseconds(393);

}*

* *If you're talking about ^^^ that, I actually didn't know what to put within those [ ]'s. I assumed it would be "i", but wasn't sure. The code I posted without the code formatting was intentional, I was just showing it was the same function, but different recorded_signal string being used.* *> the function only takes an integer value (and will be ±2 µs precise). so you should just write* *That was a typo, I actually did mean to drop the decimal as the delay is an int and not a float.* *I actually would really like to send the binary as you suggested* *
const uint16_t recordedSignal_1fanlow = 0b01001001011010; // read 14 bits from LSb to MSb
* *but I'm not great at the conversion. Also, I'm not really certain on the difference between uint16_t versus uint8_t. Also, I actually had to chop down a great amount of those 1's and 0's because it seemed like it just blew out my post and restricted my character limit.* _I believe in total there are 236 1's & 0's. *I know, that's a lot of info, but it was just how it turned out after I plugged the data in to audacity and decoded the remote's signals.* Actually, the first 172 bits are all the same. That is probably something also I could use to compact the size of this program overall._ *> that would help show that the last byte is a terminator.* *That is exactly why. I added the trailing two 0's to make sure the signal was off. * *@J-M-L, I honestly/truly appreciate the feedback you're giving me and it may seem a bit tutorial or teaching but I appreciate it!* *> why do you declare the arrays as boolean?* *It was just the code I was mimicking from a video of someone doing the same I'm trying to achieve.* *[Youtube link: How to copy 433MHZz signal](https://www.youtube.com/watch?v=LbCDpbWrdlQ&t=165s)* *> why would your for loop not read the full array ?* *I believe I understand this question. This goes back to copying the code in the video I found.* *If I were to read the full array as is, would I still have the ability to slow the read speed? The 393 delay actually controls the RF signal's period (?). I had to meddle with this number in Audacity for a while in order to get the RF signal I was producing to align with the length of the remote's signal.* *If your question was in regards to my proposed changed code, I was using the array at line 2 (for example) and the 13 values in that array to declare which signal, set of 1's & 0's, to send in the FanTransmit function.* *Here is the common bits of every signal:* *
{1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
```
I was hesitant on using the uint16_t and the uint8_t because 172 is not divisible easily by 8 as well as 236 (actual length of signal, excluding trailing two 0’s). I wasn’t sure it would operate if my bits didn’t fully complete a byte. Honestly don’t know enough about uint16_t to understand and be comfortable using it in my code.
Here’s the actual signal for the fan off/on:
1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, This also excludes the 172 bit header. This is exactly 64 bits.
Again, I just added the two 0’s to signify termination. They’ve been excluded from the code above ^^^
> of course as timing is important for your frames, don’t keep the Serial debug info in the function !
yep, I plan on stripping out all the serial.print
> Now it seems that your function just repeat 8 times the sending of the 14 bits and the only difference between the function is that the array you use differs.
>
> As explained above, your transmit function could have a parameter which would be an index into an array of frames to send.
I seriously need to chew on this some more. I know you’re getting me to my end result, I’m just having a difficult time wrapping my head around it.
I’ll go back to the board on this JML, sometimes it helps me when I can print out the code and make notes on paper as to what’s happening. I’m after creating a function implementing an index to an array of frames as you mentioned.

Ok I did not realize your frame was that long.

It could still be stored as bits in an array of bytes, you just need to know the number of bits to read

Try to understand how I read those bits and once you get that you’ll have made a big step forward.

Yes this forum is more about guidance than doing your homework for you.