#1 2017-04-07 16:57:07

VaDoSiQ
Участник
Из Ukraine
Зарегистрирован: 2017-02-06
Сообщений: 4

Считывание данных по ModBus RTU

Здравствуйте. У меня имеется частотный преобразователь серии VLT 2800 компании Danfoss. Работает он по протоколу ModBus RTU через интерфейс RS485.
Мне нужно считать данные с нужного мне регистра, записать их в переменную и вывести в порт Arduino.
Вот моя схема подключения:
Cxema.png
Вот скетч:

#include <ModbusRtu.h>

// data array for modbus network sharing
uint16_t au16data[16];
uint8_t u8state;

/**
 *  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,0,10); // this is master and RS-232 or USB-FTDI

/**
 * This is an structe which contains a query to an slave device
 */
modbus_t telegram;

unsigned long u32wait;

void setup() {
  master.begin( 9600 ); // baud-rate at 19200
  master.setTimeOut( 2000 ); // if there is no answer in 2000 ms, roll over
  u32wait = millis() + 1000;
  u8state = 0; 
}

void loop() {
  switch( u8state ) {
  case 0: 
    if (millis() > u32wait) u8state++; // wait state
    break;
  case 1: 
    telegram.u8id = 1; // slave address
    telegram.u8fct = 3; // function code (this one is registers read)
    telegram.u16RegAdd = 29; // start address in slave
    telegram.u16CoilsNo = 2; // number of elements (coils or registers) to read
    telegram.au16reg = au16data; // pointer to a memory array in the Arduino
    master.query( telegram ); // send query (only once)
    Serial.println();
    Serial.print(au16data[16]);
    Serial.println();
    u8state++;
    break;
  case 2:
    master.poll(); // check incoming messages
    if (master.getState() == COM_IDLE) {
      u8state = 0;
      u32wait = millis() + 1000; 
    }
    break;
  }
}

Когда я считываю 29 регистр, в порту мне пишет вот это:
Cxema2.png
Хотя в регистре, значение равно: 1500.
Вот что пишет в Termite:
Cxema3.png
Так же у меня имеется USB to RS485 Converter, вот пример его работы, через программу QModBUS:
rrara.png
Запрос ModBus: 01  03  00 1d  00 02
Ответ ModBus: 01 03 04 00 00 05 dc f8 fa
Подскажите пожалуйста, что я делаю не так? Уже вторую неделю голову ломаю.

#2 2017-04-07 18:05:32

NoName
Customer
Из Київ
Зарегистрирован: 2014-07-08
Сообщений: 1,220

Re: Считывание данных по ModBus RTU

отправьте  01  03  00 1d  00 02   и обработайте ответ, дальше будет проще

#3 2017-04-07 18:25:37

VaDoSiQ
Участник
Из Ukraine
Зарегистрирован: 2017-02-06
Сообщений: 4

Re: Считывание данных по ModBus RTU

Я дико извеняюсь, но не могли бы вы мне подробнее обьяснить? Желательно программно. Отправить и обработать я и без Arduino могу.

#4 2017-04-07 19:50:34

NoName
Customer
Из Київ
Зарегистрирован: 2014-07-08
Сообщений: 1,220

Re: Считывание данных по ModBus RTU

дайте урл на
#include <ModbusRtu.h>
посмотрю на код
кто делал то либу?

#5 2017-04-08 07:48:50

NoName
Customer
Из Київ
Зарегистрирован: 2014-07-08
Сообщений: 1,220

Re: Считывание данных по ModBus RTU

у Вас ведь именно на arduino не работает )
отправьте сырой пакет, я ведь даже не догадываюсь какой у вас arduino, и особо нет смысла ковырять, я для себя выбрал micro где debug serial USB, и  есть UART и не парюсь о конфликтах (типа как в nano)

условно я так работаю

QByteArray Client::MOD_ReadRegister(unsigned char NetID, unsigned char CODE, unsigned short NRegister,unsigned short COUNT )
{
unsigned short us;
QByteArray TransmitBuffer;

TransmitBuffer[0] = NetID;
TransmitBuffer[1] = CODE;

unsigned char *puc=(unsigned char *)&NRegister;
TransmitBuffer[2] = puc[1];
TransmitBuffer[3] = puc[0];

unsigned char *puc2=(unsigned char *)&COUNT;
TransmitBuffer[4] = puc2[1];
TransmitBuffer[5] = puc2[0];

puc = (unsigned char *)&us;
us = CRC16_modbus( TransmitBuffer , 6);
TransmitBuffer[6]=puc[0];
TransmitBuffer[7]=puc[1];

return ( TransmitBuffer );
}

подготовил данные,  перевел UART-485 на передачу,
отправил данные, дождался окончания передачи
есть 2 варианта, использовать аппаратное echo или по прерыванию по выгрузке uart buffer в аппаратный канал
но никак не по по загрузке в  uart buffer, в меге есть такое?
далее принял ожидаемое количество байт, или считаю все на лету
и на обработку принятых данных, 

если au16data ответ,
    Serial.println();
    Serial.print(au16data[16]);
    Serial.println();

то почему есть запрос? общий serial?

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

#6 2017-09-13 08:34:18

enyuzer
Участник
Зарегистрирован: 2017-08-19
Сообщений: 1

Re: Считывание данных по ModBus RTU

Добрый день.
Подскажите, пожалуйста, где взять ModbusRtu.h. У меня проект в arduino-1.8.4-windows для Arduino Uno с RC522. Тему свою не создаю, т.к. пока ничего новенького. Просто RFID метку считал быстро и без проблем.

#7 2017-09-14 21:25:20

Lic Control
Участник
Зарегистрирован: 2016-01-23
Сообщений: 43

Re: Считывание данных по ModBus RTU

По моему мнению, которое сложилось после многократных попыток использовать сеть Modbus через Arduino это не очень удачное решение. Намного проще, надежнее и стабильнее работать с Modbus через Raspberry / Orange Pi и библиотеку, например minimalmodbus под Python.
У меня, например через Modbus соединяются комнатные термостаты с контроллером на Orange Pi
Liccontrol.com
Комнатные термостаты или универсальный сенсорные панели я делаю из мобильных телефонов.
Работает и выглядит отлично. По функционалу, дизайну и цене конкурентов я пока не нашел.
Подробнее можно почитать на сайте liccontrol.com

Быстрое сообщение

Введите сообщение и нажмите Отправить

Подвал раздела