Почему полученное сообщение хранится в массиве символов - PullRequest
0 голосов
/ 24 апреля 2020

У меня проблема с кодом Arduino после получения сообщения от Serial.

Проблема заключается в том, что после получения сообщения «START» через последовательный порт Arduino переходит к выполнению функции startSequence() что, используя два случайных числа, выбирает 8 значений из 2D-матрицы и сохраняет эти значения в массиве символов.

Проблема здесь в том, что, хотя этот массив символов был объявлен с размером 8, сообщение «START» добавляется в конец этого массива символов, и он вообще не должен этого делать, это сообщение должно быть полностью отброшено после handleReceivedMessage(char *msg). Мой код:

#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)];
  }
}

Я видел код снова и снова, и я не могу понять, почему сообщение, которое я получаю через последовательный порт, удается добавить в конец массива, размер которого только 8. Ниже приведены некоторые примеры правильного вывода, за исключением сообщения «START», которое находится в конце строки.

Output generated by sending

Заранее всем спасибо за помощь, и если ошибка очевидна, мои извинения, но я перебирал этот код снова и снова и, похоже, не могу его найти.

1 Ответ

1 голос
/ 24 апреля 2020

Вам нужно завершить nuS newSecretCode, если вы ожидаете, что он будет действовать как строка. Но лучше не использовать класс String для преобразования того, что вам не нужно преобразовывать. Напечатайте это так:

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
  }
}

Последовательные данные выходят побайтово. Приемник на другом конце просто видит непрерывный поток байтов. Он не знает, сделали ли вы это с одним оператором печати и кучей ресурсов, потраченных впустую на строку, или же вы сделали это с отдельным оператором печати для каждого символа.

...