Китайский MODBUS релейный модуль

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Ребят, здрасте, давно меня тут не было)

Нужна помощь с модбасом. Как то особо не попадалось с ним работать, опыта с этим протоколом практически нет. Сейчас стоит задача с такого модуля считать входы и щёлкать релюхами.

Есть вот такое описалово на странице товара, у продавана более выудить ничего не смог. т.к. толком с модбасом не сталкивался + это описание...затуп.

 

Modbus RTU инструкция

Скорость передачи данных: 96008 нет 1

Шестнадцатеричный передачи
Шестнадцатеричный приема

Управление шаги:
1. Настройка программного обеспечения скорость передачи данных
2. Адрес настройки (адрес устройства для связи, адрес по умолчанию 01)

/*********************************************************************************************************************************/

Примечание: подключено только одно устройство, иначе будет установлен адрес.
Установите Адрес: 01
00 100 00 00 01 02 00 01 6 A 00/изменить 01
Установите Адрес: 02
00 100 00 00 01 02 00 02 2A 01/изменить 02
Установите Адрес: 03
00 100 00 00 01 02 00 03 EB C1/изменить 03


Прочитайте адрес
00 03 00 00 01 85 дБ
Возврат:
00 03 02 00 01 44 44/01 как адрес

/*********************************************************************************************************************************/
/*********************************************************************************************************************************/
Значение каждого байта:
[1]
/------------------------------------------------------------------------------------------------------------------------------------------------
№ 1 реле: 01 05 00 01 00 9D 9A

Байт 1: адрес
Байт 2: функция?
Байт 34: адрес регистрации
Байт 56: данные регистрации
Байт 7 8: проверка CRC

/==============================================================
[1]
/------------------------------------------------------------------------------------------------------------------------------------------------
№0 реле: 01 05 00 FF 00 8C 3A
№0 реле Закрыто: 01 05 00 00 00 00 компакт-дисков CA
/------------------------------------------------------------------------------------------------------------------------------------------------
№ 1 реле: 01 05 00 01 FF 00 DD FA
№ 1 реле Выключите: 01 05 00 01 00 9C 0A
/------------------------------------------------------------------------------------------------------------------------------------------------
№ 2 реле: 01 05 00 02 FF 00 2D фа
№ 2 реле Выключите: 01 05 00 02 00 06C 0A
/------------------------------------------------------------------------------------------------------------------------------------------------
№ 3 реле: 01 05 00 03 FF 00 7C 3A
№ 3 реле Выключите: 01 05 00 03 00 3D CA
/------------------------------------------------------------------------------------------------------------------------------------------------
№ 4 реле: 01 05 00 04 FF 00 CD FB
№ 4 реле отключения: 01 05 00 04 00 8C 0B
/------------------------------------------------------------------------------------------------------------------------------------------------
№ 5 реле: 01 05 00 05 FF 00 9C 3B
№ 5 реле Закрыто: 01 05 00 05 00 00 DD сертификатом от сертификационной
/------------------------------------------------------------------------------------------------------------------------------------------------
№ 6 реле: 01 05 00 06 FF 00 6C 3B
Реле № 6 Выключите: 01 05 00 06 00 2D сертификатом от сертификационной
/------------------------------------------------------------------------------------------------------------------------------------------------
№ 7 реле: 01 05 00 07 FF 00 3D FB
Реле № 7 Выключите: 01 05 00 07 00 07 C 0B
/------------------------------------------------------------------------------------------------------------------------------------------------

/********************************************************************************************************************************/
Чтение № 0 статус реле: 01 01 00 00 01 FD CA
Прочитайте № 1 реле статуса: 01 01 00 01 01 AC 0A
Прочитайте 2 реле статуса: 01 01 00 02 00 01 5C 0A
Прочитайте 3 реле статуса: 01 01 00 03 00 01 0D CA
Читайте о статусе № 4 реле: 01 01 00 04 00 01 BC 0B
Прочитайте № 5 реле статуса: 01 01 00 05 00 01 ED сертификатом от сертификационной
Прочитайте № 6 реле статуса: 01 01 00 06 00 01 1D сертификатом от сертификационной
Прочитайте 7 реле статуса: 01 01 00 07 00 01 4C 0B

Прочитали все реле статуса: 01 01 00 00 08 3D CC
/*********************************************************************************************************************************/
Чехол-книжка с инструкции:
Описание: закройте сразу после открытия. 100 мс является единицей [1 стенда для 100 мс]

Адрес № 1:
№0 реле перегрева: 01 05 02 00 07 00 CE 42/700 MS = 7*100 MS = 700 мс
№ 1 реле перегрева: 01 05 01 02 08 00 9A 72/800 MS
Возврат: то же, что и инструкции по отправке
Адрес (строка 2):
№0 реле перегрева: 02 05 02 00 05 00/CF/11/500 MS
№ 1 реле перегрева: 02 05 01 02 06 00 9E 21/600 MS

/======================================================================
Полного исчезновения: 01 0F 00 00 00 08 01 00 FE 95
Полный яркий: 01 0F 00 00 08 01 FF быть D5

/********************************************************************************************************************************/
Один Чехол-книжка Инструкция:
№0 реле флип: 01 05 00 55 00 F2 9A
№ 1 реле флип: 01 05 00 01 55 00 A3 5A
№ 2 реле опрокидывания: 01 05 00 02 55 00 53 5A
№ 3 реле опрокидывания: 01 05 00 03 55 00 02 9A
№ 4 реле флип: 01 05 00 04 55 00 B 3 5B
№ 5 реле опрокидывания: 01 05 00 05 55 00 E2 9B
№ 6 реле опрокидывания: 01 05 00 06 55 00 129B
№ 7 реле флип: 01 05 00 07 55 00 43 5B

Все флип инструкции по уходу за изделием
01 05 00 5A 00 F7 6A

/***********************************************************************************************************************************/
Считывайте Все входные состояния интерфейса
Отправка: 01 02 00 00 00 08 79 CC/чтения 8 входных сигналов государства
Возврат: 01 02 01 00 A1 88

с одной стороны у меня мега(controllino), с другой эта штуковина.

Так понимаю у меня мега будет мастером и должна опрашивать регистры входов и писать в регистры реле?

Мастер адрес 0, а слэйв 1.

Я так понимаю я записываю один байт в конкретный регистр этот байт в бинарном виде будет устанавливать состояния реле и при считывании наоборот, считываю байт из определённого регистра и состояние бит в байте мне показывают состояние входа?

На сайте cotrollino есть такой пример для modbus master, что то я совсем подвис как описалово от модуля применить к этому примеру.

Где в этом примере задаются адреса регистров для считывания\записи?

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */
#include "ModbusRtu.h" /* Usage of ModBusRtu library allows you to implement the Modbus RTU protocol in your sketch. */

// This MACRO defines Modbus master address.
// For any Modbus slave devices are reserved addresses in the range from 1 to 247.
// Important note only address 0 is reserved for a Modbus master device!

#define MasterModbusAdd 0
#define SlaveModbusAdd 1

// This MACRO defines number of the comport that is used for RS 485 interface.
// For MAXI and MEGA RS485 is reserved UART Serial3.
#define RS485Serial 3

// The object ControllinoModbuSlave of the class Modbus is initialized with three parameters.
// The first parametr specifies the address of the Modbus slave device.
// The second parameter specifies type of the interface used for communication between devices - in this sketch - RS485.
// The third parameter can be any number. During the initialization of the object this parameter has no effect.
Modbus ControllinoModbusMaster(MasterModbusAdd, RS485Serial, 0);

// This uint16 array specified internal registers in the Modbus slave device.
// Each Modbus device has particular internal registers that are available for the Modbus master.
// In this example sketch internal registers are defined as follows:
// (ModbusSlaveRegisters 0 - 3 read only and ModbusSlaveRegisters 4 - 7 write only from the Master perspective):
// ModbusSlaveRegisters[0] - Read an analog value from the CONTROLLINO_A0 - returns value in the range from 0 to 1023.
// ModbusSlaveRegisters[1] - Read an digital value from the CONTROLLINO_D0 - returns only the value 0 or 1.
// ModbusSlaveRegisters[2] - Read the number of incoming messages - Communication diagnostic.
// ModbusSlaveRegisters[3] - Read the number of number of outcoming messages - Communication diagnostic.
// ModbusSlaveRegisters[4] - Sets the Relay output CONTROLLINO_R0 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[5] - Sets the Relay output CONTROLLINO_R1 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[6] - Sets the Relay output CONTROLLINO_R2 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[7] - Sets the Relay output CONTROLLINO_R3 - only the value 0 or 1 is accepted.
uint16_t ModbusSlaveRegisters[8];

// This is an structe which contains a query to an slave device
modbus_t ModbusQuery[2];

uint8_t myState; // machine state
uint8_t currentQuery; // pointer to message query

unsigned long WaitingTime;

void setup() {
 // initialize serial communication at 9600 bits per second:
 Serial.begin(9600);
 Serial.println("-----------------------------------------");
 Serial.println("CONTROLLINO Modbus RTU Master Test Sketch");
 Serial.println("-----------------------------------------");
 Serial.println("");
 // ModbusQuery 0: read registers
 ModbusQuery[0].u8id = SlaveModbusAdd; // slave address
 ModbusQuery[0].u8fct = 3; // function code (this one is registers read)
 ModbusQuery[0].u16RegAdd = 0; // start address in slave
 ModbusQuery[0].u16CoilsNo = 4; // number of elements (coils or registers) to read
 ModbusQuery[0].au16reg = ModbusSlaveRegisters; // pointer to a memory array in the CONTROLLINO

 // ModbusQuery 1: write a single register
 ModbusQuery[1].u8id = SlaveModbusAdd; // slave address
 ModbusQuery[1].u8fct = 6; // function code (this one is write a single register)
 ModbusQuery[1].u16RegAdd = 4; // start address in slave
 ModbusQuery[1].u16CoilsNo = 1; // number of elements (coils or registers) to write
 ModbusQuery[1].au16reg = ModbusSlaveRegisters+4; // pointer to a memory array in the CONTROLLINO
 ModbusSlaveRegisters[4] = 1; // initial value for the relays 
 
 ControllinoModbusMaster.begin( 19200 ); // baud-rate at 19200
 ControllinoModbusMaster.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over
 
 WaitingTime = millis() + 1000;
 myState = 0;
 currentQuery = 0; 
}

void loop() {
 switch( myState ) {
 case 0: 
 if (millis() > WaitingTime) myState++; // wait state
 break;
 case 1: 
 Serial.print("---- Sending query ");
 Serial.print(currentQuery);
 Serial.println(" -------------");
 ControllinoModbusMaster.query( ModbusQuery[currentQuery] ); // send query (only once)
 myState++;
 currentQuery++;
 if (currentQuery == 2) 
 {
 currentQuery = 0;
 }
 break;
 case 2:
 ControllinoModbusMaster.poll(); // check incoming messages
 if (ControllinoModbusMaster.getState() == COM_IDLE) 
 {
 // response from the slave was received
 myState = 0;
 WaitingTime = millis() + 1000; 
 // debug printout
 if (currentQuery == 0)
 {
 // registers write was proceed
 Serial.println("---------- WRITE RESPONSE RECEIVED ----");
 Serial.println("");
 }
 if (currentQuery == 1)
 {
 // registers read was proceed
 Serial.println("---------- READ RESPONSE RECEIVED ----");
 Serial.print("Slave ");
 Serial.print(SlaveModbusAdd, DEC); 
 Serial.print(" ADC0: 0x");
 Serial.print(ModbusSlaveRegisters[0], HEX);
 Serial.print(" , Digital0: ");
 Serial.print(ModbusSlaveRegisters[1], BIN);
 Serial.print(" , ModbusCounterIn: ");
 Serial.print(ModbusSlaveRegisters[2], DEC);
 Serial.print(" , ModbusCounterOut: ");
 Serial.println(ModbusSlaveRegisters[3], DEC);
 Serial.println("-------------------------------------");
 Serial.println("");

 // toggle with the relays
 ModbusQuery[1].u16RegAdd++;
 if (ModbusQuery[1].u16RegAdd == 8)
 {
 ModbusQuery[1].u16RegAdd = 4;
 if (ModbusSlaveRegisters[4]) 
 {
 ModbusSlaveRegisters[4] = 0;
 }
 else 
 {
 ModbusSlaveRegisters[4] = 1;
 }
 }
 }
 }
 break;
 }
}

 

 ModbusQuery[0].u8id = SlaveModbusAdd; // тут понятно адрес модуля "1"
 ModbusQuery[0].u8fct = 3; // функция читаем остаётся та же "3"
 ModbusQuery[0].u16RegAdd = 0; // Какой адрес регистра мне считывать????
 ModbusQuery[0].u16CoilsNo = 4; // количество регистров "1"?
 ModbusQuery[0].au16reg = ModbusSlaveRegisters; // массив считанных байт или регистров(совсем запутался)

Помогите разобраться?!

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

судя по картинке, этим модулем кроме модбаса можно управлять пинами ардуины, как в самом обычном реле. Так что если вам самому не нужен модбас - не парьтесь

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

b707 пишет:

судя по картинке, этим модулем кроме модбаса можно управлять пинами ардуины, как в самом обычном реле. Так что если вам самому не нужен модбас - не парьтесь

не, это дискретные входы, т.е. в модбас...

И у меня на меге всё занято, для этого мне и нужно прикрутить этот модуль...

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

Чтобы начать изучать Modbus, необходимо иметь, как минимум: https://www.modbusdriver.com/modpoll.html (есть и покруче утилиты) и 

 

А иначе это будет битва добра со злом. 

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

usb rs конвертер где то валяется...ну всё равно вопрос открытый остаётся, с какими регистрами мне работать...из описания к железке ничего не понятно...

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

knack пишет:

usb rs конвертер где то валяется...ну всё равно вопрос открытый остаётся, с какими регистрами мне работать...из описания к железке ничего не понятно...

так вам даже пример вроде дали - там все адреса и регистры прописаны. Вы для начала на железе с этим кодом попробуйте - глядишь все и прояснится

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

b707 пишет:

knack пишет:

usb rs конвертер где то валяется...ну всё равно вопрос открытый остаётся, с какими регистрами мне работать...из описания к железке ничего не понятно...

так вам даже пример вроде дали - там все адреса и регистры прописаны. Вы для начала на железе с этим кодом попробуйте - глядишь все и прояснится

этот пример от библиотеки он к модулю не имеет отношения, эту библиотеку производитель controllino рекомендует, с этой библиотекой идёт этот пример. Хотя на этом ПЛК все библиотеки заводятся лишь бы по пинам сросталось. по крайней мере MQTT с полпинка завелось. 

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

я не совсем понимаю, в чем вопрос

Вот кусок из китайского описания:

Байт 1: адрес
Байт 2: функция?
Байт 34: адрес регистрации
Байт 56: данные регистрации
Байт 7 8: проверка CRC

вот кусок из примера либы

ModbusQuery[0].u8id = SlaveModbusAdd; // тут понятно адрес модуля "1"
ModbusQuery[0].u8fct = 3; // функция читаем остаётся та же "3"
ModbusQuery[0].u16RegAdd = 0; // Какой адрес регистра мне считывать????
ModbusQuery[0].u16CoilsNo = 4; // количество регистров "1"?
ModbusQuery[0].au16reg = ModbusSlaveRegisters; 

соответствия не замечаете?

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

b707 пишет:

я не совсем понимаю, в чем вопрос

Вот кусок из китайского описания:

Байт 1: адрес
Байт 2: функция?
Байт 34: адрес регистрации
Байт 56: данные регистрации
Байт 7 8: проверка CRC

вот кусок из примера либы

ModbusQuery[0].u8id = SlaveModbusAdd; // тут понятно адрес модуля "1"
ModbusQuery[0].u8fct = 3; // функция читаем остаётся та же "3"
ModbusQuery[0].u16RegAdd = 0; // Какой адрес регистра мне считывать????
ModbusQuery[0].u16CoilsNo = 4; // количество регистров "1"?
ModbusQuery[0].au16reg = ModbusSlaveRegisters; 

соответствия не замечаете?

похоже на правду, только мне больше эта шпора помогла )

надо до железок добраться.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Любит у нас народ всякую гадость по помойкам собирать :)

https://ru.wikipedia.org/wiki/Modbus

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Реле щёлкать получилось, но чуствую делаю это неправильно:

unsigned long premil = 0;
boolean state[] = {false, false, false, false, false, false, false, false};
int numRelay = 0;

#include <Controllino.h> /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */
#include "ModbusRtu.h" /* Usage of ModBusRtu library allows you to implement the Modbus RTU protocol in your sketch. */
#define MasterModbusAdd 0
#define SlaveModbusAdd 1
#define RS485Serial 3
Modbus ControllinoModbusMaster(MasterModbusAdd, RS485Serial, 0);
uint16_t ModbusSlaveRegisters[16];
modbus_t ModbusQuery[2];
uint8_t myState; // machine state
uint8_t currentQuery; // pointer to message query

unsigned long WaitingTime;

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(115200);
  Serial.println("-----------------------------------------");
  Serial.println("CONTROLLINO Modbus RTU Master Test Sketch");
  Serial.println("-----------------------------------------");
  Serial.println("");
  // ModbusQuery 0: read registers
  ModbusQuery[0].u8id = SlaveModbusAdd; // slave address
  ModbusQuery[0].u8fct = 2; // function code (this one is registers read)
  ModbusQuery[0].u16RegAdd = 1; // start address in slave
  ModbusQuery[0].u16CoilsNo = 8; // number of elements (coils or registers) to read
  ModbusQuery[0].au16reg = ModbusSlaveRegisters+7; // pointer to a memory array in the CONTROLLINO

  // ModbusQuery 1: write a single register
  ModbusQuery[1].u8id = SlaveModbusAdd; // slave address
  ModbusQuery[1].u8fct = 5; // function code (this one is write a single register)
  ModbusQuery[1].u16RegAdd = 0; // start address in slave
  ModbusQuery[1].u16CoilsNo = 7; // number of elements (coils or registers) to write
  ModbusQuery[1].au16reg = ModbusSlaveRegisters + 1; // pointer to a memory array in the CONTROLLINO
  //ModbusSlaveRegisters[4] = 1; // initial value for the relays

  ControllinoModbusMaster.begin( 9600 ); // baud-rate at 19200
  ControllinoModbusMaster.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over
}

void loop() {
ControllinoModbusMaster.poll();
if(millis() - premil > 1000){
  numRelay++;
  if(numRelay>7)numRelay = 0;
  state[numRelay] = !state[numRelay];

for(int i =0; i < 8; i++){
        Serial.print("Input");
        Serial.print(i);
        Serial.print(": ");
        Serial.print(ModbusSlaveRegisters[i+8], BIN);
        Serial.println();
}
 
  if(state[numRelay])modbusRelay(numRelay,1);
  else modbusRelay(numRelay,0);
  premil = millis();
}
}
void modbusRelay(int numRelay, int stateRelay) {
  if (ControllinoModbusMaster.getState() == COM_IDLE){
    ModbusQuery[1].u16RegAdd = numRelay;
    ModbusSlaveRegisters[numRelay] = stateRelay;
    ControllinoModbusMaster.query( ModbusQuery[1]);
  }
}

Этот ModbusSlaveRegisters массив собирает в себя данные с регистров слейва. ControllinoModbusMaster.poll() я так понял проверяет полученные пакеты.

С 26й по 30ю строку, что то не то...как мне теперь считать входы?

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Никак не выходит малахитовый цветок (

Подключил модуль к usb конвертеру, регистры читаются

Подключаю к CONTROLLINO глухо...

/**
    Modbus master example 1:
    The purpose of this example is to query an array 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>

// 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
    port : serial port
    u8txenpin : 0 for RS-232 and USB-FTDI
                 or any pin number > 1 for RS-485
*/
Modbus master(0, Serial3, 0); // 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;
int preSendTel = 0;
void setup() {
  Serial.begin( 115200 ); // baud-rate at 19200
  master.begin(9600);
  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 = 2; // function code (this one is registers read)
      telegram.u16RegAdd = 0; // start address in slave
      telegram.u16CoilsNo = 8; // 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)
      u8state++;
      break;
    case 2:
      master.poll(); // check incoming messages
      if (master.getState() == COM_IDLE) {
        u8state = 0;
        u32wait = millis() + 100;
      }
      break;
  }
  
  if(preSendTel != master.getOutCnt()){
        Serial.print("Send: ");
        Serial.print(master.getOutCnt());
        Serial.print("  Incoming: ");
        Serial.print(master.getInCnt());
        Serial.print("  Errors: ");
        Serial.print(master.getErrCnt());
        Serial.print("  Error type: ");
        switch (master.getLastError()) {
          case 255: Serial.println("Time - out");
            break;
          case 1: Serial.println("Function code not available");
            break;
          case 2: Serial.println("Address beyond available space for Modbus registers");
            break;
          case 3: Serial.println("Coils or registers number beyond the available space");
            break;
            default: Serial.println();
        }
        for(int i = 0; i<16; i++){
        Serial.print(" ");
        Serial.print(au16data[i],HEX);  
        }
        Serial.println();
        preSendTel = master.getOutCnt();
        
}
}

 

Согласно даташиту RS конвертер на CONTROLLINO сидит на Serial3

При этом до этого получалось дёргать реле...

Что я делаю не так?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Что не так ?
Все не так.
Вам же дали ссылку на описание протокола, изучайте.
Сам долго бился, пока не въехал.
Потом все стало ясно и прозрачно.

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

knack пишет:

Что я делаю не так?

Как правило - без моделирования ситуации на схожем железе никто не возьмется давать ответ. А у кого это контроллино и девайс ваш есть?

У меня вот был китайский счётчик, который тоже не отвечал в определённых условиях. Условия эти были - слишком большое, по мнению счётчика, кол-во запрошенных регистров. Нашёл только методом тыка.

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Там на борту та же мега и IDE определяет её как мегу. По поводу RE,DE они обязательно должны подключены? По даташиту они на 68 и 69 пинах, да и микросхема преобразователя скорее всего max485. Пробовал в лоб отсылать, что то типа этого:

byte a[] = {0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x79, 0xCC};
unsigned long preMillis = 0;

#define RE A14
#define DE A15

void setup() {
  Serial.begin(115200);
  Serial3.begin(9600);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);
}

void loop() {
  if (millis() - preMillis > 1000 ) {
    preMillis = millis();
    digitalWrite(RE,LOW);
    digitalWrite(DE,HIGH);
    delay(5);
    Serial.println("Send");
    Serial3.write(a,16);
    delay(5);
    }
    digitalWrite(DE,LOW);
    digitalWrite(RE,HIGH);
  }

  if (Serial3.available() > 0) {
    Serial.println("incoming:");
    Serial.println(Serial3.read(), HEX);
  }
}

В ответ тишина, ни мусора ничего...(

Может что то с CRC или с таймингами, или я какую то мелочь упускаю, глаза уже замылились...(

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

Вам надо воткнуть в винду свисток, запустить терминал. Свисток по 485 соединить с контролиной. Проверить простой коннект на read/write.

Затем - найти ModBus сервер. Запустить его и натравить на свисток, который по 485 будет продолжен быть соединен с контролиной. Контролину сделать клиентом и дёргать ею виндовый Modbus, да смотреть ему в логи.

Так будет понятно хотя бы - работает какой-либо компонент или нет. Сейчас же локализовать проблему вы не можете, поэтому и мечетесь.

 

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Я же это сделал 4 поста выше, вы да же не смотрите...(

Аааа...пробовать наоборот, как вариант....

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

Я вижу "Подключил модуль к usb конвертеру, регистры читаются" - контролино тут никак не проверено.

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Свисток подключил к rs контроллино, залил это:

byte a[] = {0x01, 0x05, 0x00, 0x01, 0xFF, 0x00, 0xDD, 0xFA};
unsigned long preMillis = 0;

#define RE A14
#define DE A15

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial3.begin(9600);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);

  digitalWrite(DE, LOW);
  digitalWrite(RE, HIGH);
}

void loop() {
  //  if (millis() - preMillis > 1000 ) {
  //    preMillis = millis();
  //    digitalWrite(RE,LOW);
  //    digitalWrite(DE,HIGH);
  //    //delay(10);
  //    Serial.println("Send");
  //    //for(int i = 0; i<8; i++){
  //    //Serial3.write(a,16);
  //    delay(5);
  //    //}
  //    digitalWrite(DE,LOW);
  //    digitalWrite(RE,HIGH);
  //  }



  if (Serial3.available() > 0) {
    Serial.println("incoming:");
    Serial.println(Serial3.read(), HEX);
  }
}

с термита отправляю "типа" запрос на считывание 01 02 00 00 00 08, буфер Serial3 пустой...так ведь не должно быть?

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

Ну да, нездоровая ситуация. Хоть что-то должно вылезать.

Свисток, как видим, работоспособный, провода проверили, полагаю, несколько раз. Значит на стороне контролины фигня. DE/RE проверяйте - действительно ли на тех ли пинах, которыми вы в скетче манипулируете.

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Залил в контроллино пример слейва который должен быть рабочим, который предлагает производитель, запустил ModbusLook, ModbusLook пишет что нет связи... 

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

 

написано тут...

в библиотеке так...

#define RS485_PIN_DE      0b01000000
#define RS485_PIN_RE      0b00100000
#define RS485_DIR_REG     DDRJ
#define RS485_PORT_REG    PORTJ
#define RS485_CLEAR_DE    RS485_PORT_REG &= ~RS485_PIN_DE
#define RS485_CLEAR_RE    RS485_PORT_REG &= ~RS485_PIN_RE
#define RS485_SET_DE      RS485_PORT_REG |= RS485_PIN_DE
#define RS485_SET_RE      RS485_PORT_REG |= RS485_PIN_RE

 

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

Без железяки сложно разобраться. Она может быть нескольких ревизий, где соединено всё по-разному.

Вот я вижу в https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library/blob/master/Controllino.h

#define CONTROLLINO_RS485_DE 75
#define CONTROLLINO_RS485_nRE 76

Т.е. какбутто DE/RE на 75/76 ноге чипа висят. Ведь у платы Arduino Mega2560 нет 75 и 76 пина. Но при этом, в камменте читаем: Set of macros mapping CONTROLLINO aliases to Arduino pin numbers.

Вобщем, расследование проводить нужно по полной программе.

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Связался с представителем, возможно они прояснят...вроде ребята отзывчивые...

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

Видимо, DE/RE (по вашей схеме висят) на PJ5/PJ6. У Ардуино IDE, похоже, прямого выхода нет на эти пины - я на картинках пиноута меги не вижу эти PJ. То есть остаётся попробовать прямую манипуляцию через DDRJ/PORTJ.

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

В спешке в примере для слейва не изменил скорость...

#include <Controllino.h>  /* Usage of CONTROLLINO library allows you to use CONTROLLINO_xx aliases in your sketch. */
#include "ModbusRtu.h"    /* Usage of ModBusRtu library allows you to implement the Modbus RTU protocol in your sketch. */
/*
   CONTROLLINO - Modbus RTU protocol Slave example for MAXI and MEGA, Version 01.00
   
   The sketch is relevant only for CONTROLLINO variants MAXI and MEGA (because of necessity of RS485 interface)!

   This sketch is intended as an example of the communication between devices via RS485 with utilization the ModbusRTU protocol.
   In this example the CONTROLLINO  is used as the Modbus slave!
   For more information about the Modbus protocol visit the website: http://modbus.org/
   
   Modbus master device can read Modbus 16bit registers (provided by the slave):
    0 - analog CONTROLLINO_A0 value (0 - 1024)
    1 - digital CONTROLLINO_D0 value (0/1)
    2 - Modbus messages received
    3 - Modbus messages transmitted

   Modbus master device can write Modbus 16bit registers:
    4 - relay CONTROLLINO_R0 (0/1)
    5 - relay CONTROLLINO_R1 (0/1)
    6 - relay CONTROLLINO_R2 (0/1)
    7 - relay CONTROLLINO_R3 (0/1)

   To easily evaluate this example you need a second CONTROLLINO as Modbus master running DemoModbusRTUMaster example sketch.
   Please note that both CONTROLLINOs need 12/24V external supply and you need to interconnect GND, -, + signals of RS485 screw terminal.

   Modbus Master-Slave library for Arduino (ModbusRtu.h) was taken from the website: https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino
   It was necessary to modify setting of the PORTJ for pins DE and RE control. These pins are located at the PORJ and on the pins PIN6(DE) and PIN5(RE).

  IMPORTANT INFORMATION!
  Please, select proper target board in Tools->Board->Controllino MAXI/MEGA before Upload to your CONTROLLINO.
  (Please, refer to https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library if you do not see the CONTROLLINOs in the Arduino IDE menu Tools->Board.)

  Created 30 March 2017
  by David

  https://controllino.biz/

  (Check https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library for the latest CONTROLLINO related software stuff.)
*/

// This MACRO defines Modbus slave address.
// For any Modbus slave devices are reserved addresses in the range from 1 to 247.
// Important note only address 0 is reserved for a Modbus master device!
#define SlaveModbusAdd  1

// This MACRO defines number of the comport that is used for RS 485 interface.
// For MAXI and MEGA RS485 is reserved UART Serial3.
#define RS485Serial     3

// The object ControllinoModbuSlave of the class Modbus is initialized with three parameters.
// The first parametr specifies the address of the Modbus slave device.
// The second parameter specifies type of the interface used for communication between devices - in this sketch is used RS485.
// The third parameter can be any number. During the initialization of the object this parameter has no effect.
Modbus ControllinoModbusSlave(SlaveModbusAdd, RS485Serial, 0);

// This uint16 array specified internal registers in the Modbus slave device.
// Each Modbus device has particular internal registers that are available for the Modbus master.
// In this example sketch internal registers are defined as follows:
// (ModbusSlaveRegisters 0 - 3 read only and ModbusSlaveRegisters 4 - 7 write only from the Master perspective):
// ModbusSlaveRegisters[0] - Read an analog value from the CONTROLLINO_A0 - returns value in the range from 0 to 1023.
// ModbusSlaveRegisters[1] - Read an digital value from the CONTROLLINO_D0 - returns only the value 0 or 1.
// ModbusSlaveRegisters[2] - Read the number of incoming messages - Communication diagnostic.
// ModbusSlaveRegisters[3] - Read the number of number of outcoming messages - Communication diagnostic.
// ModbusSlaveRegisters[4] - Sets the Relay output CONTROLLINO_R0 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[5] - Sets the Relay output CONTROLLINO_R1 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[6] - Sets the Relay output CONTROLLINO_R2 - only the value 0 or 1 is accepted.
// ModbusSlaveRegisters[7] - Sets the Relay output CONTROLLINO_R3 - only the value 0 or 1 is accepted.
uint16_t ModbusSlaveRegisters[8];

// The setup function runs once when you press reset (CONTROLLINO RST button) or connect the CONTROLLINO to the PC
// In the setup function is carried out port setting and initialization of communication of the Modbus slave protocol.
void setup()
{
    pinMode(CONTROLLINO_R0, OUTPUT);    // Set the pin CONTROLLINO_R0 as output.
    pinMode(CONTROLLINO_R1, OUTPUT);    // Set the pin CONTROLLINO_R1 as output.
    pinMode(CONTROLLINO_R2, OUTPUT);    // Set the pin CONTROLLINO_R2 as output.
    pinMode(CONTROLLINO_R3, OUTPUT);    // Set the pin CONTROLLINO_R3 as output.

    pinMode(CONTROLLINO_D0, INPUT);     // Set the pin CONTROLLINO_D0 as input - Read digital value at the pin D0.
    pinMode(CONTROLLINO_A0, INPUT);     // Set the pin CONTROLLINO_A0 as input - Read analog value at the pin A0

    ControllinoModbusSlave.begin( 9600 );  // Start the communication over the ModbusRTU protocol. Baund rate is set at 19200.
}

// The loop function runs over and over again forever
void loop()
{
    // This instance of the class Modbus checks if there are any incoming data.
    // If any frame was received. This instance checks if a received frame is Ok.
    // If the received frame is Ok the instance poll writes or reads corresponding values to the internal registers (ModbusSlaveRegisters).
    // Main parameters of the instance poll are address of the internal registers and number of internal registers.
    ControllinoModbusSlave.poll(ModbusSlaveRegisters, 8);

    // While are not received or sent any data, the Modbus slave device periodically reads the values of analog and digital outputs.
    // Also it updates the other values of registers.
    ModbusSlaveRegisters[0] = analogRead(CONTROLLINO_A0);           // Read the analog input CONTROLLINO_A0.
    ModbusSlaveRegisters[1] = digitalRead(CONTROLLINO_D0);          // Read the digital input CONTROLLINO_A0.
    ModbusSlaveRegisters[2] = ControllinoModbusSlave.getInCnt();    // Read the number of incoming messages.
    ModbusSlaveRegisters[3] = ControllinoModbusSlave.getOutCnt();   // Read the number of outcoming messages

    digitalWrite(CONTROLLINO_R0, ModbusSlaveRegisters[4]); // Update the relay output CONTROLLINO_R0 - ON/OFF
    digitalWrite(CONTROLLINO_R1, ModbusSlaveRegisters[5]); // Update the relay output CONTROLLINO_R1 - ON/OFF
    digitalWrite(CONTROLLINO_R2, ModbusSlaveRegisters[6]); // Update the relay output CONTROLLINO_R2 - ON/OFF
    digitalWrite(CONTROLLINO_R3, ModbusSlaveRegisters[7]); // Update the relay output CONTROLLINO_R3 - ON/OFF
}

/* End of the example. Visit us at https://controllino.biz/ or contact us at info@controllino.biz if you have any questions or troubles. */

/* 2017-03-31: The sketch was successfully tested with Arduino 1.8.1, Controllino Library 1.1.0 and CONTROLLINO MAXI and MEGA. */

с этим примером 

Значит где то в коде напортачил...

nik182
Offline
Зарегистрирован: 04.05.2015

Третий элемент в инициализации это нога re de. Эти ноги надо соединить и соединить с ногой платы, которая прописана в инициализации. Для 485 ноль не может быть. У Вас ноль.

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

Тут не получится соединить, в том то и вопрос какие пины нужно прописать...этот пример рекомендует производитель...

тут он приводит пример

// The object ControllinoModbuSlave of the class Modbus is initialized with three parameters.
// The first parametr specifies the address of the Modbus slave device.
// The second parameter specifies type of the interface used for communication between devices - in this sketch - RS485.
// The third parameter can be any number. During the initialization of the object this parameter has no effect.
Modbus ControllinoModbusMaster(MasterModbusAdd, RS485Serial, 0);

пишет что третий параметр ни на что не влияет 

nik182
Offline
Зарегистрирован: 04.05.2015

Ну тогда считайте, что мой комментарий к посту #11. С контролино дел не имел. Modbusrtu работает без проблем

knack
knack аватар
Offline
Зарегистрирован: 27.03.2012

В Controllino.h есть функции:

CONTROLLINO_RS485_RX
CONTROLLINO_RS485_DE

Причём у них же в примере:

 pinMode(CONTROLLINO_RS485_RX, INPUT);
 pinMode(CONTROLLINO_RS485_RE, OUTPUT);
 pinMode(CONTROLLINO_RS485_DE, OUTPUT);*/

Вот только функции 

CONTROLLINO_RS485_RE

нету, если поковырять библиотеку есть 

 pinMode(CONTROLLINO_RS485_nRE, OUTPUT);

и за что отвечает CONTROLLINO_RS485_RX ???