Получение ответа от MODBUS устройства?
- Войдите на сайт для отправки комментариев
Привет.
Пытаюсь прочитать мультиметр производства ABB по модбас.
Наверное, это очень тупой вопрос, но как получить ответ устройства, к которому обращается мастер?
Если этот код запустить и открыть терминал, то все прекрасно работает - мастер(ардуино) отправляет запрос, и мультметр ему отвечает. Проверил по инструкции - отвечает правильно, все параметры те же, что и на дисплее. Т.е. все корректно. Еще раз, повторю, все в железе правильно соединено и все корректно работает.
Но как в программу получить эти данные?
Конструкции типа x=master.poll(); - в x какая-то хрень, ничего общего с ответом устройства не имеющая?
Если кто знает, напишите пример получения ответа в виде массива байтов из ответа, пожалуйста.
Спасибо.
/** * Modbus master example 2: * The purpose of this example is to query several sets of data * from an external Modbus slave device. * The link media can be USB or RS232. * * Recommended Modbus slave: * diagslave http://www.modbusdriver.com/diagslave.html * * In a Linux box, run * "./diagslave /dev/ttyUSB0 -b 19200 -d 8 -s 1 -p none -m rtu -a 1" * This is: * serial port /dev/ttyUSB0 at 19200 baud 8N1 * RTU mode and address @1 */ #include <ModbusRtu.h> uint16_t au16data[16]; //!< data array for modbus network sharing uint8_t u8state; //!< machine state uint8_t u8query; //!< pointer to message query /** * Modbus object declaration * u8id : node id = 0 for master, = 1..247 for slave * port : serial port * u8txenpin : 0 for RS-232 and USB-FTDI * or any pin number > 1 for RS-485 */ Modbus master(0,Serial,2); // this is master and RS-232 or USB-FTDI /** * This is an structe which contains a query to an slave device */ modbus_t telegram[2]; unsigned long u32wait; void setup() { // telegram 0: read registers telegram[0].u8id = 0x01; // slave address telegram[0].u8fct = 0x03; // function code (this one is registers read) telegram[0].u16RegAdd = 0x00; // start address in slave telegram[0].u16CoilsNo = 0x04; // number of elements (coils or registers) to read telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino Serial.begin( 9600 ); // baud-rate at 19200 master.start(); master.setTimeOut( 500 ); // if there is no answer in 5000 ms, roll over u32wait = millis() + 1000; u8state = u8query = 0; } void loop() { switch( u8state ) { case 0: if (millis() > u32wait) u8state++; // wait state break; case 1: master.query( telegram[u8query] ); // send query (only once) u8state++; u8query++; if (u8query > 2) u8query = 0; break; case 2: master.poll(); // check incoming messages if (master.getState() == COM_IDLE) { u8state = 0; u32wait = millis() + 1000; } break; } }
https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino/blob/maste...
Видите там, в конце, println() - вот он выводит содержимое запрошенных регистров.
Спасибо за ответ.
Я встречал этот пример, но он увы не работает.
Если создать softSerial для вывода au16data[] и открыть два терминала - один на Serial, а другой на softSerial, то можно увидеть, как на первом совершенно правильно и ожидаемо работает modbus, а на втором - выводятся одни сплошные нули из регистров, хотя там точно должны быть данные.
Так что, вопрос остается.
Antarius - так обсуждать бессмысленно, выкладывайте код, где вы бы пытались вывести содержимое регистра в сериал. В коде в заглавном сообщении ничего похожего нет.
Ответ уже озвучен - все данные находятся в массиве au16data, а вывести их можно указанным в примере с софтсериалом способом. Если же вы не можете совладать с самим софтсериалом - это вопрос совершенно из другой оперы. Возьмите МК с двумя хардварными сериалами.
Хотя я вполне успешно, как помню, читал наной и этой библиотекой китайский трёхфазный счётчик по модбасу. Правда, там другая заковыка получилась и библиотеку модбаса перелицевать пришлось...