Невозможно повторно прочитать данные Modbus

Я пытаюсь установить связь с двумя датчиками RS485 (pH и EC), но у меня возникают проблемы с кодом. Сначала я попытался получить данные только из одного:

Функция, отвечающая за отправку запроса:

String GET_probe(String probe){

if(probe == "pH"){
Serial.println("Sending request pH...");
digitalWrite(modbusModuleRE, RS485Transmit);  // Инициализируем приемопередатчик
digitalWrite(modbusModuleDE, RS485Transmit);  // Инициализируем приемопередатчик
byte  RTUrequest[] = {0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x85, 0xDB};
RS485Serial.write(RTUrequest, sizeof(RTUrequest));
}

if(probe == "EC"){
Serial.println("Sending request EC...");          

digitalWrite(modbusModuleRE, RS485Transmit);  // Инициализируем приемопередатчик
digitalWrite(modbusModuleDE, RS485Transmit);  // Инициализируем приемопередатчик
byte  RTUrequest[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
RS485Serial.write(RTUrequest, sizeof(RTUrequest));  
}

RS485Serial.flush();
RS485Serial.listen();
}

Функция, отвечающая за считывание ответа датчика:

void ReadRx() {
     digitalWrite(modbusModuleRE, RS485Receive);
     digitalWrite(modbusModuleDE, RS485Receive);
     if(RS485Serial.available()) {
     Serial.print("Answer: ");
      for(int i=0; i<7; i++){  
          String myByte = String(RS485Serial.read(), HEX);// Читаем байт

          if (myByte.length() == 1)
          {
            myByte = "0"+myByte;
          }
          modbusHexBuffer[i] = myByte;

          Serial.print(myByte);
          Serial.print(" "); 
      }
      Serial.println();
    }
   }

И цикл, отправляющий запрос каждые 5 секунд:

void loop(){

  static uint32_t ts = millis();

  if (millis() - ts >= 5000) {
      ts = millis();
      GET_probe("pH");
  }

ReadRx();
}

Цикл работает нормально один раз и завершается ошибкой во второй раз, как показано в терминале. Можете ли вы сказать мне, почему, и помочь мне исправить это?

Sending request pH...
Answer: 00 03 02 05 78 86 f6 
Sending request pH...

, 👍1

Обсуждение

комментарии: подключить DE и RE к одному контакту; вам не нужно вызывать listen, если у вас есть только один экземпляр SoftwareSerial; не используйте строку; если доступен хотя бы 1 байт, вы читаете 7, @Juraj

Вы про эту строчку?: String myByte = String(RS485Serial.read(), HEX);, @Teddol

относительно String и чтения вслепую, да. используйте RS485Serial.readBytes(RTUresponse, 7);. readBytes будет ждать следующего байта, @Juraj


1 ответ


Лучший ответ:

1

Я нашел почему!!!

1-й: buf[8] вместо buf[7] в объявлении 2-й: повторно инициализировать байт buf[8] перед частью запроса EC.

Итак, код, который работает нормально:

byte buf[8];
void loop(){

      Serial.print("pH: ");   
      digitalWrite(modbusModuleRE, RS485Transmit);  // Инициализируем приемопередатчик
      digitalWrite(modbusModuleDE, RS485Transmit);  // Инициализируем приемопередатчик
      byte  pHrequest[] = {0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x85, 0xDB}; 
      RS485Serial.write(pHrequest, sizeof(pHrequest));
      RS485Serial.flush();
      digitalWrite(modbusModuleRE, RS485Receive);
      digitalWrite(modbusModuleDE, RS485Receive);
      RS485Serial.readBytes(buf, 8);
     Serial.print(buf[3], HEX);Serial.println(buf[4], HEX);

byte buf[8];

      Serial.print("EC: "); 
      digitalWrite(modbusModuleRE, RS485Transmit);  // Инициализируем приемопередатчик
      digitalWrite(modbusModuleDE, RS485Transmit);  // Инициализируем приемопередатчик
      byte  ECrequest[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
      RS485Serial.write(ECrequest, sizeof(ECrequest));
      RS485Serial.flush();
      digitalWrite(modbusModuleRE, RS485Receive);
      digitalWrite(modbusModuleDE, RS485Receive);
      RS485Serial.readBytes(buf, 8);
      Serial.print(buf[3], HEX);Serial.print(buf[4], HEX);Serial.print(buf[5], HEX);Serial.println(buf[6], HEX);

Serial.println();

}
,

перепишите это, пожалуйста, как отдельный ответ, @Juraj