ArduinoModbus / RS485 конфликт между Serial и Serial1
Я пытаюсь реализовать ArduinoModbus на моем STM32 Poternta H7 с помощью коммутационной платы.
Хорошо документировано, что в ArduinoRS485 объект RS485 жестко подключен. Если вы используете плату PH7/Breakout, вам нужно перенастроить ее, чтобы убедиться, что RS485 установлен на Serial1/Uart1.
После перенастройки, когда я запускаю свой код, я изначально могу писать отладочные сообщения в последовательный монитор через последовательный порт (встроенный USB C). Но как только я начинаю использовать RS485 на Serial1, я больше не могу печатать в последовательный монитор через последовательный порт, и код зависает.
Что я сделал, чтобы перенастроить объект RS485. Я реализовал следующее на основе этого обходного пути от Arduino ArduinoModbus для других шилдов и с другим последовательным портом - MKR SHIELDS - Форум Arduino 1 Затем сохранил обновленный ArduinoRS485 в /lib.
В ArduinoRS485.cpp
void RS485Class::setSerial(HardwareSerial* serial) {
_serial = serial;
}
В ArduinoRS485.h
void setSerial(HardwareSerial* serial);
В моем коде настройки я определил:
#define UART1_TX_PIN PA_9 // Заголовок J1 33 (LPUART) = SERIAL1_TX = R0
#define UART1_RX_PIN PA_10 // Заголовок J1 35 (LPUART) = SERIAL1_RX = DI
#define UART1_RTS_PIN PI_14 // Разъем J1 37 (LPUART) = SERIAL1_RTS = вывод REn
#define UART1_CTS_PIN PI_15 // Заголовок J1 39 (LPUART) = SERIAL1_CTS = DE
#define SERIAL_PORT_HARDWARE Serial1
Мой ModbusClient настроен
void modbusClientSetup() {
while (!Serial);
Serial.println("");
Serial.println("Modbus RTU Client Test");
RS485.setPins(UART1_TX_PIN, UART1_RX_PIN, UART1_RTS_PIN);
RS485.setDelays(50,50);
RS485.setSerial(&SERIAL_PORT_HARDWARE);
if(!ModbusRTUClient.begin(9600,SERIAL_8N1 )){
//Serial.println("Failed to start Modbus RTU Client!");
while (1);
}
}
Строка Serial.println("Modbus RTU Client Test"); работает нормально.
Then i run this code to test my Modbus
void writeCoilValues() {
// устанавливаем катушки на 1, когда счетчик нечетный
byte coilValue = ((counter % 2) == 0) ? 0x00 : 0x01;
Serial.print("Writing Coil values ... ");
// записать 10 значений катушки в (ведомый) идентификатор 1, адрес 0x00
ModbusRTUClient.beginTransmission(slaveID, COILS, 0x15, 10);> for (int i = 0;
i < 10; i++) {
counter = i;
coilValue = ((counter % 2) == 0) ? 0x00 : 0x01;
ModbusRTUClient.write(coilValue);
delay(100);
if (!ModbusRTUClient.endTransmission()) {
Serial.print("failed! ");
errClient = ModbusRTUClient.lastError();
Serial.println(errClient);
} else {
errClient = "All Good";
Serial.println("success");
}
}
Строка Serial.print("Writing Coil values ... "); не печатается, но код не зависает.
Но как только я дохожу до Serial.print("failed! "); код просто зависает на write_op.wait(NULL); в USBCDC.cpp ниже.
bool USBCDC::send(uint8_t *buffer, uint32_t size)
{
lock();
AsyncWrite write_op(this, buffer, size);
_tx_list.add(&write_op);
unlock();
write_op.wait(NULL);
return write_op.result;
}
Я проделывал это уже несколько дней, но так и не смог найти, где происходит сбой. Если у кого-то есть идея или лучший метод, пожалуйста, дайте мне знать.
Ура
@Dave by 2, 👍0
2 ответа
Лучший ответ:
Хорошо документировано, что в ArduinoRS485 объект RS485 подключен жестко.
Я не знаю, откуда вы черпаете эту «хорошо документированную» информацию, но и библиотека ArduinoRS485, и библиотека ArduinoModbus позволяют вам передавать последовательный порт, который вы собираетесь использовать, через конструкцию класса. Вы можете увидеть исходный код RS485 Construct и ModbusRTU Construct.
Итак, чтобы использовать Serial1, вам нужно создать экземпляр класса и передать ему последовательный порт, который вы собираетесь использовать.
#include <ArduinoRS485.h>
#include <ArduinoModbus.h>
#define UART1_TX_PIN PA_9 // Заголовок J1 33 (LPUART) = SERIAL1_TX = R0
#define UART1_RX_PIN PA_10 // Заголовок J1 35 (LPUART) = SERIAL1_RX = DI
#define UART1_RTS_PIN PI_14 // Разъем J1 37 (LPUART) = SERIAL1_RTS = вывод REn
#define UART1_CTS_PIN PI_15 // Заголовок J1 39 (LPUART) = SERIAL1_CTS = DE
RS485 rs485(Serial1, UART1_TX_PIN, UART1_RX_PIN, UART1_RTS_PIN, UART1_CTS_PIN);
ModbusRTUClient mbClient(&rs485);
void setup() {
Serial.begin(115200);
// запустить клиент Modbus RTU
if (!mbClient.begin(9600)) {
Serial.println("Failed to start Modbus RTU Client!");
while (1);
}
}
void loop() {
// доступ к различным методам ModbusRTUClient с помощью объекта mbClient
}
Спасибо это сработало (почти, мне пришлось внести несколько изменений, но это помогло мне добиться цели, я добавил требуемые изменения ниже). Я уже пробовал версию этого подхода раньше, но по какой-то причине мне не удалось заставить ее работать.
#include <ArduinoRS485.h>
#include <ArduinoModbus.h>
#define UART1_TX_PIN PA_9 // Заголовок J1 33 (LPUART) = SERIAL1_TX = R0
#define UART1_RX_PIN PA_10 // Заголовок J1 35 (LPUART) = SERIAL1_RX = DI
#define UART1_RTS_PIN PI_14 // Разъем J1 37 (LPUART) = SERIAL1_RTS = вывод REn
#define UART1_CTS_PIN PI_15 // Заголовок J1 39 (LPUART) = SERIAL1_CTS = DE
// Следующие две строки отличаются.
RS485Class rs485(Serial1, UART1_TX_PIN, UART1_RX_PIN, UART1_RTS_PIN);
ModbusRTUClientClass mbClient(&rs485);
void setup() {
Serial.begin(115200);
// запустить клиент Modbus RTU
if (!mbClient.begin(9600)) {
Serial.println("Failed to start Modbus RTU Client!");
while (1);
}
}
void loop() {
// доступ к различным методам ModbusRTUClient с помощью объекта mbClient
}
- Основная связь 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 и контроллером температуры