как заставить последовательные данные ждать, пока не будет достигнута определенная длина

У меня есть код, который проходит через 2 разных последовательных входа на arduino mega и постоянно отправляет их в последовательный порт:

int RFIDResetPin = 13;


void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial2.begin(9600);
  pinMode(RFIDResetPin, OUTPUT);
  digitalWrite(RFIDResetPin, HIGH);
}

void loop() {

  char tagString1[13];
  int index = 0;
  boolean reading1 = false;
  boolean reading2 = false;
  /////////////////////////////////////////
  // это читается из установленного считывателя
  // на serial1, который является контактом 19
  ////////////////////////////////////////
  while (Serial1.available() > 0) {

    int readByte1 = Serial1.read(); //читаем следующий доступный байт

    if (readByte1 == 2) reading1 = true;
    if (readByte1 == 3) reading1 = false;

    if (reading1 && readByte1 != 2 && readByte1 != 10 && readByte1 != 13) {
      tagString1[index] = readByte1;
      index++;
    }
  }
  Serial.println(String("Reader 7: ") + tagString1); //сам тег

delay(1);
  clearTag(tagString1); //Очистить символ от всех значений
  resetReader(); //сбросить считыватель RFID
  //////////////////////////////////////////////////
  // Этот бит считывается из serial2, расположенного на выводе 17
  ///////////////////////////////////////////////////
  while (Serial2.available() > 0) {

    int readByte2 = Serial2.read();

    if (readByte2 == 2) reading2 = true;
    if (readByte2 == 3) reading2 = false;

    if (reading2 && readByte2 != 2 && readByte2 != 10 && readByte2 != 13) {
      tagString1[index] = readByte2;
      index++;
    }
  }
  Serial.println(String("Reader 8: ") + tagString1);

  clearTag(tagString1);
  resetReader();
}




void resetReader() {
  ////////////////////////////////////
  // Сбросьте считыватель RFID для повторного чтения.
  ////////////////////////////////////
  digitalWrite(RFIDResetPin, LOW);
  digitalWrite(RFIDResetPin, HIGH);
  delay(150);
}

void clearTag(char one[]) {
  ////////////////////////////////////
  // очистить массив символов, заполнив его нулем — ASCII 0
  //В противном случае будет считаться, что тот же тег был прочитан
  ////////////////////////////////////
  for (int i = 0; i < strlen(one); i++) {
    one[i] = 0;
  }
}

когда ничего не сканируется, последовательный монитор выводит следующее:

Reader 1:
Reader 2:
Reader 1:
Reader 2:

Когда я сканирую тег, скажем, на считывателе 1, я получаю следующее:

Reader 1: 000004f5
Reader 2:
Reader 1: 000004f5
Reader 2:

невозможно одновременно сканировать более одного сканера. Можно ли заставить первую строку ждать, пока будет отсканировано определенное количество символов (что указывает на то, что тег был отсканирован), а затем выводить на последовательный монитор? После этого начального запуска код зациклится, как я показал выше. любая помощь приветствуется.

, 👍0

Обсуждение

Ваш dcode не соответствует вашему выводу (например, «Reader 7:») При скорости 9600 бод у вас может быть много времени между символами и одновременное чтение. Попробуйте прочитать байты из отдельных портов в отдельные буферы побайтно, а затем действовать только при заполнении буфера., @Dave X

Похоже, что индекс распределяется между тегами, и вы выполняете цикл сброса 150 мс и очищаете каждый цикл, ответ Per Bra1n, рассмотрите конечный автомат и, возможно, используйте index1 и index2 для отслеживания количества байтов, которые вы прочитайте каждый и разделите отчет на что-то условное, если «было отсканировано определенное количество символов», @Dave X

Так это работает для 8 читателей? Похоже, что если вы попытаетесь прочитать больше считывателей за цикл(), index может превысить 13 и сделать что-то ужасное. Может быть, очистить index перед циклами while?, @Dave X


2 ответа


2

Я бы использовал концепцию программирования, называемую конечным автоматом. Например, целочисленная переменная State может использоваться для отслеживания текущего состояния, которое может быть, например, WAITING_FOR_DATA или RECEIVING_DATA или DATA_COMPLETE и печатать только тогда, когда DATA_COMPLETE. Я уверен, что есть много примеров, которые вы могли бы найти с помощью соответствующего поиска.

,

Лучше использовать тип enum для State вместо int (и использовать лучшее имя, например UartState или UartState1, UartState2, если вам нужно), @Michel Keijzers


1

1. предпочтительнее использовать Serial.readStringUntil(); ИЛИ Serial.readString(), таким образом, им очень легко манипулировать.

2.используйте статическую переменную в функции цикла, которая хранит строку, или используйте глобальную переменную для сохранения массива символов tagString1 перед входом в функцию println. То же самое происходит со вторым считывателем, таким образом, println будет показывать предыдущее сканирование до нового сканирования. не сделано.

3.распечатайте обе строки тегов в конце кода одну за другой

,