0

I'm working on RF modules using Arduino but I observed the if statement is only running once and I need to reset the receiver every time to make it work with real-time changes in the transmitter.

I connected the 16X2 LCD display for displaying the data. If I start the transmitter and started sending data as "1", it's showing "Bye" but when I change the transmitter data to "0", then also it is showing "Bye" only.

I changed a code a little bit but I felt it is the problem with the previous data stored in buf variable.

I'm expecting the LCD should display "Hi" when I changed the transmitting data to "0" from "1" which is not happening only "Bye" is displaying every time.

Here is the Arduino receiver code:

#include <RH_ASK.h>
#include <SPI.h> 
#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
RH_ASK rf_driver;
char message[2];

void setup()
{
    rf_driver.init();
    Serial.begin(9600);
    lcd.begin(16,2);
}

void loop()
{
    uint8_t buf[2];
    uint8_t buflen = sizeof(buf);
    
    buf[1] = '\0';
 
    if (!rf_driver.recv(buf, &buflen))
    {
        if (strcmp((char*)buf, "0") == 0) {
            Serial.println("Hi");
            if (strcmp(message[0], (char*)buf[0]) != 0) {
                lcd.print("Hi");
            }

            lcd.display();
        }
        else if (strcmp((char*)buf, "1") == 0) { 
            Serial.println("Bye");
            if (strcmp(message[0], (char*)buf[0]) != 0) {
                lcd.print("Bye");
                lcd.display();
            }
        }
    }
    message[0] = (char*)buf[0];
}

Here is the transmitter code:

#include <RH_ASK.h>
#include <SPI.h> 
RH_ASK rf_driver;
 
void setup()
{
    rf_driver.init();
    Serial.begin(9600);
}
 
void loop()
{
    const char *msg = "1";
    rf_driver.send((uint8_t *)msg, strlen(msg));
    rf_driver.waitPacketSent();
    delay(1000);
}

The Serial monitor output is as follows: enter image description here

8
  • Does the serial monitor output "Hi" if you change the transmitted value to "0"? (You might want to extend your transmitter code a bit for easier debugging.) -- Why do you initialize the LCD each time, is this necessary? -- Please indent your source properly, it is hard to read. I've edited it once, but you have overwritten it, so I repeat the edit. Commented Aug 1, 2022 at 7:36
  • No, it's not outputting "Hi" when i change the transmitted value to "1". It is continuously showing "bye" only. Commented Aug 1, 2022 at 8:28
  • Huh? With "1" you want to output "Bye". Why do you expect "Hi"? Commented Aug 1, 2022 at 9:10
  • sorry, it's not outputting "Hi" when i change the transmitted value to "0". It is continuously showing "bye" only. Only i click on reset button on Arduino, it is working Commented Aug 1, 2022 at 9:17
  • What is shown in the serial monitor if you output the received message? Commented Aug 1, 2022 at 9:18

1 Answer 1

1

I pointed this out in a comment thinking the question would probably get closed when this was understood to be a typo, but I guess it's not a typo.

char message[2]; ... if (strcmp(message[0], You should be getting a warning for this. If not, turn your warning level up in the preferences.

If you increase the warning level you should see something that at least hints at some of what I'm saying below.

Cutting your code down to a part relevant to the description of the problem:

char message[2];
// ...
uint8_t buf[2];
// ...
if (strcmp(message[0], (char*)buf[0]) != 0) {

strcmp() expects a pointer to a character for both its first and second arguments. However, message[0] is of type char and buf[2] is of type uint8_t (ultimately an unsigned char). The individual characters being used are being interpreted as pointer values (as in memory addresses) which strcmp() expects to refer to the first characters of strings. In other words, it's going to some pair of memory addresses between 0 and 255 and trying to interpret whatever it finds at those locations as strings and compare them. The combination of what you're doing being undefined and not having a strong expectation of what to find at these memory addresses, it's not really surprising (to me anyway) how your comparisons are evaluating.

A minimal change that should bring the strcmp closer to making sense is:

if (strcmp(message, (char*)buf) != 0) {

message and buf here will end up evaluating to the actual locations of their strings. You were already doing half of this line correctly in your other use of buf in if (strcmp((char*)buf, "0") == 0); note no [0] usage there.


In the above I'm addressing this directly and taking it for granted that you have some reason to want to use string that have one (non-null) character in them, that you intended to expand this code to longer messages somehow. Otherwise it makes more sense to just dispense with strings altogether and have rh_driver.recv read directly into a single character type and then use the equality comparison == rather than strcmp().

The sections of code would look more like:

char message; // now individual char
// ...
uint8_t buf;  // now individual char  
// ...
if (!rf_driver.recv(&buf, sizeof buf)) { //sizeof buf is 1
    if (buf == '0') { // now simple application of ==
        Serial.println("Hi");
        if (message != buf) {  // now simple application of !=
            lcd.print("Hi");
        }
// ...
message = buf; // no longer using [0] because no longer an array

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.