Pmsmm
Pmsmm

Reputation: 440

Why Serial Received Message Getting Stored In Char Array

I'm having an issue in my Arduino code after receiving a message from Serial.

The issue is that, upon receiving the message "START" via serial, the Arduino proceeds to execute the function startSequence() that, using two random numbers, fetches 8 values from a 2D matrix and stores these values in a char array.

The problem here is that even though this char array has been declared with a size of 8, the message "START" gets appended to the end of this char array and it shouldn't do this at all, this message should be completely discarded after handleReceivedMessage(char *msg). My code:

#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 4;

char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
char newSecretCode[8];
char introducedSecretCode[8];

byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};

int secretCodeIndex = 0;

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup() {
  Serial.begin(9600);
  delay(2000);  //Delay to allow initializations on Raspberry side
  Serial.println("COM:SETUP;INT_NAME:Keypad Puzzle;BAUD:9600");
  randomSeed(analogRead(0));
}

void loop() {
  if (Serial.available()) {
    processSerialMessage();
  }
  char customKey = customKeypad.getKey();
  if (customKey) {
    if (secretCodeIndex < 8) {
      introducedSecretCode[secretCodeIndex] = customKey;
      secretCodeIndex += 1;
    } else {
      secretCodeIndex = 0;
    }
  }
}

void processSerialMessage() {
  const int BUFF_SIZE = 32; // make it big enough to hold your longest command
  static char buffer[BUFF_SIZE + 1]; // +1 allows space for the null terminator
  static int length = 0; // number of characters currently in the buffer

  char c = Serial.read();
  if ((c == '\r') || (c == '\n')) {
    // end-of-line received
    if (length > 0) {
      handleReceivedMessage(buffer);
    }
    length = 0;
  }
  else {
    if (length < BUFF_SIZE) {
      buffer[length++] = c; // append the received character to the array
      buffer[length] = 0; // append the null terminator
    } else {
      // buffer full - discard the received character
    }
  }
}

void handleReceivedMessage(char *msg) {
  if (strcmp(msg, "START") == 0) {
    startSequence();
    Serial.println("COM:START_ACK;MSG:Set new code to " + String(newSecretCode));
  }else {
    // etc
  }
}

void startSequence() {
  for (int i = 0; i < 8; i++) {
    newSecretCode[i] = hexaKeys[random(0,ROWS)][random(0,COLS)];
  }
}

I've seen the code over and over and I can't seem to figure out why does the message I receive through serial manages to get appended to the end of an array whose size is only 8. Below are some examples of the output which is correct except for the "START" message that is at the end of the String.

Output generated by sending "START" command through serial

Thank you to everyone in advance for the help and if the mistake is obvious my apologies, but I've been through this code over and over and can't seem to find it.

Upvotes: 0

Views: 311

Answers (1)

Delta_G
Delta_G

Reputation: 3243

You need to null terminate newSecretCode if you expect it to act as a string. But it is better to not use the String class to convert something you don't need to convert. Print it this way:

void handleReceivedMessage(char *msg) {
  if (strcmp(msg, "START") == 0) {
    startSequence();
    Serial.println("COM:START_ACK;MSG:Set new code to " );
    for (int i=0; i<8; i++){
      Serial.print(newSecretCode[i]);
    }
  }else {
    // etc
  }
}

Serial data goes out byte by byte. The receiver on the other end just sees a continuous stream of bytes. It has no knowledge of whether you did that with one single print statement and a bunch of resources wasted on a String or if you did it with a separate print statement for each character.

Upvotes: 1

Related Questions