Скетч, который Вы мне дали. Писали Вы? Или где то его нашли? Мне бы узнать о нём больше. Что и как работает. А то комментариев в коде, как кот наплакал.
В ардуине мало памяти, поэтому в скобках прописываются не номера регитров, а количество, которое будет в обработке. У вас два регистра. Т.е.достаточно [2]. При этом 29 регистр будет иметь индекс массива [0], 1500 будет лежать в [1]. Во всех приведённых вами скечах я ни разу не видел вывода из ардуины в компьютер данных. Как вы собираетесь понять - получила ардуина что то или нет? И как отправлять дальше в комп?
Можете привести пример? Как получить значение регистра?
В коде, который давал человек, выше. Значения выводились в терминал порта. А в этом коде не получается. Мне просто нужно считать 29 регистр и вывести в мониторе порта ардуины, всё.
Мой код получается из программы FLprog при создании модбаса. Данная программа предназначена для графического программитрования ардуино. Я там создавал модбас. После вывода проекта FLprog создает обычный скетч на arduino IDE. Вот его то я и выкладывал. Вопросы по работе программы и скетчу лучше задавать у них н форуме.
насколько я понимаю библиотека #include <ModbusRtu.h> не поддерживает подключение модбас к софт сериал порту.
Надо что бы библиотека поддерживала подключение RS 485 на СОФТсериал порт. Чтобы железный порт использовать для монитора порта. Нельзя один и тот же порт использовать и для монитора порта и для модбаса.
насколько я понимаю библиотека #include <ModbusRtu.h> не поддерживает подключение модбас к софт сериал порту.
Надо что бы библиотека поддерживала подключение RS 485 на СОФТсериал порт. Чтобы железный порт использовать для монитора порта. Нельзя один и тот же порт использовать и для монитора порта и для модбаса.
Проблема в строке 13. В программе инициализируется сериал порт, потом этот порт отдается модбасу. Для обмена с компьютером надо использовать SoftwareSerial, так как SoftwareSerial на модбасе не подразумевает RS485. Т.е. RS485 нужно повесить на ноги 1 и 2, а с компом соединяться с помощью переходника TTL-USB через любые ноги и SoftwareSerial. После 43 строки и до 44 можно вписать любые команды вывода и обработки, как в примере software_serial_simple_master.ino
.....
case 2:
master.poll(); // check incoming messages
if (master.getState() == COM_IDLE) {
u8state = 0;
u32wait = millis() + 2000;
Serial.println(au16data[0]);//Or do something else!
}
.......
no matching function for call to 'Modbus::Modbus(int)'
/**
* Modbus master example 2:
* The purpose of this example is to query an array of data
* from an external Modbus slave device.
* This example is similar to "simple_master", but this example
* allows you to use software serial instead of hardware serial
* in case that you want to use D1 & D2 for other purposes.
* The link media can be USB or RS232.
The circuit:
* software serial rx(D3) connect to tx pin of another device
* software serial tx(D4) connect to rx pin of another device
* In this example, we will use two important methods so that we can use
* software serial.
*
* 1. Modbus::Modbus(uint8_t u8id)
* This is a constructor for a Master/Slave through USB/RS232C via software serial
* This constructor only specifies u8id (node address) and should be only
* used if you want to use software serial instead of hardware serial.
* This method is called if you create a ModBus object with only on parameter "u8id"
* u8id is the node address of the arduino that will be programmed on,
* 0 for master and 1..247 for slave
* for example: Modbus master(0);
* If you use this constructor you have to begin ModBus object by
* using "void Modbus::begin(SoftwareSerial *softPort, long u32speed)".
*
* 2. void Modbus::begin(SoftwareSerial *sPort, long u32speed)
* Initialize class object.
* This is the method you have to use if you construct the ModBus object by using
* Modbus::Modbus(uint8_t u8id) in order to use software serial and to avoid problems.
* You have to create a SoftwareSerial object on your own, as shown in the example.
* sPort is a pointer to your SoftwareSerial object, u32speed is the baud rate, in
* standard increments (300..115200)
created long time ago
by smarmengol
modified 29 July 2016
by Helium6072
This example code is in the public domain.
*/
#include <ModbusRtu.h>
#include <SoftwareSerial.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); // this is master and RS-232 or USB-FTDI via software serial
/**
* This is an structe which contains a query to an slave device
*/
modbus_t telegram;
unsigned long u32wait;
SoftwareSerial mySerial(7, 8);//Create a SoftwareSerial object so that we can use software serial. Search "software serial" on Arduino.cc to find out more details.
void setup() {
Serial.begin(9600);//use the hardware serial if you want to connect to your computer via usb cable, etc.
master.begin( &mySerial, 9600 ); // begin the ModBus object. The first parameter is the address of your SoftwareSerial address. Do not forget the "&". 9600 means baud-rate at 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 = 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)
u8state++;
break;
case 2:
master.poll(); // check incoming messages
if (master.getState() == COM_IDLE) {
u8state = 0;
u32wait = millis() + 2000;
Serial.println(au16data[0]);//Or do something else!
}
break;
}
}
Теперь еще один вопрос, как считать 2 регистра сразу?
Спасибо)
/**
* 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
* 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,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;
void setup() {
master.begin( 19200 ); // 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 = 1; // start address in slave
telegram.u16CoilsNo = 4; // 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;
}
}
насколько я понимаю, за 1 раз можно считать не более 16 регистров.
и это у Вас код слейва, Вам мастер шлет 2 записаных регистра №4 и № 1000?
если не ошибаюсь протакол модбус такое не поддерживает......
возможно там 2 разные телеграммы.... и в каждой не более 16 регистров.
и должно быть чтото в роде этого
telegram[0].u8id = Slaves; // slave address
telegram[0].u8fct = 3; // function code (this one is registers read)
telegram[0].u16RegAdd = 0; // start address in slave
telegram[0].u16CoilsNo = 6; // number of elements (coils or registers) to read
telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino
// telegram 1: write a single register
telegram[1].u8id = Slaves; // slave address
telegram[1].u8fct = 6; // function code (this one is write a single register)
telegram[1].u16RegAdd = 1000; // start address in slave
telegram[1].u16CoilsNo = 1; // number of elements (coils or registers) to read
telegram[1].au16reg = au16data+6; // pointer to a memory array in the Arduino
спасибо, с какой страницы надо начинать поиск на github и как отделить клоны библиотек от авторского оригинала? Например, если искать с главной страницы Github.com и потом включить фильтр "arduino", то показывает две другие библиотеки, а Вашей ссылки среди них нет:
Здравствуйте, дабы не плодить темы, подскажите, имеется счётчик и ПО которое его опрашивает через rs485 по протоколу modbas rtu, задача заключается в том чтобы, с помощью конвертера rs485 и ардуино брать данные с счётчика и отправлять их на компьютер через виртуальный сом порт. Спасибо.
Не знаю будет ли полезна вам эта информация, но я тоже несколько дней мучился на uno вычитыванием регисторов с энергометра DDS238.
Использовал библиотеку ModbusRtu.h
Подключение платки RS485 было к основному COM порту ардуины (пины RX,TX), т.е. к тому же по которому идет подключение к ПК. Так вот. Все сделал правильно, modbus сниффером слушал, пакеты отлично уходили, и отлично приходили ответы. А этот приемный регистр telegram.au16reg = au16data ну никак не обновлялся!
Короче, я везде в программе поставил конструкции Serial.Println И, о Боже данные вдруг считались.
Методом тыка убирал их по одной. В результате осталась одна. Как только ее убираешь все опять отваливается.
Ставишь - данные считываются. Опять же методом тыка обнаружил, что чем больше регистров за раз считываеешь со slave устройства, тем больше надо символов на выдачу.
Вот вам кусок кода с этой конструкцией.
Функция GetMessage вызывается для передачи на slave и получения ответа
В комментах все ясно.
Мистика. Если у вас есть идеи, интересно было бы послушать.
// moduladdr - адрес модуля DDS238
// функция последовательно считывает вольты, текущую мощность, расход квт.ч и записывает их в глоб структуру.
void ModbusDDS238 (uint8_t moduladdr)
{
telegram.u8id = 1; // адрес slave устройства (байт)
telegram.u8fct = 3; // код функции (байт)
telegram.u16RegAdd = 0;
telegram.u16CoilsNo = 15; // считаем значения 15 регистров
telegram.au16reg = au16data;
GetMessage(); //первый раз значение по умолчанию
GetMessage(); //норм
DDS238_TEnergy=(au16data[0]*65535+au16data[1])/100; //преобразуваем два 16бит слова в 32бит переменную и преобразуем в кВт/ч
DDS238_Voltage=au16data[12]/10; //убираем десятые доли
DDS238_ActPower=au16data[14];
//sprintf (str, "\nP=%d Wt, V=%d v,E=%d kwth\n",DDS238_ActPower,DDS238_Voltage,DDS238_TEnergy);
sprintf (str, "\nhttp://192.168.1.81/mqt.php?t=DDS238&s=1&p=%d&v=%d&e=%d\n",DDS238_ActPower,DDS238_Voltage,DDS238_TEnergy);
Serial.println(str);
return 0;
}
void GetMessage()
{
unsigned long u32wait2=millis()+200;
master.query( telegram ); // send query (only once)
master.poll();
while (master.getState() != COM_IDLE)
{
master.poll(); // check incoming messages
// Вот эта штука очень важная. Эти символы вносят некую задержку, чтобы функция считывания прочухалась
// про это нигде не написано, но если их подобрать неправильно почему данные нифига не считываются
Serial.print("...");
if (millis()>u32wait2)
{
Serial.println("modbus error");
return 1;
}
}
}
Всем добрый день
У кого есть простой скеч для чтения и записи на ардуино по модбас рту. У меня есть usb to rs485 и rs485 to ttl но не могу соединенится к ардуино по модбус межет я не правильно написал скеч
Заранее спасибо !!!
Всем добрый день У кого есть простой скеч для чтения и записи на ардуино по модбас рту. У меня есть usb to rs485 и rs485 to ttl но не могу соединенится к ардуино по модбус межет я не правильно написал скеч Заранее спасибо !!!
может в тех регистрах реально ноли?
Да нет, вот если выводить по одному значению, всё показывает.
Да и вот, прошло несколько минут и тут второе значение проснулось. Мистика какая то.
значит дело в слейве
Delete
Скетч, который Вы мне дали. Писали Вы? Или где то его нашли? Мне бы узнать о нём больше. Что и как работает. А то комментариев в коде, как кот наплакал.
В ардуине мало памяти, поэтому в скобках прописываются не номера регитров, а количество, которое будет в обработке. У вас два регистра. Т.е.достаточно [2]. При этом 29 регистр будет иметь индекс массива [0], 1500 будет лежать в [1]. Во всех приведённых вами скечах я ни разу не видел вывода из ардуины в компьютер данных. Как вы собираетесь понять - получила ардуина что то или нет? И как отправлять дальше в комп?
Можете привести пример? Как получить значение регистра?
Вот код:
В коде, который давал человек, выше. Значения выводились в терминал порта. А в этом коде не получается. Мне просто нужно считать 29 регистр и вывести в мониторе порта ардуины, всё.
Мой код получается из программы FLprog при создании модбаса. Данная программа предназначена для графического программитрования ардуино. Я там создавал модбас. После вывода проекта FLprog создает обычный скетч на arduino IDE. Вот его то я и выкладывал. Вопросы по работе программы и скетчу лучше задавать у них н форуме.
насколько я понимаю библиотека #include <ModbusRtu.h> не поддерживает подключение модбас к софт сериал порту.
Надо что бы библиотека поддерживала подключение RS 485 на СОФТсериал порт. Чтобы железный порт использовать для монитора порта. Нельзя один и тот же порт использовать и для монитора порта и для модбаса.
насколько я понимаю библиотека #include <ModbusRtu.h> не поддерживает подключение модбас к софт сериал порту.
Надо что бы библиотека поддерживала подключение RS 485 на СОФТсериал порт. Чтобы железный порт использовать для монитора порта. Нельзя один и тот же порт использовать и для монитора порта и для модбаса.
Из библиотеки ModbusRtu.h
Проблема в строке 13. В программе инициализируется сериал порт, потом этот порт отдается модбасу. Для обмена с компьютером надо использовать SoftwareSerial, так как SoftwareSerial на модбасе не подразумевает RS485. Т.е. RS485 нужно повесить на ноги 1 и 2, а с компом соединяться с помощью переходника TTL-USB через любые ноги и SoftwareSerial. После 43 строки и до 44 можно вписать любые команды вывода и обработки, как в примере software_serial_simple_master.ino
Ошибка компиляции:
У меня этот скетч компилируется без ошибок:
Спасибо. Всё заработало, даже без софтсериала.
Теперь еще один вопрос, как считать 2 регистра сразу?
Спасибо)
строка 55 у вас говорит о том что вы считываете 4 регистра начиная с адреса, указанного в 54 строке
Строка 54 - с какого номера регистра стартовать ответ. Строка 55 - сколько вподряд ячеек 16бит передать.
Если за строкой 63 поставить вывод в сом порт или на дисплей то можно будет увидеть что получили. Или вставить какую либо обработку.
Допустим я считываю 29 регистр в нём 2 coils. И мне нужно считать 1000 регистр, с 1 coils.
Как тут это реализовать?
насколько я понимаю, за 1 раз можно считать не более 16 регистров.
и это у Вас код слейва, Вам мастер шлет 2 записаных регистра №4 и № 1000?
если не ошибаюсь протакол модбус такое не поддерживает......
возможно там 2 разные телеграммы.... и в каждой не более 16 регистров.
и должно быть чтото в роде этого
Где взять библиотеку ModbusRTU.h или эту modbusrtu .
Нужна для работы в режимах Master и Slave
Где взять библиотеку ModbusRTU.h или эту modbusrtu .
Нужна для работы в режимах Master и Slave
https://github.com/prashantrar/ModbusRtu/tree/master/firmware
спасибо, с какой страницы надо начинать поиск на github и как отделить клоны библиотек от авторского оригинала? Например, если искать с главной страницы Github.com и потом включить фильтр "arduino", то показывает две другие библиотеки, а Вашей ссылки среди них нет:
https://github.com/search?l=Arduino&q=ModbusRtu&type=Repositories&utf8=%E2%9C%93
Взял для пробы пример из аналогичной библиотеки https://github.com/norgor/ModbusRTU
Как понять строку №2 - объявление класса, а угловые скобки <16> что означают?
Здравствуйте, дабы не плодить темы, подскажите, имеется счётчик и ПО которое его опрашивает через rs485 по протоколу modbas rtu, задача заключается в том чтобы, с помощью конвертера rs485 и ардуино брать данные с счётчика и отправлять их на компьютер через виртуальный сом порт. Спасибо.
Не знаю будет ли полезна вам эта информация, но я тоже несколько дней мучился на uno вычитыванием регисторов с энергометра DDS238.
Использовал библиотеку ModbusRtu.h
Подключение платки RS485 было к основному COM порту ардуины (пины RX,TX), т.е. к тому же по которому идет подключение к ПК. Так вот. Все сделал правильно, modbus сниффером слушал, пакеты отлично уходили, и отлично приходили ответы. А этот приемный регистр telegram.au16reg = au16data ну никак не обновлялся!
Короче, я везде в программе поставил конструкции Serial.Println И, о Боже данные вдруг считались.
Методом тыка убирал их по одной. В результате осталась одна. Как только ее убираешь все опять отваливается.
Ставишь - данные считываются. Опять же методом тыка обнаружил, что чем больше регистров за раз считываеешь со slave устройства, тем больше надо символов на выдачу.
Вот вам кусок кода с этой конструкцией.
Функция GetMessage вызывается для передачи на slave и получения ответа
В комментах все ясно.
Мистика. Если у вас есть идеи, интересно было бы послушать.
Добрый день!
"Спасибо. Всё заработало, даже без софтсериала."
Помогите мне пожалуйста считать два регистра... все перепробовал..... идут нули и все....
С уважением Дмитрий. Оренбург.
Всем добрый день
У кого есть простой скеч для чтения и записи на ардуино по модбас рту. У меня есть usb to rs485 и rs485 to ttl но не могу соединенится к ардуино по модбус межет я не правильно написал скеч
Заранее спасибо !!!
Судя по тому, какой ты громмотей, -"межет и не правильно", мы твой "скеч" не видели.
Добрый. У меня нету скечЯ. Но если выделить "чтения и записи на ардуино по модбас" и нажать "искать в гуглях", то первые две ссылки
https://microkontroller.ru/arduino-projects/posledovatelnaya-svyaz-po-pr...
http://mypractic.ru/urok-57-obmen-dannymi-mezhdu-platoj-arduino-i-kompyu...
Заранее пожалуйста!!!