Взаимодействие с контроллером температуры Eurotherm 2416 через Modbus RS232
Я пытаюсь реализовать библиотеку Modbus, написанную smarmengol, для чтения значений процесса и установки новых заданных значений (например, температуры) на контроллере Eurotherm. Скетч Arduino выглядит так:
/**
* Мастер-устройство Modbus, пример 2:
* Целью этого примера является запрос нескольких наборов данных.
* от внешнего ведомого устройства Modbus.
* В качестве средства связи может использоваться USB или RS232.
*
* Рекомендуемое ведомое устройство Modbus:
* Diagslave http://www.modbusdriver.com/diagslave.html
*
* В системе Linux запустите
* "./diagslave /dev/ttyUSB0 -b 9600 -d 8 -s 1 -p none -m rtu -a 1"
* Это:
* последовательный порт /dev/ttyUSB0 на скорости 9600 бод 8N1
* Режим RTU и адрес @1
*/
#include <ModbusRtu.h>
#include <SoftwareSerial>
SoftwareSerial mySerial (3,5);
uint16_t au16data[16]; //!< массив данных для совместного использования сети Modbus
uint8_t u8state; //!< состояние машины
uint8_t u8query; //!< указатель на запрос сообщения
/**
* Modbus object declaration
* u8id : node id = 0 for master, = 1..247 for slave
* u8serno : serial port (use 0 for Serial)
* u8txenpin : 0 for RS-232 and USB-FTDI
* or any pin number > 1 for RS-485
*/
Modbus master(0); // это мастер и RS-232 или USB-FTDI
/**
* This is an structe which contains a query to an slave device
*/
modbus_t telegram[2];
unsigned long u32wait;
void setup() {
// телеграмма 0: чтение регистров
telegram[0].u8id = 1; // адрес подчиненного устройства
telegram[0].u8fct = 3; // код функции (это чтение регистров)
telegram[0].u16RegAdd = 1; // начальный адрес в подчиненном устройстве
telegram[0].u16CoilsNo = 1; // количество элементов (обмоток или регистров) для чтения
telegram[0].au16reg = au16data; // указатель на массив памяти в Arduino
// телеграмма 1: записываем один регистр
telegram[1].u8id = 1; // адрес подчиненного устройства
telegram[1].u8fct = 6; // код функции (это запись одного регистра)
telegram[1].u16RegAdd = 2; // начальный адрес в подчиненном устройстве
telegram[1].u16CoilsNo = 250; // (Setpoint) количество элементов (обмоток или регистров) для чтения
telegram[1].au16reg = au16data+4; // указатель на массив памяти в Arduino
Serial.begin(9600);
master.begin( &mySerial, 9600); // скорость передачи данных 9600
master.setTimeOut( 5000 ); // если ответа не будет в течение 5000 мс, перевернуться
u32wait = millis() + 1000;
u8state = u8query = 0;
}
void loop() {
switch( u8state ) {
case 0:
if (millis() > u32wait) u8state++; // состояние ожидания
break;
case 1:
master.query( telegram[u8query] ); // отправляем запрос (только один раз)
u8state++;
u8query++;
if (u8query > 2) u8query = 0;
break;
case 2:
master.poll(); //проверяем входящие сообщения
if (master.getState() == COM_IDLE) {
u8state = 0;
u32wait = millis() + 1000;
}
break;
}
Serial.print(au16data[O]);
au16data[4] = analogRead( 0 );
}
Я очень хорошо могу прочитать значения процесса с помощью телеграммы[0] (температура и/или заданное значение), но я не могу изменить заданное значение с помощью телеграммы[1]. Если я запускаю код, он отображает текущую температуру на последовательном мониторе, но сбрасывает заданные значения, измененные вручную, на ноль. Где ошибка? Должен ли я записать значение уставки в формате HEX или DEC? Что на самом деле делает последняя команда?
Спасибо!
@Viktor Scherf, 👍0
Обсуждение1 ответ
Вы также можете взглянуть на этот проект на GitHub: https://github.com/ukos-git/arduino-eurotherm2416
Он специально разработан для той цели, о которой вы просите. По сути, он включает в себя модуль с именем «Температура» и возможность его установки или чтения:
Temperature.set(100)
t = Temperature.getTemperature()
Посмотрите https://github.com/ukos-git/arduino -eurotherm2416/blob/master/app/app.ino.
- Подключите Arduino к ПЛК (обмен данными)
- Основная связь Arduino ModBus RTU с проблемой измерителя мощности
- Мониторинг контроллера Modbus RTU с помощью Arduino и модуля RS485
- Ардуино для чтения с преобразователя RS232 в последовательный модуль TTL
- Как читать и записывать на устройство rs232 с/на Arduino
- Связь Arduino Uno и ESP32 с использованием RS485
- Использование сервера Modbus TCP на Arduino
- Управление VFD с помощью ModBus RTU через RS485 и Arduino
1) telegram[1].u16CoilsNo = похоже, что это должно быть 1, а не 250 (запись одного 16-битного регистра); 2) вы пишете в тот же регистр/установку, которую прочитали в Telegram[0]? если да, то почему адрес u16RegAdd отличается?, @Flanker
@Flanker Вы правы, это должно быть 1 (один регистр), а не 250. Решением моей проблемы было установить для
au16data[4]
фиксированное значение, например 250, или что-то в этом роде. Я думаю, чтоau16data[4]
можно установить в интерактивном режиме, отправив любое число через последовательный аппаратный порт, посколькуanalogRead(0)
— это Rx на Arduino. Начальный адрес для установки (записи) уставки равен 2 и 1 для чтения того же значения (уставки). Вот чем отличаетсяau16RegAdd
. Спасибо за ответ!!, @Viktor Scherf