Невозможно повторно прочитать данные 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...
@Teddol, 👍1
Обсуждение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();
}
,
@Teddol
перепишите это, пожалуйста, как отдельный ответ, @Juraj
Смотрите также:
- Основная связь Arduino ModBus RTU с проблемой измерителя мощности
- Мониторинг контроллера Modbus RTU с помощью Arduino и модуля RS485
- Связь Arduino Uno и ESP32 с использованием RS485
- Когда дело доходит до связи UART-RS485, в чем разница между модулем "MAX485" и модулем "HW-0519"?
- Преобразование десятичных данных rtu Modbus в число с плавающей запятой
- Управление VFD с помощью ModBus RTU через RS485 и Arduino
- Взаимодействие NodeMCU Modbus с Multi-Switch давления
- Использование Modbus-RTU с Arduino и контроллером температуры
комментарии: подключить DE и RE к одному контакту; вам не нужно вызывать listen, если у вас есть только один экземпляр SoftwareSerial; не используйте строку; если доступен хотя бы 1 байт, вы читаете 7, @Juraj
Вы про эту строчку?: String myByte = String(RS485Serial.read(), HEX);, @Teddol
относительно String и чтения вслепую, да. используйте
RS485Serial.readBytes(RTUresponse, 7);
.readBytes
будет ждать следующего байта, @Juraj