Нужна помощь, ардуино-rs485-modbus-slave - PLC OWEN

Oleg_balt
Offline
Зарегистрирован: 07.06.2015

Помогите мне знающие люди, не могу связать в сеть контроллер овен по сети 485 и протоколу модбас рту

в сети есть примеры работы с контроллерами других фирм (например https://www.youtube.com/watch?v=Nzi0NBb9ZVE)

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

Подскажите примерами хотябы похожими, буду пытаться разобраться.

Спасибо.  

Sander224
Offline
Зарегистрирован: 01.04.2015

Добрый день! Предлагаю объединть усилия. Только у меня своя задача стоит. Необходимо сделать ардуину мастером сети и по RS485 опрашивать модуль ввода температур, и в соответствии и уставками , блокировками и пр, управлять твердотельным реле. Цены на ПЛК что то ооочень закусались. Вот и приходиться искать альтернативные пути.

Oleg_balt
Offline
Зарегистрирован: 07.06.2015

Я уже много примеров поробовал и изменял их все ровно нет связи, не знаю как еще сделать. вот пример отсюда http://forum.arduino.cc/index.php?topic=291648.0 

вот еще пример http://www.biemmeitalia.net/blog/android-touchscreen-communicates-with-arduino-using-modbus-rs485/

Sander224
Offline
Зарегистрирован: 01.04.2015

в понедельник забираю преобразователь на плате мах485. судя по примерам смысл ясен. Вопрос в библиотеках.

Оказывается ПЛК в codesys гораздо проще программируется :)

 

Oleg_balt
Offline
Зарегистрирован: 07.06.2015

Sander224 пишет:

в понедельник забираю преобразователь на плате мах485. судя по примерам смысл ясен. Вопрос в библиотеках.

Оказывается ПЛК в codesys гораздо проще программируется :)

 

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

Sander224
Offline
Зарегистрирован: 01.04.2015

подвяжем! это такой же контроллер.

Oleg_balt
Offline
Зарегистрирован: 07.06.2015

Вот программа которая у меня заработала в связке с ПЛК теперь осталось реализовать вход и выход.Я не могу в регистрах протокола разобраться ((

#include "ModbusRtu.h"
Modbus slave(1, 0, 2);
int8_t state = 0;
unsigned long tempus;
uint16_t au16data[11];
void setup()
{slave.begin( 9600 )}
void loop() {
state = slave.poll( au16data, 11); 
  if (state > 4) {
    tempus = millis() + 50;
    digitalWrite(13, HIGH);
  }
  if (millis() > tempus) digitalWrite(13, LOW );
}

Oleg_balt
Offline
Зарегистрирован: 07.06.2015

Я пользовался этой статьей и брал от сюда библиотеку, это если кому интересно.

http://habrahabr.ru/post/249043/

но я так и не разобрался и работает у меня все криво 

Oleg_balt
Offline
Зарегистрирован: 07.06.2015

Всем спасибо разобрался.

Sander224
Offline
Зарегистрирован: 01.04.2015

Предлагаю озвучить бесценный труд :)

Oleg_balt
Offline
Зарегистрирован: 07.06.2015

Что именно? я все ссылки дал я тупо брал чужие примеры так как сам не разбираюсь. 

alexval2007
Offline
Зарегистрирован: 10.11.2012

Если еще есть интерес мы с моим товарищем осилили эту проблему и Modbus TCP и Modbus RTU для Modbus RTU работает как мастер так и слейв с контролерами и модулями овен пробовал плк 100, плк110, спк107 и модуль мх110-16дн

Sander224
Offline
Зарегистрирован: 01.04.2015

Уважаемый alexval2007! Если не затруднит, можете просветить по этому вопросу! Буду очень признателен!

alexval2007
Offline
Зарегистрирован: 10.11.2012

хорошо я на днях ближе к выходным подготовлю материал чтобы он был более менее читаем и выложу сами понимаете все как попало творческий хаус кстати на тему овена есть у меня эксперементы удачные с установкой codesys с веб визуализацией на Rasproberry Pi все работает прикольно

Sander224
Offline
Зарегистрирован: 01.04.2015

Думаю мы сможем быть полезны друг другу :) Заранее спасибо!

Evg-Chugunov
Evg-Chugunov аватар
Offline
Зарегистрирован: 22.08.2015

Тоже интересно. Подписался на тему.

gonzales
Offline
Зарегистрирован: 13.07.2015

тоже с удовольствием посмотрел бы. на даче стоит ПЛК-63, хочу его с ардуинкой подружить

alexval2007
Offline
Зарегистрирован: 10.11.2012
Dr_grizzly
Dr_grizzly аватар
Offline
Зарегистрирован: 07.12.2015
#include <ModbusRtu.h>

// data array for modbus network sharing
uint16_t au16data[16];
uint8_t u8state;
int8_t state = 0;
int ledpin=13;
int Val;

/**
 *  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,1,3); // 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; 
  pinMode(ledpin,OUTPUT);
  au16data[0] = 1;
}

void loop() {
  switch( u8state ) {
  case 0: 
    if (millis() > u32wait) u8state++; // wait state
    break;
  case 1: 
    telegram.u8id = 4; // slave address
    telegram.u8fct = 4; // function code (this one is registers read)
    telegram.u16RegAdd = 1018; // start address in slave
    telegram.u16CoilsNo = 1; // 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)
    digitalWrite(ledpin,HIGH);
    delay(1000);
    u8state++;
    break;
  case 2:
   state= master.poll(); // check incoming messages
   digitalWrite(ledpin,LOW);
   Serial.println(state, HEX);
    
    if (master.getState() == COM_IDLE) {
      u8state = 0;
      u32wait = millis() + 100; 
    }
    delay(1000);
    break;
  }
}

Люди добрые! Помогите разобраться... Хочу отправить пакет в виде 040403FA0001, светодиод моргает на ардуине, т.е цикл выполняется, но ничего не вижу, ни отправлено пакета, ни полученного ответа... Как ловить данные которы присылает устройство? Подключено Autonics TM4. Использую RS485 для коммутации. На Serial1 сидит RS485, а Serial - комп. Так же в сети подключена Овен AC4, чтобы мониторить что ходит по сети...

 

#include <ModbusRtu.h>

// data array for modbus network sharing
int TransmitModePin=3;
byte bf=B0100;
byte bf1=B0100;

Modbus master(0,1,3); // this is master and RS-232 or USB-FTDI

/**
 * This is an structe which contains a query to an slave device
 */
void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
  pinMode(TransmitModePin,OUTPUT);
  
}

void loop() {
Serial.write(bf);
digitalWrite(TransmitModePin, HIGH);
Serial1.write(bf);
delay(1000);
digitalWrite(TransmitModePin, LOW);
delay(1000);
}

Вот этот код отправляет в сеть пакет... т.е. я все вижу и на компе и на ас4... а вот с модбас чет не выходит...

alexval2007
Offline
Зарегистрирован: 10.11.2012

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

Dr_grizzly пишет:

#include <ModbusRtu.h>


// data array for modbus network sharing
int TransmitModePin=3;
byte bf=B0100;
byte bf1=B0100;

Modbus master(0,1,3); // this is master and RS-232 or USB-FTDI

/**
 * This is an structe which contains a query to an slave device
 */
void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
  pinMode(TransmitModePin,OUTPUT);
  
}

void loop() {
Serial.write(bf);
digitalWrite(TransmitModePin, HIGH);
Serial1.write(bf);
delay(1000);
digitalWrite(TransmitModePin, LOW);
delay(1000);
}

Вот этот код отправляет в сеть пакет... т.е. я все вижу и на компе и на ас4... а вот с модбас чет не выходит...

Dr_grizzly
Dr_grizzly аватар
Offline
Зарегистрирован: 07.12.2015

Спасибо что откликнулись! Честно говоря, я разные библиотеки подключал, и в том числе предложенную вами, но не совсем понимаю в каком месте происходит обработка принятных ответов от slave устройств... Вот пример из вашего кода:

#include <SimpleModbusMaster.h>
//////////////////// Port information ///////////////////
#define baud        9600
#define timeout     1000
#define polling     200 // скорость опроса по модбус
#define retry_count 10
#define TxEnablePin 2   // Tx/Rx пин RS485
#define LED1        9   // светодиод 1
#define LED2        13  // светодиод 2
//Общая сумма доступной памяти на ведущем устройстве, чтобы хранить данные
#define TOTAL_NO_OF_REGISTERS 4

// This is the easiest way to create new packets
// Add as many as you want. TOTAL_NO_OF_PACKETS
// is automatically updated.
enum
{
  PACKET1,
  PACKET2,
  PACKET3,
  PACKET4,
  TOTAL_NO_OF_PACKETS // leave this last entry
};

// Масив пакетов модбус
Packet packets[TOTAL_NO_OF_PACKETS];

// Массив хранения содержимого принятых и передающихся регистров
unsigned int regs[TOTAL_NO_OF_REGISTERS];

void setup()
{
  // Настраиваем пакеты
  // Шестой параметр - это индекс ячейки в массиве, размещенном в памяти ведущего устройства, в которую будет 
  // помещен результат или из которой будут браться данные для передачи в подчиненное устройство. В нашем коде - это массив reg
  // Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
  modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS,    0, 1, 0);
  modbus_construct(&packets[PACKET2], 1, READ_HOLDING_REGISTERS,    1, 1, 0);
  // Пакет,SLAVE адрес,функция модбус,адрес регистра,данные,локальный адрес регистра.
  modbus_construct(&packets[PACKET3], 1, PRESET_MULTIPLE_REGISTERS, 2, 1, 0); 
  modbus_construct(&packets[PACKET4], 1, PRESET_MULTIPLE_REGISTERS, 3, 1, 0);
  
  // инициализируем протокол модбус
  modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);
  
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
}

void loop()
{
  modbus_update();
  unsigned int temp1;
  unsigned int temp2;
  //regs[0] = analogRead(0);       // запись данных master-slave
  //analogWrite(LED, regs[0]>>2);  // чтение данных slave-master (ограничеть количесво бит данных числом 255)
  regs[0] = 255;   // запись данных master-slave (slave адрес 1, регистр 1)
  regs[1] = 255;   // запись данных master-slave (slave адрес 1, регистр 2) 
  temp1 = regs[2]; // чтение данных slave-master (slave адрес 1, регистр 3)  
  temp2 = regs[3]; // чтение данных slave-master (slave адрес 1, регистр 4) 
   if (temp1 == 255){digitalWrite(LED1, HIGH);}else{digitalWrite(LED1, LOW);}//если пришло 255 зажигаем светодиод
   if (temp2 == 255){digitalWrite(LED2, HIGH);}else{digitalWrite(LED2, LOW);}
}

Как я понимаю вот здесь "modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs" - происходит инициализация, если я использую RX1 и TX1 на ардуино Мега, то указываю &Serial1, верно? Так же исправляю параметр TxEnablePin на ногу где соединены DE и RE ноги RX485,  больше в инициализации ничего не меняю?

Теперь собственно пакет разобрать хочется. Мне нужно отправить пакет в виде "04 04 03FA 0001" где функция 04 соответствует READ_INPUT_REGISTERS, а вот что дальше не совсем понято... "адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра" - адрес регистра у меня = 03FA, количество запрашиваемых регистров = 0001, а вот что значит "локальный адрес регистра" не понимаю...

"modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0);" формируется пакет для отправки.

А вот ответ который я ожидаю должен прийти в таком виде "04 04 02 015F" где 04 - адрес, 04 - функция, 02 кол-во байт, 015F - значение датчика температуры (в DEC = 351 или 35,1 градуса цельсия). 

В каком месте кода и каким образом я могу прочитать полученный ответ от устройства подскажите пожалуйста? Заранее благодарен!

 

alexval2007
Offline
Зарегистрирован: 10.11.2012

 если я использую RX1 и TX1 на ардуино Мега, то указываю &Serial1, верно?   ДА

Так же исправляю параметр TxEnablePin на ногу где соединены DE и RE ноги RX485, ДА

Serial, baud, СКОРОСТЬ ОБМЕНА ВЫСТАВИТЬ ВАШУ

SERIAL_8N1 ЭТО ФОРМАТ ДАНЫХ 8 БИТ БЕЗ КОНТРОЛЯ ЧЁТНОСТИ 1 СТОП БИТ
 
// Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
37   modbus_construct(&packets[PACKET1], 4, READ_INPUT_REGISTERS,    1018, 1, 0);

 ТУТ ЧТЕНИЕ ПО 4Й ФУНКЦИИ АДРЕС ОПРАШИВАЕМОГО СЛЕЙВА 4, РЕГИСТР 1018, КОЛИЧЕСТВО РЕГИСТРОВ 1 ОН 16БИТНЫЙ НАСКОЛЬКО Я ПОМНЮ 2 БАЙТА ВХОДЯТ ТУДА, ЛОКАЛЬНЫЙ АДРЕС РЕГИСТРА ОСТАВИМ НУЛЕВЫМ ЭТО АДРЕС РЕГИСТРА В ПАМЯТИ ВАШЕГО АРДУИНО ГДЕ БУЕТ ХРАНИТСЯ ПОЛУЧЕНОЕ И ВАШЕГО ПРИБОРА ПО МОДБУС

ВОТ ТУТ ЗАБИРЁМ ПОЛУЧЕННЫЕ ОТ ВАШЕГО ПРИБОРА ДАННЫЕ ИЗ НУЛЕВОГО ЛОКАЛЬНОГО РЕГИСТРА ТАК КАК МЫ ТУДА ЕГО СОХРАНЯЛИ 

temp1 = regs[0]; // чтение данных slave-master (slave адрес 4, регистр 1018) 

38   modbus_construct(&packets[PACKET1], 4, READ_HOLDING_REGISTERS,    1018, 1, 0);

ТУТ ЧТЕНИЕ ПО 3Й ФУНКЦИИ 

Dr_grizzly
Dr_grizzly аватар
Offline
Зарегистрирован: 07.12.2015

Отлично, вроде все по коду рабочее, но на деле - в регистре regs[0] остается постоянный 0... как будто ничего не приходит от slave

Dr_grizzly
Dr_grizzly аватар
Offline
Зарегистрирован: 07.12.2015

Куда теперь нужно поглядеть? ))) на этих же проводах еще висит Овен АС4 и подключен к компу. У ардуино сом5 у овна сом3. Запущена программа мониторинга данных на сом портах, и пакетов отправки нет... А еще интересный момент - решил установить паузу в коде программы и мультиметром замерить напряжение на управляемой ноге DE и RE. Там 0.4вольта и не дергается даж...

Dr_grizzly
Dr_grizzly аватар
Offline
Зарегистрирован: 07.12.2015

Нашел проблему! Я при монтажных работах использую брэд, у него есть две шины питания, на них я питание подал с ардуинки, а с шинки на rs485 не взял ))))) 4 дня мозг выносил себе и вам!))))

При чем когда работал как мастер - на rs485 горел светодиод, поэтому подозрений то не вызывал. А когда решил попробовать slave библиотеку, то он потух, и тут стал вопрос в чем дело )) Так и нашел проблему )

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

всем привет!

решил не начинать новую тему а в этой задать вопрос!

Пришли модули на базе чипа макс решил попробовать, подключил сперва 2 ардуинки по сериалу, все работает.., установил модули вроди как рабоотает но выдает не то что нужно а точнее мусор

вот 2 скетча мега это мастер а уно это слейв.

мега

 
void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  Serial1.begin(9600);
  delay(300);
  Serial.println("Goodnight mega!");
   pinMode(2, OUTPUT); 
}
void loop() { // run over and over
  if (Serial1.available()) {
    Serial.write(Serial1.read());
  }
  if (Serial.available()) {
  Serial1.write(Serial.read());
  digitalWrite(2, HIGH);
  delay(10);
  }
}

уно 

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
 
void setup() {
  Serial.begin(9600);
  Serial.println("Goodnight uno!");
  mySerial.begin(9600);
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
  delay(10);
}

void loop() {
  if (mySerial.available()) { 
    Serial.write(mySerial.read());
  }
  
  if (Serial.available()) {
   mySerial.write(Serial.read());
  }
}

вот что выдает...

отправляю 1 получаю g=

отправляю 2 получаю 3=

отправляю 3 получаю f=

в чем может быть подвох? кто знает отзавитель пож....

 

kasper007
Offline
Зарегистрирован: 23.05.2016

Похоже такая же ситуация как и та, с которой я на днях столкнулся. Заказал на ali переходник USB-RS485 (для ПК) и преобразователь уровней Arduino TTL-RS485 (для Arduino). Вроде что-то передается, но не то. Промучился два дня. Затем убрал одну из линий (RX или TX) и увидел, что на результат это не повлияло. Закрадывается впечталение, что неисправен один из модулей. Сейчас закажу новую пару преобразователей уровней. Они копеечные, жаль только времени, которое тратится на доставку. Из-за этого простой в проекте.

http://arduino.ru/forum/apparatnye-voprosy/podklyuchenie-konvertera-rs-4...

Кстати при отправке 1 у меня помоему тоже g получалось получить.

Dr_grizzly
Dr_grizzly аватар
Offline
Зарегистрирован: 07.12.2015

ПОдскажите, а что вы пытаетесь сделать? чип макс485 соответствует протоколу Modbus. Кодировка передачи данных - в hex системе исчисления. При инициализации протокола вы должны указать уникальные адреса для устройств в пределах 127. ПРи отправке пакета в первый байт записываем адрес нашего устройства, которому хотим что-то передать. Затем команду запись 06h, затем адрес регистра в который хотим сделать запись, например 00h 01h  затем - то что хотим, число или код символа. Следовательно на втором устройстве должен быть регистр 0001, в который устройство будет ожидать прием данных. Суть как-то так ))

 

Я реализовал код по передачи команд по modbus ардуино, а ардуино, выбрав нужную команду - отправила устройству(например частотнику) и получила от него ответ. С компа мы можем прочитать этот ответ записанный уже в нашем ардуино

kasper007
Offline
Зарегистрирован: 23.05.2016

Dr_grizzly,

ну немножко неверно связывать физическое преобразование уровней и протокол Modbus. Приведя свой сигнал от уровней TTL arduino к уровням RS485 я могу передавать любую информацию по любому протоколу (одни из которых является Modbus, особенностю которого является возможность адресации устройств). Мне ничего подобного делать не нужно было. Мне от компьютера нужно передать один пакет в 5 байт в ардуино (на текущий момент). Зачем мне к этому привязывать какой-то протокол?

Поэтому я в лоб из терминальной программы отправляю посылку (упростил до передачи одного байта), читаю его ардуиной и транслирую этот же байт обратно в терминальную программу.  В данном случае не вижу никакой программной разницы с отправкой через обычный USB кабель (в этом варианте все прекрасно работает). Разница лишь в физической реализации.

Но особенность в том, что в конечном итоге мне нужно будет передать эту информация на 30-70 метров. А USB кабелей такого размера не делают :). А благодаря стандарту RS485 я смогу без всяких сложностей передать информацию на такое расстояние.

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

может попробовать каждый символ в некст переводить потом передавать и потом обратно из некста в символ?

Dr_grizzly
Dr_grizzly аватар
Offline
Зарегистрирован: 07.12.2015

воот )) я про это хотел сказать )) что все таки эта система будет жевать hex данные )))

jtahun
Offline
Зарегистрирован: 20.04.2017

Здравствуйте товарищи! Вопрос все о том же... Связь  аналогового модуля ОВЕН с ардуиной-мастер.

Задача - в браузере наблюдать измеренное значение. 

Использую: ардуино Уно, преобразователь RS485, ethernet модуль(enc28j60), ну и собственно Овен МВ110-2АС.

для опроса Овен на ардуине подключаю SimpleModbusMaster.h

В общем-то успех есть, но с оговорками. Возникают 2-е проблемы:

Измеренные значения не изменяются, даже если отсоединить сигнал от канала ОВЕН.

И инициализирутся только один Пакет, т.е. одним пакетом могу опросить 2 канала, а опросить каждый канал отдельным пакетом нет.

При опросе использовал и 3-ю, и 4-ю функции Modbus. Измеренные значения хранятся 0х100 - 1 канал, 0х101 - 2 канал. 

#include <SimpleModbusMaster.h>
#include <EtherCard.h>

static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
static byte myip[] = { 192,168,1,203 };

byte Ethernet::buffer[500];
BufferFiller bfill;


//////////////////// Макроопределения портов и настройки программы  ///////////////////
#define baud        9600 // скоростьобмена по последовательному интерфейсу. (UART)
#define timeout     1000 // Длительность ожидание ответа (таймаут modbus)
#define polling     200  // скорость опроса по modbus
#define retry_count 10   // количесво запросов modbus до ошибки и останова обмена 
#define TxEnablePin 2    // Tx/Rx пин RS485
#define LED1        9    // светодиод 1
#define LED2        13   // светодиод 2

// Общая сумма доступной памяти на master устройстве, для хранения данных
// не забудьте изменить макроопределение TOTAL_NO_OF_REGISTERS. Если из слейва 
// запрашиваешь 4 регистра, то тогда в массиве reg должно быть не меньше 4х ячеек 
// для хранения полученных данных.
#define TOTAL_NO_OF_REGISTERS 6

// Масив пакетов modbus
// Для добавления новых пакетов просто добавте ихсюда
// сколько вам нужно.
int ch1,ch2;
enum
{
  PACKET1,
  PACKET2,
  PACKET3,
  PACKET4,
  TOTAL_NO_OF_PACKETS // эту строку неменять
};

// Масив пакетов модбус
Packet packets[TOTAL_NO_OF_PACKETS];

// Массив хранения содержимого принятых и передающихся регистров
unsigned int regs[TOTAL_NO_OF_REGISTERS];

 static word homePage() {
  
  bfill = ether.tcpOffset();
  bfill.emit_p(PSTR(
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
    "\r\n"
    "<meta http-equiv='refresh' content='1'/>"
    "<title>ModBus Master</title>" 
    "<h1>$D::$D</h1>"),
      regs[0],regs[1]);
  return bfill.position();
}

void setup()
{  
  Serial.begin(9600);
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println(F("Failed to access Ethernet controller"));
  ether.staticSetup(myip);
  
 // Настраиваем пакеты
 // Шестой параметр - это индекс ячейки в массиве, размещенном в памяти ведущего устройства, в которую будет 
 // помещен результат или из которой будут браться данные для передачи в подчиненное устройство. В нашем коде - это массив reg
  
 // Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
 modbus_construct(&packets[PACKET1], 16, READ_INPUT_REGISTERS, 256, 2, 0); // (slave адрес 16, регистр 0x100) 
//modbus_construct(&packets[PACKET2],16, READ_HOLDING_REGISTERS, 257, 1, 2); // (slave адрес 16, регистр 0x101)
  
 // инициализируем протокол модбус
 modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);
  
 pinMode(LED1, OUTPUT);
 pinMode(LED2, OUTPUT);
} // конец void setup()

//onwVersion of loop()
void loop()
{
  modbus_update();   
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if (pos)  // check if valid tcp data is received
    ether.httpServerReply(homePage()); // send web page data
    //ch1=regs[0];
    //ch2=regs[1];
     Serial.print(" ");
     Serial.print(regs[0],DEC);
     Serial.print(" ");
     Serial.print(regs[1],DEC);
     Serial.print(" ");
     /*Serial.print(regs[2],HEX);
     Serial.print(" ");
     Serial.print(regs[3],HEX);  */
     Serial.print("\n"); 
     //delay(10);
 
}

Dr_grizzly
Dr_grizzly аватар
Offline
Зарегистрирован: 07.12.2015

Вот эту конструкцию нужно не в setup а в loop и желательно по таймеру, чтобы не сплошняком валила. Тогда данные будут обновлятся. Такой же конструкцией можно опрашивать каждый регистр который нас интересует. Просто его надо конфигурировать в loop цикле перед каждым запросом.  P.S. я посчитал что эта библиотека не слишком гибкая, и использую другую. см.выше.

modbus_construct(&packets[PACKET1], 16, READ_INPUT_REGISTERS, 256, 2, 0);

monser
Offline
Зарегистрирован: 01.07.2017

У меня такая задача: Имеются несколько (8) датчиков температуры и давления подключенных к ТРМ202 (4). ТРМ в свою очередь подключены к компу по RS485 через ОВЕНовский преобразователь АС4 . На компе у дежурного в программе SimpLight отображаются эти данные. Нужно подключив ардуино через свой преобразователь RS485 к линии прослушивать данные поступающие на комп и далее по СМС  запросу через Neoway M590 (https://istarik.ru/blog/arduino/68.html)  отсылать эти данные на номер от которого пришла СМС. Есть ли у кого наработки на данную тему прошу помочь.

 

 

Duet
Offline
Зарегистрирован: 17.01.2015

Как обычно черт ногу сломит в этих библиотеках. Какая библиотека Modbus Slave актуальней на сегодняшний день? Мне для связи с Mach3. Библиотек много, но мне как новичку, лучше разбирать библиотеку по проще, самую используемую и с документацией.

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

Кто ж его знает. Ни разу не видел рейтинга библиотек. Устрой опрос. А так они все одинаково работают - выполняют что надо. Бери любую. Лучшая та, которую знаешь.

Pyotr
Offline
Зарегистрирован: 12.03.2014

Duet пишет:

Как обычно черт ногу сломит в этих библиотеках. Какая библиотека Modbus Slave актуальней на сегодняшний день? Мне для связи с Mach3. Библиотек много, но мне как новичку, лучше разбирать библиотеку по проще, самую используемую и с документацией.

Я эту использую.

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

Опять же вопрос для чего и как она будет использоваться. Если только опрос то библиотека не нужна вовсе.

Вот такой вариант реализовывал.

Правда modbusTCP, клиент отдает по запросу состояние регистра.

#include <ESP8266WiFi.h>

#define maxHoldingRegister 20
 
byte arr[260];
unsigned int MBHoldingRegister[maxHoldingRegister];
 
//////////////////////////////////////////////////////////////////////////
 
WiFiServer MBServer(ModbusTCP_port);
 
void setup() {
 
  Serial.begin(9600);
  delay(100);
  WiFi.begin(ssid, password);
  delay(100);
  Serial.println(".");
 
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
 
  MBServer.begin();
  Serial.println("Connected ");
  Serial.print("ESP8266 Slave Modbus TCP/IP ");
  Serial.print(WiFi.localIP()); Serial.print(":"); Serial.println(String(ModbusTCP_port));
  Serial.println("Modbus TCP/IP Online");
}
 
 
void loop() {
  // Check if a client has connected // Modbus TCP/IP
  WiFiClient client = MBServer.available();
  if (!client) { return; }
 
  boolean flagClientConnected = 0;
  byte byteFN=0;
  int Start;
  int WordDataLength;
  int ByteDataLength;
  int MessageLength;
 
  // Modbus TCP/IP
  while (client.connected()) {
    if(client.available()) {
      flagClientConnected = 1;
      int i = 0;
      while(client.available()) {
        arr[i] = client.read();
        i++;
      }
      client.flush();
  
      //// routine Modbus TCP
      byteFN = arr[7];
      Start = word(arr[8],arr[9]);
      WordDataLength = word(arr[10],arr[11]);
    }
 
    // Handle request
    switch(byteFN) {
 
      case 0:
        break;
 
      case 3:
        ByteDataLength = WordDataLength * 2;
        arr[5] = ByteDataLength + 3; //Number of bytes after this one.
        arr[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data).
        for(int i = 0; i < WordDataLength; i++) {
          arr[ 9 + i * 2] = highByte(MBHoldingRegister[Start + i]);
          arr[10 + i * 2] = lowByte(MBHoldingRegister[Start + i]);
        }
        MessageLength = ByteDataLength + 9;
        client.write((const uint8_t *)arr,MessageLength);
        byteFN=0;
        break;
  
      case 6:
      byteFN=0;
        break;
 
      case 16: 
      byteFN=0;
        break;
    }
  }
}

 

 

Duet
Offline
Зарегистрирован: 17.01.2015

.

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

А что не понятно? Ответ пришёл. Теперь по мануалу надо его расшифровать. В мануале написано в каких ячейках что лежит. Так что там в мануале про адреса 45000 и далее написано?

Duet
Offline
Зарегистрирован: 17.01.2015

.

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

Я вот не понял, что нужно от программы. Что она должна делать и как. Например по полученному ответу видно, что что то имете значение +0.91 . Что с этим надо сделать?

Duet
Offline
Зарегистрирован: 17.01.2015

.

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

Это ж простая математика. Берём переменную float. Eй присваиваем значение из регистра 45000, прибавляем значение из регистра 45001 делённое на 10000 и ставим знак из регистра 45002. И выводим переменную на экран.

Duet
Offline
Зарегистрирован: 17.01.2015

.

nik182
Offline
Зарегистрирован: 04.05.2015
float f= au16data[0]+(float)au16data[1]*0.0001;
if (!au16data[2]) f=-f;

 

Duet
Offline
Зарегистрирован: 17.01.2015

.

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

Вот я опять не понимаю, что надо сделать. Кто мастер? Какие значения надо считать? Откуда? Слейв не может считать. В него можно только записать. В библиотеке есть описание, что такое state для pool. Пока он не примет значение принято читать регистры бесполезно - нет там ничего. Но в регистр должен записать мастер. Кто когда и как пишет в регистры? Можете нарисовать диаграмму обмена между ячейками сети? 

Duet
Offline
Зарегистрирован: 17.01.2015

.

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

Не похоже. Modbus view это что? Программа сниффер или мастер? 

Duet
Offline
Зарегистрирован: 17.01.2015

.