Получение ответа от MODBUS устройства?

Antarius
Offline
Зарегистрирован: 08.02.2017

Привет.

Пытаюсь прочитать мультиметр производства 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;    
  }  
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino/blob/maste...

Видите там, в конце, println() - вот он выводит содержимое запрошенных регистров.

Antarius
Offline
Зарегистрирован: 08.02.2017

Спасибо за ответ.

Я встречал этот пример, но он увы не работает.

Если создать softSerial для вывода au16data[] и открыть два терминала - один на Serial, а другой на softSerial, то можно увидеть, как на первом совершенно правильно и ожидаемо работает modbus, а на втором - выводятся одни сплошные нули из регистров, хотя там точно должны быть данные.

Так что, вопрос остается.

b707
Offline
Зарегистрирован: 26.05.2017

Antarius - так обсуждать бессмысленно, выкладывайте код, где вы бы пытались вывести содержимое регистра в сериал. В коде в заглавном сообщении ничего похожего нет.

sadman41
Offline
Зарегистрирован: 19.10.2016

Ответ уже озвучен - все данные находятся в массиве au16data, а вывести их можно указанным в примере с софтсериалом способом. Если же вы не можете совладать с самим софтсериалом - это вопрос совершенно из другой оперы. Возьмите МК с двумя хардварными сериалами.

Хотя я вполне успешно, как помню, читал наной и этой библиотекой китайский трёхфазный счётчик по модбасу. Правда, там другая заковыка получилась и библиотеку модбаса перелицевать пришлось...