Comparing strings

I'm very new to this and I'm struggling to solve the following issue, so any help would be greatly appreciated.

I'm trying to create a remote trigger (to launch a model rocket). I want to receive data via Bluetooth (which is then stored in the variable [newMessage] and then check that data against a launch code (which is stored in the variable [launchCode]). If the [launchCode] and the [newMessage] data match then it will start the launch procedure. The problem that I'm having is that the 'if' statement at line 34 of the attached code never gets triggered - even though the [newMessage] matches the [launchCode]. I'm wondering whether it has anything to do with the way I'm trying to compare these variables?

#define RX_PIN 0
#define LED 7
#define LAUNCH_PIN 13

char launchCode[] = "123BOOM";

//message handling variables
#define BUF_SIZE 30
char newMessage[BUF_SIZE];

//flags
bool newMessageAvailable = false;
bool endOfMessage = false;
bool newMsgReceivedstate = false;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(LAUNCH_PIN, OUTPUT);
  Serial1.begin(9600);
  attachInterrupt(digitalPinToInterrupt(RX_PIN), ToggleMsgReceivedstate, HIGH);

}

void loop() {
  //check for new messages
  if (newMsgReceivedstate == true) {
    readSerial();

    Serial.print(newMessage);
    Serial.println();
    
  }

  if (strcmp(launchCode, newMessage) == 0) {
    launchProcedure();
  }
}

void ToggleMsgReceivedstate() {
  newMsgReceivedstate = true;
}

void readSerial(void) {
  
  uint8_t putIndex = 0;
  
  while (Serial1.available() > 0) {
    newMessage[putIndex] = (char)Serial1.read();
    if ((newMessage[putIndex] == '\n') || (putIndex >= BUF_SIZE - 5)) {      
      //end the string
      newMessage[putIndex] = '\0';
      endOfMessage = true;
      putIndex = 0;
    }
    
    delay(20);
    putIndex++;
  }
  newMsgReceivedstate = false;
  delay(500);
}

void launchProcedure(void) {
  Serial.print("Launch initiated!!");

  // Initiate countdown
  for (int i = 1; i <= 10; i++) {
    //Countdown warning LED blink sequence
    digitalWrite(LED, HIGH);
    delay(500);
    digitalWrite(LED, LOW);
    delay (500);
  }

  digitalWrite(LAUNCH_PIN, HIGH); //Switch voltage to starter to high and ignite rocket motor
  delay (5000);
  digitalWrite(LAUNCH_PIN, LOW); //Switch voltage to starter to low after launch
  newMsgReceivedstate = false;
}

Please post your code here following the instructions about using code tags in How to get the best out of this forum

Open the serial port to the IDE.
Add print statements in each if statement. You can then follow the program flow.
I print the line numbers for my debug efforts.

Thanks. I wasn't sure how to do that.

It may have been helpful to explain that to do that you can use

Serial.print(__LINE__);

Your right I was in a hurry, wife called.....

In Setup add:

Serial.begin(115200);

Then in critial areas add this line;

Serial.print(__LINE__);

This has to be done while still connected to the IDE. And you must open the "Serial Monitor" listed under tools. Then change the baud rate (lower right hand corner) to 115200.
In the Serial Monitor window you will see the line numbers be printed as your code is executed.
If they go too fast, add a delay(2000); at the loop beginning.

BTW I learned something too. I was not aware that __ LINE __ would print the line numbers. I had been doing it manually :frowning:

Perhaps your "launchcode" is not a String.
Paul

Which Arduino are you using?

bool newMsgReceivedstate = false;

Variables shared with interrupt routines must be declared "volatile". In any case, you should not be attempting to set up your own serial interrupt, as you are attempting to do.

There are much better ways of determining whether serial data are available. See the "Serial Input Basics" tutorial on this forum.

Does your Arduino have a External Interrupt on Pin 0? The UNO and Nano don't. Just use Serial.available() if you want t know if any characters have arrived.

Thanks. I’ll take a look at that. The problem I’m having isn’t with the interrupt though. Everything appears to work fine other than the if statement that compares the launchCode with the newMessage. It’s really this part of the code that I’m after help on - although I do appreciate any general comments.

Hi. Yes, the Bluetooth RX data pin is on Pin 0 of the Arduino. So I’m checking this to determine if the Bluetooth module has received data. Hope that makes sense.

Sorry, forgot to mention. It’s an Arduino Leonardo that I’m using.

The two variables that I’m comparing are defined as ‘char’. I’m not sure if this causes a problem?

If you think that could cause a problem, print both in HEX to verify you belief.
Paul

I just looked again, you are comparing them as strings.

Assuming the Bluetooth is on Serial1, that is exactly what interrupt-driven Serial1.available() does for you. So no, it doesn't make sense.

Usually, it is best to use the system as it is intended to be used.

Thanks. Like I said, I’m very new to this so don’t know the best way to do things. I wasn’t aware that I could check for serial data from Bluetooth module in the way that you’ve suggested so thanks for the advice.

Thanks. Are you saying that these variables aren’t treated as strings by the code? If so, is there a way to compare them?

#define RX_PIN 0
#define LED 7
#define LAUNCH_PIN 13

char launchCode[] = "123BOOM";

//message handling variables
#define BUF_SIZE 30
char newMessage[BUF_SIZE];

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(LAUNCH_PIN, OUTPUT);
  Serial1.begin(9600);
 
}

void loop() {
  //check for new messages
  if (Serial1.available()) {
    readSerial();

    Serial.print(newMessage);
    Serial.println();
     
    if (strcmp(launchCode, newMessage) == 0) {
      launchProcedure();
    }
  }
}

void readSerial(void) {

  Serial1.readBytesUntil('\n', newMessage, BUF_SIZE-1);
  
}

void launchProcedure(void) {
  Serial.print("Launch initiated!!");

  // Initiate countdown
  for (int i = 1; i <= 10; i++) {
    //Countdown warning LED blink sequence
    digitalWrite(LED, HIGH);
    delay(500);
    digitalWrite(LED, LOW);
    delay (500);
  }

  digitalWrite(LAUNCH_PIN, HIGH); //Switch voltage to starter to high and ignite rocket motor
  delay (5000);
  digitalWrite(LAUNCH_PIN, LOW); //Switch voltage to starter to low after launch
  newMsgReceivedstate = false;
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.