Кстати, если будешь заказывать на Алиэкспресс, то вот Тебе доп. скидка в 10,5% в виде возврата средств на телефон или вебмани первые 7 дней после регистрации. Вот ссылка для регистрации https://cashback.epn.bz/?inviter=qkxtcs и вводите промокод epnbest2017, который Вам даст на семь дней покупок возврат в 10,5%.
Также, если не зарегистрированы на Алиэкспресс, то кидайте мейл на почту, вышлю ссылку, получите на 300 руб купон на покупки и плюс кучу других купонов на скидку.
Хотелось бы чтобы всегда мастер на связи был, т.е если слейвы не отвечают, мастер бы не впадал в спячку а продолжал их теребить запросами.
благодарю
может быть попробовать поставить ноль или космическое число зарядить?
Проще свой опрос написать, и опрашивать при каждом проходе. Плюс еще и в том, что с опытом будет больше знаний, будешь оптимизировать свой код получая постоянный результат в виде лучшей работы программы. А чужая библиотека - кот в мешке, и зависимость от нее в самом узком месте программы. Это же не опрос часов - тут важно все контролировать самому.
Хотелось бы чтобы всегда мастер на связи был, т.е если слейвы не отвечают, мастер бы не впадал в спячку а продолжал их теребить запросами.
благодарю
может быть попробовать поставить ноль или космическое число зарядить?
Проще свой опрос написать, и опрашивать при каждом проходе. Плюс еще и в том, что с опытом будет больше знаний, будешь оптимизировать свой код получая постоянный результат в виде лучшей работы программы. А чужая библиотека - кот в мешке, и зависимость от нее в самом узком месте программы. Это же не опрос часов - тут важно все контролировать самому.
Возможно и так. Но для начала думаю все же готовые решения рассмотреть. Итак с rs485 с нового года на одном месте топчусь.
Для преодоления ограничения в количестве регистров ардуинки возможно ли для сохранения в регистре использовать текстовую или числовую строку данных.
Например, к ардуинке-слейву подключены 3 датчика температуры, пара реле. Она все эти данные пишет в один регистр в виде строки с разделением пробелом: 25 24 15 1 1. Читать как 25, 24, 15 - температуры, 1, 1 - сработка реле. Ардуинка-мастер эти данные берет, раскрывает и получаем отдельные значения.
Для преодоления ограничения в количестве регистров ардуинки возможно ли для сохранения в регистре использовать текстовую или числовую строку данных.
Например, к ардуинке-слейву подключены 3 датчика температуры, пара реле. Она все эти данные пишет в один регистр в виде строки с разделением пробелом: 25 24 15 1 1. Читать как 25, 24, 15 - температуры, 1, 1 - сработка реле. Ардуинка-мастер эти данные берет, раскрывает и получаем отдельные значения.
Это возможно?
Благодарю
Аналоговые значения, если регистры идут последовательно, можно передать функцией 16, дискреты, если идут последовательно в приемнике, можно передать функцией 15.
В Modbus нет функций, позволяющих передавать за один пакет разные виды данных, но Вы можете отойти от этого стандарта и передавать свой пакет( (если не будете использовать бибилиотеки), привязать ему, например, функцию номер 33, под которой будете уже знать, что эти байты - туда, а эти - туда. Да и вообще придумать свой стандарт передачи - зачем Вам Modbus, если Вы не работаете с левыми устройствами, обязующими Вас использовать данный протокол. Посылайте слейвам свой пакет данных, идущих в нужной Вам последовательности, если слейвы больше ни с кем не "общаются", а в слейвах сортировать данные куда нужно и также собирать свой пакет для отправки.
Можно создать такой пакет в слейве: температура1, температура2, температура3, реле1, реле2, проверочный байт. Проверочный байт можете создать сложением всех 5 байтов. Ждете запроса от мастера своей комбинации байт, например 255. Получив данное число - кидаете свой пакет мастеру, читаете аналоги, дискреты и далее ждете нового запроса. Мастер принимает пакет, пишет в массив, складывает первые 5 байт и проверяет с 6 байтом - если числа равны - значит пакет получен, обрабатываем данные из массива как надо, если числа не равны - посылаем новый запрос.
А в чем проблема собственно? )) кто мешает постоянно генерировать пакет на оправку в цикле loop? Ведь retry_count - это число повторов, если слейв не ответил нам. Задаем ему например 2 пакета (10 пакетов вешает цикл отправки на одном пакете, 1 пакет не надежен, т.к. слейв может не услышать его полностью). Мастер отправит пакет, если нет ответа отправит его еще раз. Чтобы повторить эту процедуру просто инициализируем пакет Modbus не в Setup а в основном теле цикла. К примеру таким пакетом: modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0);
Ардуино его соберет и попробует отправить, попыток будет 2, затем снова соберет и попробует отправить, и так бесконечно))))
Желательно между циклами генерации поставить задержку, чтобы они не генерировались с частотой процессора )) а то rs485 будет не успевать их преобразовывать на отправку, как придут новые данные.
В этой теме я постараюсь описать свои эксперементы с промышленным протоколом Modbus для локальной сети и RS485 мне удалось как управлять ардуиной с ПЛК так и ардуиной управлять плк и модулями вводы вывода от овена.
позже добавлю еще про ардуино модбус мастер и модуль ввода как slave устройсво
"Измеренные значения не изменяются" - а пробовали через программу ОВЕН Конфигуратор Мх110 посмотерть значения этих каналов? Там изменяются данны? Если да, то можно повесить снифер на СОМ порт и посмотреть какие пакеты обмена идут.
За основу взял библиотеки SimpleModbusMaster.h и SimpleModbusSlave.h. Не "разговаривали" ардуинки по причине битых модулей на max485 (половину отбраковал).
Пробный стенд:
К мастеру подключен дисплей TM1867 - на него должна приходить информация (температура) со слейва. Мастер посылает 1. К слейву подключен ds18b20. Слейв должен получить от мастера число, если это 1 то зажечь светик на ардуинке (13 пин), и посылает мастеру температуру и число (генерация случайным образом от 0 до 9). Мастер выводит температуру на TM1867 и если число от слейва = 1 то зажигает свой светик.
Что имеем: слейв отвечает мастеру, посылает ему случайное число и температуру, мастер это принимает, выводит на экран, мигает светиком. Но слейв информацию от мастера не получает, т.е 1 не приходит от мастера к слейву, соответственно он светиком не моргает.
Help!
В мастере сбор пакетов в loop - чтобы в перспективе больше 30 параметров передавать\получать.
мастер:
//#include <iarduino_RTC.h>
#include <Wire.h>
#include <SimpleModbusMaster.h>
#include "TM1637.h"
#define CLK 6 // CLK -> pin D6
#define DIO 5 // DIO -> pin D5
TM1637 tm1637(CLK, DIO); // Семи сегментный индикатор, модуль на TM1637
#define brightness 7 // яркость индикатора, от 0 до 1
//iarduino_RTC time(RTC_DS3231);
int8_t TimeDisp[4];
//пакеты регистров Modbus
long previousMillis_regs = 0; // храним время последнего формирования пакетов
long interval_regs = 5000; //интервал
byte i = 0;
//////////////////// Макроопределения портов и настройки программы ///////////////////
#define baud 19200 // скоростьобмена по последовательному интерфейсу. (UART)
#define timeout 1000 // Длительность ожидание ответа (таймаут modbus)
#define polling 200 // скорость опроса по modbus
#define retry_count 1000 // количесво запросов modbus до ошибки и останова обмена
#define TxEnablePin 4 // Tx/Rx пин RS485
#define LED1 13 // светодиод 1
#define TOTAL_NO_OF_REGISTERS 4
enum
{
PACKET1,
PACKET2,
PACKET3,
PACKET4,
TOTAL_NO_OF_PACKETS // эту строку неменять
};
Packet packets[TOTAL_NO_OF_PACKETS];
unsigned int regs[TOTAL_NO_OF_REGISTERS];
void setup()
{
tm1637.init(); // инициализируем индикатор
tm1637.set(brightness); // включаем подсветку индикатора
tm1637.point(POINT_ON); // включаем точки
pinMode(LED1, OUTPUT);
} // конец void setup()
void loop()
{
unsigned long currentMillis_regs = millis();
//--------------------------------------------------------------------------------------
//сборка пакетов регистров Modbus
if (currentMillis_regs - previousMillis_regs > interval_regs)
{
previousMillis_regs = currentMillis_regs;
i++;
}
//пакет 1
if (i == 1)
{
// Настраиваем пакеты
// Шестой параметр - это индекс ячейки в массиве, размещенном в памяти ведущего устройства, в которую будет
// помещен результат или из которой будут браться данные для передачи в подчиненное устройство. В нашем коде - это массив reg
// Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0); // чтение данных slave-master (slave адрес 1, регистр 0)
modbus_construct(&packets[PACKET2], 1, READ_HOLDING_REGISTERS, 1, 1, 1); // чтение данных slave-master (slave адрес 1, регистр 1)
// Пакет,SLAVE адрес,функция модбус,адрес регистра,данные,локальный адрес регистра.
modbus_construct(&packets[PACKET3], 1, PRESET_MULTIPLE_REGISTERS, 2, 1, 2); // запись данных master-slave (slave адрес 1, регистр 2)
modbus_construct(&packets[PACKET4], 1, PRESET_MULTIPLE_REGISTERS, 3, 1, 3); // запись данных master-slave (slave адрес 1, регистр 3)
// инициализируем протокол модбус
modbus_configure(&Serial, baud, SERIAL_8N2, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);
//modbus_update(); // запуск обмена по Modbus
regs[2] = 1;
i = 0;
}
modbus_update(); // запуск обмена по Modbus
if (regs[1] == 1)
{
digitalWrite(LED1, HIGH);
}
else
{
digitalWrite(LED1, LOW);
}
//Serial.println(regs[0]);
TimeDisp[0] = regs[0] / 10;
TimeDisp[1] = regs[0] % 10;
TimeDisp[2] = regs[1] / 10;
TimeDisp[3] = regs[1] % 10;
tm1637.display(TimeDisp); // воводим на индикатор
} // конец void loop()/*
слейв:
#include <SimpleModbusSlave.h>
#include <DallasTemperature.h>
//////////////////// Макроопределения портов и настройки программы ///////////////////
#define TxEnablePin 4 // Tx/Rx пин RS485
#define baud 19200 // скоростьобмена по последовательному интерфейсу. (UART)
#define Slave_ID 1 // Адрес Slave устройсва
#define LED1 13 // светодиод 1
//////////////// Регистры вашего Slave ///////////////////
enum
{
//Просто добавьте или удалите регистры. Первый регистр начинается по адресу 0
reg_0, // исходящий 1
reg_1, // исходящий 2
reg_2, // входящий 1
reg_3, // входящий 2
HOLDING_REGS_SIZE // Это не удалять размер массива HOLDING_REGS.
//общее количество регистров для функции 3 и 16 разделяет тотже самый массив регистров
//т.е. то же самое адресное пространство
};
unsigned int holdingRegs[HOLDING_REGS_SIZE]; // функции 3 и 16 массив регистров
////////////////////////////////////////////////////////////
//ds18b20
OneWire oneWire(3); // вход датчиков 18b20
DallasTemperature ds(&oneWire);
DeviceAddress ds_frosya = {0x28, 0xFF, 0x33, 0xD0, 0x72, 0x16, 0x5, 0x5A};
//подсчет времени
//опрос датчиков
long previousMillis_sensor = 0; // храним время последнего опроса датчиков
long interval_sensor = 5000; //интервал
//температура
int temp;
float i = 0;
void setup()
{
modbus_configure(&Serial, baud, SERIAL_8N2, Slave_ID, TxEnablePin, HOLDING_REGS_SIZE, holdingRegs);
modbus_update_comms(19200, SERIAL_8N2, 1);
pinMode(LED1, OUTPUT);
}// конец void setup()
void loop()
{
unsigned long currentMillis_sensor = millis();
//--------------------------------------------------------------------------------------
//ds
if (currentMillis_sensor - previousMillis_sensor > interval_sensor)
{
previousMillis_sensor = currentMillis_sensor;
i++;
}
//dallas подготовка
if (i == 1)
{
ds.requestTemperatures(); // считываем температуру с датчиков
}
//dallas считывание
if (i == 2)
{
if (ds.getTempC(ds_frosya) <= 50) temp = ds.getTempC(ds_frosya);
i = 0;
}
modbus_update(); // запуск обмена по Modbus
holdingRegs[reg_0] = temp;
holdingRegs[reg_1] = random(9);
if (holdingRegs[reg_3] == 0)
{
digitalWrite(LED1, LOW);
}
else
{
digitalWrite(LED1, HIGH);
}
//Serial.println(temp);
}// конец
*/
Библиотеки стабильно работают. Вся работа библиотеки выполняется в фоновом режиме. Ваша программа выполнятся без задержек. Примеры и библиотеки хорошо прокомментированы и интуитивно понятны это позволит вам легко создать свой первый проект с Modbus.
Библиотеки написаны с применением объектно-ориентированного подхода, на языке C не используя C ++. Это облегчает портирование программного обеспечения библиотеки на другие платформы, который поддерживают компилятор C.
позже добавлю еще про ардуино модбус мастер и модуль ввода как slave устройсво
Организовал обмен - овеновский СПК107 (как мастер) + ардуино уно (как слейв). Библиотека slave RTU. На этой же шине висят два ПР200. Обмен норм, все стабильно. НО замечен такой момент:
#define Slave_ID 1 // Адрес Slave устройсва
пытаюсь переназначить адреса слейвов, при замене вышеуказанного ID ардуина упорно висит на первом адресе. Т.е. ставим 2 или 3 или 16, без разницы - она опрашивается мастером только по адресу слейва 1. В чем причина, кто-нибудь сталкивался? Баг пока не критичный, но как действовать при необходимости подцепить несколько ардуин на один канал?
в том то и прикол, что ID меняешь, заливаешь в ардуину, опрашиваешь по новому адресу - нет ответа. Опрашиваешь по адресу 1, есть связь. Т.е. какой ID ни ставь - адрес у ардуины все-равно 1. Загадка...)
пробовал принудительно адрес писать, без Slave_ID. Заливал разными компиляторами, родным ардуиновским и через AtmelStudio. Нет эффекта...) Опрашиваю с СПК107, стандартная процедура, обмен корректный в обе стороны, ардуина бодро жужжит шаговым движком по команде мастера. НО ТОЛЬКО ПО ПЕРВОМУ АДРЕСУ! Странное дело) Буду разбираться дальше. Отпишусь, когда найду в чем прикол.
Столкнулся с такой же фигней, только использовал две ардуины (мастер и слэйв), и тоже опрос шел только по первому адресу в независимости от того, какой адрес ставил слэйву.
Я ее прочел. Многое понятно но так же не совсем ясно несколько моментов. Вот дупустим пример основанный на бибилиотеке данной.
#include <SimpleModbusMaster.h>
#define baud 9600
#define timeout 1000
#define polling 200
#define retry_count 10
#define TxEnablePin 2
#define TOTAL_NO_OF_REGISTERS 4
enum {
PACKET1,
PACKET2,
TOTAL_NO_OF_PACKETS};
Packet packets[TOTAL_NO_OF_PACKETS];
unsigned int regs[TOTAL_NO_OF_REGISTERS];
void setup() {
// Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, regs[0]);
modbus_construct(&packets[PACKET2], 1, PRESET_MULTIPLE_REGISTERS, 1, 1, regs[1]);
modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);
}
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);}
}
Сначала суть. Есть готовое устроиства на базе кристала atmega2560. У данноо устроиства 9 дискретных выходов, 9 дискретных входов, 5 аналоговых входов, а так же на борту есть еще 2а реле и так же на плате разведено подключение МК к линии 485. делал я это для своей задачи своеобразной. Теперь решил к этому делую написать прошивку. Сначала хотел делать на библиотеке ModbusRTU, но не зашло че то) Потом почел про эту и вот не задача не понимаю несколько вещей:
1. В данной бибилиотеке если я использую кристал 2560 сколько я могу регистров хранить то используя данную бибилиотеку? (TOTAL_NO_OF_REGISTERS сколько максимуму может быть в данной библиотке)
2. Из вашего опыта как лучше организовать хранение значений с моих 23 портов? (я бы хотел чтобы все значения записывались в цикле в массив и уже оперировались дальше в цикле)
3. И не могли бы вы мне сказать как в данной библиотеки писать биты и байты и читать их? Я просто увидел примеры только в целом с регистрами. Т.е. не так как организованно например в библиотеки ModbusRTU. Может есть еще какой то функционал. Но в описании библиотеки я ниче не понял ибо не сильно разбираюсь в англиском=( Заранее спасибо за советы и ответы.
Можете помочь с библиотекой кое что понять? Вроде понял всме кроме одного=( почему у меня не читаются регистры выше 4го??? скрины ниже. Код простой просто 7 регистров в каждый присваевается значение свое не важно какое. Так вот первые 4е читаются отлично. Выше же откажывается читать выдавая ошибку что типа не верный адресс.
Ребят подскажите как Вы думаете как читать в данной библиотеке сразу два или более регистров 1 пакетом? Т.е. как бы понимаю что функция меняю но где в конце пакета надо указать локальное хранилище данных там что надо регистры через запятаю писат ьили как? Нет примера, не найду. Заранее спасибо
Очень нужна ваша подсказка. В данной библиотеке я так и не понял по инструкции как запросить сразу 7 регистров. ТОчнее не понял как их сохранить в локальное харнилище в массив? можете строчку написать. И второй вопрос про буфер в 29 регистров. Я не понял это имеется ввиду что за раз не может больше 29 запросить? или хранить не может больше 29ти значений. У меня мастер на кристале атмега 2560 но не ардуина а своя плата без загрузчика и т.д. Просто уже две неделе бьюсь. Слейвы сделал работают отчлино! А вот с мастером беда какая то. Три устроиства и желательно сделать три пакета к каждому чтобы не делать 14 пакетов. А как сохранять не ясно.
Добрый день, очень нужна ваша помощь по билиотеке Simple Modbus. Написал тестовый скетч, при обрыве связи, попытки обмена прекращаются через заданное число раз, и все. Как получить информацию о том что обмен остановлен? в описании к библиотеке есть упоминание соответствующих переменных но как обращатся к ним, как считать данные?
Цитата:
"Как уже упоминалось, пакет содержит всю информацию, необходимую FSM. Информация и различныесчетчики могут быть доступны пользователю для каждого пакета. Счетчики информации могут использоваться для диагностических целях. Ниже приводится краткое объяснение:
запросы - содержит общие запросы к подчиненному
success_requests - содержит итоговые успешные запросы
failed_requests - общие ошибки кадра, сбои контрольной суммы и отказы буфера. Это приведет к
тайм-аут.
retries - содержит количество попыток
exception_errors - содержит конкретный счетчик ответов на исключение modbus. Обычно они являются незаконными
функции, незаконного адреса, незаконного значения данных или разного рода ошибок."
В примерах к старым версиям этой библиотеки есть вот что :
"
/* You can check or alter the internal counters of a specific packet like this:
packet1->requests;
packet1->successful_requests;
packet1->failed_requests;
packet1->exception_errors;
packet2->requests;
packet2->successful_requests;
packet2->failed_requests;
packet2->exception_errors;
*/
"
/*
Пример будет использовать packet1, чтобы считать регистр из адреса 0 (значение adc ch0)
от arduino раба (id=1). Это будет тогда использовать это значение, чтобы скорректировать яркость
из вовлеченного контакт 9 использований PWM.
Это будет тогда использовать packet2, чтобы записать регистр (его собственное значение adc ch0), чтобы адресоваться 1
на arduino рабе (id=1) корректировка яркости вовлеченного контакт 9 использований PWM.
*/
#include <SimpleModbusMaster.h>
//////////////////// Макроопределения портов и настройки программы ///////////////////
#define baud 230400 // скоростьобмена по последовательному интерфейсу. (UART)
#define timeout 1000 // Длительность ожидание ответа (таймаут modbus)
#define polling 200 // скорость опроса по modbus
#define retry_count 10 // количесво запросов modbus до ошибки и останова обмена
#define TxEnablePin 20 // Tx/Rx пин RS485
const unsigned char serialInterval = 30; // интервал отправки в SERIAL в милис\10 ( В ПРОГРАММЕ УМНОЖАЕТСЯ НА 10)МАКС ЗНАЧЕНИЕ 255 (ИЛИ 2550 милис.) сейчас 300мс.
unsigned long serialTime; // переменная хранения времени для отпраки в порт.
// Общая сумма доступной памяти на master устройстве, для хранения данных
// не забудьте изменить макроопределение TOTAL_NO_OF_REGISTERS. Если из слейва
// запрашиваешь 4 регистра, то тогда в массиве reg должно быть не меньше 4х ячеек
// для хранения полученных данных.
#define TOTAL_NO_OF_REGISTERS 20
// Масив пакетов modbus
// Для добавления новых пакетов просто добавте ихсюда
// сколько вам нужно.
enum
{
PACKET1,
PACKET2,
PACKET3,
PACKET4,
PACKET5,
PACKET6,
PACKET7,
PACKET8,
PACKET9,
PACKET10,
PACKET11,
PACKET12,
PACKET13,
PACKET14,
PACKET15,
PACKET16, // резерв
PACKET17, // резерв
PACKET18, // резерв
PACKET19, // резерв
PACKET20, // резерв
TOTAL_NO_OF_PACKETS // эту строку неменять
};
// Масив пакетов модбус
Packet packets[TOTAL_NO_OF_PACKETS];
// Массив хранения содержимого принятых и передающихся регистров
unsigned int regs[TOTAL_NO_OF_REGISTERS];
int ERR = 0;
//////////////////////////////////////////////////////////////////////////
int volt = 0; // переменная хранения вычисленного значения напряжения в вольтах. делить на 100.
int Boost1 = 0; // переменная хранения вычисленного значения Boost1 в барах. делить на 100.
int Boost2 = 0; // переменная хранения вычисленного значения Boost2 в барах. делить на 100.
int Press1 = 0; // переменная хранения вычисленного значения Press1 в барах. делить на 100.
int temp1 = 0; // переменная хранения вычисленного значения temp1 сенсора.
int temp2 = 0; // переменная хранения вычисленного значения temp2 сенсора.
/////////////////////////////////////////////////////////// MAX31855.
int EGT = 0; // переменная хранения EGT сенсора.
int intemp = 0; // переменная хранения внутренней температуры MAX31855.
/////////////////////////////////////////////////////////// ds18b20
int temp11 = 0; // измеренная температура ds18b20 нужно делить на 10.
int temp22 = 0; // измеренная температура ds18b20 нужно делить на 10.
int temp33 = 0; // измеренная температура ds18b20 нужно делить на 10.
void setup()
{
// Настраиваем пакеты
// Шестой параметр - это индекс ячейки в массиве, размещенном в памяти ведущего устройства, в которую будет
// помещен результат или из которой будут браться данные для передачи в подчиненное устройство. В нашем коде - это массив reg
// Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0); // чтение данных slave-master (slave адрес 1, регистр 0)
modbus_construct(&packets[PACKET2], 1, READ_HOLDING_REGISTERS, 1, 1, 1); // чтение данных slave-master (slave адрес 1, регистр 1)
modbus_construct(&packets[PACKET3], 1, READ_HOLDING_REGISTERS, 2, 1, 2); // чтение данных slave-master (slave адрес 1, регистр 2)
modbus_construct(&packets[PACKET4], 1, READ_HOLDING_REGISTERS, 3, 1, 3); // чтение данных slave-master (slave адрес 1, регистр 3)
modbus_construct(&packets[PACKET5], 1, READ_HOLDING_REGISTERS, 4, 1, 4); // чтение данных slave-master (slave адрес 1, регистр 4)
modbus_construct(&packets[PACKET6], 1, READ_HOLDING_REGISTERS, 5, 1, 5); // чтение данных slave-master (slave адрес 1, регистр 5)
modbus_construct(&packets[PACKET7], 1, READ_HOLDING_REGISTERS, 6, 1, 6); // чтение данных slave-master (slave адрес 1, регистр 6)
modbus_construct(&packets[PACKET8], 1, READ_HOLDING_REGISTERS, 7, 1, 7); // чтение данных slave-master (slave адрес 1, регистр 7)
modbus_construct(&packets[PACKET9], 1, READ_HOLDING_REGISTERS, 8, 1, 8); // чтение данных slave-master (slave адрес 1, регистр 8)
modbus_construct(&packets[PACKET10], 1, READ_HOLDING_REGISTERS, 9, 1, 9); // чтение данных slave-master (slave адрес 1, регистр 9)
modbus_construct(&packets[PACKET11], 1, READ_HOLDING_REGISTERS, 10, 1, 10); // чтение данных slave-master (slave адрес 1, регистр 10)
modbus_construct(&packets[PACKET12], 1, READ_HOLDING_REGISTERS, 11, 1, 11); // чтение данных slave-master (slave адрес 1, регистр 11)
modbus_construct(&packets[PACKET13], 1, READ_HOLDING_REGISTERS, 12, 1, 12); // чтение данных slave-master (slave адрес 1, регистр 12)
modbus_construct(&packets[PACKET14], 1, READ_HOLDING_REGISTERS, 13, 1, 13); // чтение данных slave-master (slave адрес 1, регистр 13)
modbus_construct(&packets[PACKET15], 1, READ_HOLDING_REGISTERS, 14, 1, 14); // чтение данных slave-master (slave адрес 1, регистр 14)
// Пакет,SLAVE адрес,функция модбус,адрес регистра,данные,локальный адрес регистра.
//modbus_construct(&packets[PACKET3], 1, PRESET_MULTIPLE_REGISTERS, 2, 1, 2); // запись данных master-slave (slave адрес 1, регистр 2)
//modbus_construct(&packets[PACKET4], 1, PRESET_MULTIPLE_REGISTERS, 3, 1, 3); // запись данных master-slave (slave адрес 1, регистр 3)
// инициализируем протокол модбус
modbus_configure(&Serial1, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);
Serial.begin(9600);
}
void loop()
{
SerialPrint(); // функция отправки в порт.
modbus_update(); // запуск обмена по Modbus
volt = regs[0] / 100; // чтение данных slave-master (slave адрес 1, регистр 0)
Boost1 = regs[1] / 100; // чтение данных slave-master (slave адрес 1, регистр 1)
Boost2 = regs[2] / 100;
Press1 = regs[3] / 100;
temp1 = regs[4];
temp2 = regs[5];
/////////////////////////////////////////////////////////// MAX31855.
EGT = regs[6];
intemp = regs[7];
/////////////////////////////////////////////////////////// ds18b20
temp11 = regs[8] / 10;
temp22 = regs[9] / 10;
temp33 = regs[10] / 10;
ERR = PACKET1->exception_errors;
//regs[2] = 255; // запись данных master-slave (slave адрес 1, регистр 2), запись константы
//regs[3] = analogRead(0); // запись данных master-slave (slave адрес 1, регистр 3), значение из аналогового входа 0
} // конец void loop()
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void SerialPrint() //функция отправки в порт.
{
if (millis() - serialTime > serialInterval * 10) { // проверяем если больше serialInterval.
Serial.print(" t11= "); // отправляем в порт.
Serial.print(temp11); // отправляем в порт.
Serial.print(" ");
Serial.print(" t22= "); // отправляем в порт.
Serial.print(temp22); // отправляем в порт.
Serial.print(" ");
Serial.print(" t33= "); // отправляем в порт.
Serial.print(temp33); // отправляем в порт.
Serial.println(" ");
Serial.print(" volt = ");
Serial.print(volt);
Serial.println("V");
Serial.print(" Boost1 = ");
Serial.print(Boost1);
Serial.print(" Boost2 = ");
Serial.print(Boost2);
Serial.print(" Press = ");
Serial.print(Press1);
Serial.print(" t1 = ");
Serial.print(temp1);
Serial.print("C");
Serial.print(" t2 = ");
Serial.print(temp2);
Serial.println("C");
Serial.print(" Intepm = ");
Serial.print(intemp);
Serial.print(" EGT = ");
Serial.println(EGT);
Serial.println(" ------------------------------------------- ");
Serial.print (ERR);
Serial.println(" ------------------------------------------- ");
serialTime = millis(); //присваеваем переменной, значение счетчика милисекунд.
}
}
/* You can check or alter the internal counters of a specific packet like this:
packet1->requests;
packet1->successful_requests;
packet1->failed_requests;
packet1->exception_errors;
packet2->requests;
packet2->successful_requests;
packet2->failed_requests;
packet2->exception_errors;
*/
При компиляции выдает ошибку в строке проверки ошибки :
Arduino: 1.8.5 (Windows 7), Плата:"Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"
C:\Users\Werwolf\Desktop\MasterArduino\MasterArduino.ino: In function 'void loop()':
MasterArduino:134: error: base operand of '->' is not a pointer
Вопрос был как читать переменные ошибок ( синтаксис).
Но кажется я нашел решение:
на забугорном сайте пишут- вы можете увидеть полный статус каждого пакета со следующим синтаксисом:
packets[PACKET_NUMBER].requests
packets[PACKET_NUMBER].successful_requests
packets[PACKET_NUMBER].failed_requests
packets[PACKET_NUMBER].exception_errors
packets[PACKET_NUMBER].retries
packets[PACKET_NUMBER].connection
unsigned int c = packets[PACKET1].failed_requests; // переменная c содержит теперь количество неудачных запросов
Ну как бы вы все верно написали изначально только применили эт овсе не правильно. Такого -> оператора нет))) То что вы щас написали последнее является правильным применением для данной библиотеки.
Я просто чуть в шоке) спрошу так вы сами знаете почему не компилируется? вы понимаете что Вам компилятор написал)???
я просто понял, что ему не нравится строка, в которой я пытался получить значение переменной с ошибками. "ERR = PACKET1->exception_errors;" -синтаксис не верен, спрашивал как правильно написать.
В русскоязычном сегменте интернета я упоминания и примеров не нашел. Может кому пригодится....
Добрый день скажите. Использую в своем проекте библиотеки SimpleModbusSlave и SimpleModbusMaster. Вопрос в данной бибилотеке мастера не постоянно слать заранее подготовленные контструкции. Т.е. чтобы МК какую то часть данных каждый цикл запрашивал и обновлял а то что касается управления чтобы по кнпоке когда надо отправлял запрос. Просто никак не въеду. Заранее спасибо
МОжно подробнее? У меня все пашет как бы но смысл в том что библа эта как то не очень работает очень много проходов. Т.е. если я разово запускаю функцию modbus.update то нифига не уходит ничего а если в цикле то все пашет .Как это поправить? Или в чем может быть беда тут?
и в loop я делаю просто обмен modbus_update(); Так вот все работает как и надо но есть две проблемы:
1. Работает с задержкой в 3-5 секунд
2. Если делаю отдельно по кнопке modbus_update(); то вообще не срабатывает или срабатывает с 3-10 раза почему? не ясно.
Но интересно то что если я подключаю комп как мастер через 485-USB адаптер то все шустр ои быстро без задержек делается. Вот и не могу понять как решить эти две проблемы
Подскажите плиз, как можно преодолеть ограничение в 29 регистров у ардуинки? Хотелось бы с датчиков ds18b20 температуру гонять.
благодарю
Подключи 16 канальный мультиплексор. https://ru.aliexpress.com/item/CD74HC4067-16-Channel-Analog-Digital-Multiplexer-Breakout-Board-Module-For-Arduino/32787406285.html?spm=2114.13010308.0.0.BXYjS1
Схему и код можно найти на ютубе.
Кстати, если будешь заказывать на Алиэкспресс, то вот Тебе доп. скидка в 10,5% в виде возврата средств на телефон или вебмани первые 7 дней после регистрации. Вот ссылка для регистрации https://cashback.epn.bz/?inviter=qkxtcs и вводите промокод epnbest2017, который Вам даст на семь дней покупок возврат в 10,5%.
Также, если не зарегистрированы на Алиэкспресс, то кидайте мейл на почту, вышлю ссылку, получите на 300 руб купон на покупки и плюс кучу других купонов на скидку.
Ребята, а как можно обойти:
Хотелось бы чтобы всегда мастер на связи был, т.е если слейвы не отвечают, мастер бы не впадал в спячку а продолжал их теребить запросами.
благодарю
может быть попробовать поставить ноль или космическое число зарядить?
Ребята, а как можно обойти:
Хотелось бы чтобы всегда мастер на связи был, т.е если слейвы не отвечают, мастер бы не впадал в спячку а продолжал их теребить запросами.
благодарю
может быть попробовать поставить ноль или космическое число зарядить?
Проще свой опрос написать, и опрашивать при каждом проходе. Плюс еще и в том, что с опытом будет больше знаний, будешь оптимизировать свой код получая постоянный результат в виде лучшей работы программы. А чужая библиотека - кот в мешке, и зависимость от нее в самом узком месте программы. Это же не опрос часов - тут важно все контролировать самому.
Ребята, а как можно обойти:
Хотелось бы чтобы всегда мастер на связи был, т.е если слейвы не отвечают, мастер бы не впадал в спячку а продолжал их теребить запросами.
благодарю
может быть попробовать поставить ноль или космическое число зарядить?
Проще свой опрос написать, и опрашивать при каждом проходе. Плюс еще и в том, что с опытом будет больше знаний, будешь оптимизировать свой код получая постоянный результат в виде лучшей работы программы. А чужая библиотека - кот в мешке, и зависимость от нее в самом узком месте программы. Это же не опрос часов - тут важно все контролировать самому.
Возможно и так. Но для начала думаю все же готовые решения рассмотреть. Итак с rs485 с нового года на одном месте топчусь.
не увидел проблем с этой библиотекой, работает как часы
на счет числа опросов можно как раз в самой библиотеке и поковыряться
Покритикуйте идею, плиз.
Для преодоления ограничения в количестве регистров ардуинки возможно ли для сохранения в регистре использовать текстовую или числовую строку данных.
Например, к ардуинке-слейву подключены 3 датчика температуры, пара реле. Она все эти данные пишет в один регистр в виде строки с разделением пробелом: 25 24 15 1 1. Читать как 25, 24, 15 - температуры, 1, 1 - сработка реле. Ардуинка-мастер эти данные берет, раскрывает и получаем отдельные значения.
Это возможно?
Благодарю
Покритикуйте идею, плиз.
Для преодоления ограничения в количестве регистров ардуинки возможно ли для сохранения в регистре использовать текстовую или числовую строку данных.
Например, к ардуинке-слейву подключены 3 датчика температуры, пара реле. Она все эти данные пишет в один регистр в виде строки с разделением пробелом: 25 24 15 1 1. Читать как 25, 24, 15 - температуры, 1, 1 - сработка реле. Ардуинка-мастер эти данные берет, раскрывает и получаем отдельные значения.
Это возможно?
Благодарю
Аналоговые значения, если регистры идут последовательно, можно передать функцией 16, дискреты, если идут последовательно в приемнике, можно передать функцией 15.
В Modbus нет функций, позволяющих передавать за один пакет разные виды данных, но Вы можете отойти от этого стандарта и передавать свой пакет( (если не будете использовать бибилиотеки), привязать ему, например, функцию номер 33, под которой будете уже знать, что эти байты - туда, а эти - туда. Да и вообще придумать свой стандарт передачи - зачем Вам Modbus, если Вы не работаете с левыми устройствами, обязующими Вас использовать данный протокол. Посылайте слейвам свой пакет данных, идущих в нужной Вам последовательности, если слейвы больше ни с кем не "общаются", а в слейвах сортировать данные куда нужно и также собирать свой пакет для отправки.
Можно создать такой пакет в слейве: температура1, температура2, температура3, реле1, реле2, проверочный байт. Проверочный байт можете создать сложением всех 5 байтов. Ждете запроса от мастера своей комбинации байт, например 255. Получив данное число - кидаете свой пакет мастеру, читаете аналоги, дискреты и далее ждете нового запроса. Мастер принимает пакет, пишет в массив, складывает первые 5 байт и проверяет с 6 байтом - если числа равны - значит пакет получен, обрабатываем данные из массива как надо, если числа не равны - посылаем новый запрос.
А в чем проблема собственно? )) кто мешает постоянно генерировать пакет на оправку в цикле loop? Ведь retry_count - это число повторов, если слейв не ответил нам. Задаем ему например 2 пакета (10 пакетов вешает цикл отправки на одном пакете, 1 пакет не надежен, т.к. слейв может не услышать его полностью). Мастер отправит пакет, если нет ответа отправит его еще раз. Чтобы повторить эту процедуру просто инициализируем пакет Modbus не в Setup а в основном теле цикла. К примеру таким пакетом: modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0);
Ардуино его соберет и попробует отправить, попыток будет 2, затем снова соберет и попробует отправить, и так бесконечно))))
Желательно между циклами генерации поставить задержку, чтобы они не генерировались с частотой процессора )) а то rs485 будет не успевать их преобразовывать на отправку, как придут новые данные.
Здравствуйте товарищи! Вопрос все о том же... Связь аналогового модуля ОВЕН с ардуиной-мастер.
Задача - в браузере наблюдать измеренное значение.
Использую: ардуино Уно, преобразователь RS485, ethernet модуль(enc28j60), ну и собственно Овен МВ110-2АС.
для опроса Овен на ардуине подключаю SimpleModbusMaster.h
В общем-то успех есть, но с оговорками. Возникают 2-е проблемы:
Измеренные значения не изменяются, даже если отсоединить сигнал от канала ОВЕН.
И инициализирутся только один Пакет, т.е. одним пакетом могу опросить 2 канала, а опросить каждый канал отдельным пакетом нет.
При опросе использовал и 3-ю, и 4-ю функции Modbus. Измеренные значения хранятся 0х100 - 1 канал, 0х101 - 2 канал.
001
#include <SimpleModbusMaster.h>
002
#include <EtherCard.h>
003
004
static
byte
mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
005
static
byte
myip[] = { 192,168,1,203 };
006
007
byte
Ethernet::buffer[500];
008
BufferFiller bfill;
009
010
011
//////////////////// Макроопределения портов и настройки программы ///////////////////
012
#define baud 9600 // скоростьобмена по последовательному интерфейсу. (UART)
013
#define timeout 1000 // Длительность ожидание ответа (таймаут modbus)
014
#define polling 200 // скорость опроса по modbus
015
#define retry_count 10 // количесво запросов modbus до ошибки и останова обмена
016
#define TxEnablePin 2 // Tx/Rx пин RS485
017
#define LED1 9 // светодиод 1
018
#define LED2 13 // светодиод 2
019
020
// Общая сумма доступной памяти на master устройстве, для хранения данных
021
// не забудьте изменить макроопределение TOTAL_NO_OF_REGISTERS. Если из слейва
022
// запрашиваешь 4 регистра, то тогда в массиве reg должно быть не меньше 4х ячеек
023
// для хранения полученных данных.
024
#define TOTAL_NO_OF_REGISTERS 6
025
026
// Масив пакетов modbus
027
// Для добавления новых пакетов просто добавте ихсюда
028
// сколько вам нужно.
029
int
ch1,ch2;
030
enum
031
{
032
PACKET1,
033
PACKET2,
034
PACKET3,
035
PACKET4,
036
TOTAL_NO_OF_PACKETS
// эту строку неменять
037
};
038
039
// Масив пакетов модбус
040
Packet packets[TOTAL_NO_OF_PACKETS];
041
042
// Массив хранения содержимого принятых и передающихся регистров
043
unsigned
int
regs[TOTAL_NO_OF_REGISTERS];
044
045
static
word homePage() {
046
047
bfill = ether.tcpOffset();
048
bfill.emit_p(PSTR(
049
"HTTP/1.0 200 OK\r\n"
050
"Content-Type: text/html\r\n"
051
"Pragma: no-cache\r\n"
052
"\r\n"
053
"<meta http-equiv='refresh' content='1'/>"
054
"<title>ModBus Master</title>"
055
"<h1>$D::$D</h1>"
),
056
regs[0],regs[1]);
057
return
bfill.position();
058
}
059
060
void
setup
()
061
{
062
Serial
.begin(9600);
063
if
(ether.begin(
sizeof
Ethernet::buffer, mymac) == 0)
064
Serial
.println(F(
"Failed to access Ethernet controller"
));
065
ether.staticSetup(myip);
066
067
// Настраиваем пакеты
068
// Шестой параметр - это индекс ячейки в массиве, размещенном в памяти ведущего устройства, в которую будет
069
// помещен результат или из которой будут браться данные для передачи в подчиненное устройство. В нашем коде - это массив reg
070
071
// Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
072
modbus_construct(&packets[PACKET1], 16, READ_INPUT_REGISTERS, 256, 2, 0);
// (slave адрес 16, регистр 0x100)
073
//modbus_construct(&packets[PACKET2],16, READ_HOLDING_REGISTERS, 257, 1, 2); // (slave адрес 16, регистр 0x101)
074
075
// инициализируем протокол модбус
076
modbus_configure(&
Serial
, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);
077
078
pinMode(LED1, OUTPUT);
079
pinMode(LED2, OUTPUT);
080
}
// конец void setup()
081
082
//onwVersion of loop()
083
void
loop
()
084
{
085
modbus_update();
086
word len = ether.packetReceive();
087
word pos = ether.packetLoop(len);
088
089
if
(pos)
// check if valid tcp data is received
090
ether.httpServerReply(homePage());
// send web page data
091
//ch1=regs[0];
092
//ch2=regs[1];
093
Serial
.print(
" "
);
094
Serial
.print(regs[0],DEC);
095
Serial
.print(
" "
);
096
Serial
.print(regs[1],DEC);
097
Serial
.print(
" "
);
098
/*Serial.print(regs[2],HEX);
099
Serial.print(" ");
100
Serial.print(regs[3],HEX); */
101
Serial
.print(
"\n"
);
102
//delay(10);
103
104
}
В этой теме я постараюсь описать свои эксперементы с промышленным протоколом Modbus для локальной сети и RS485 мне удалось как управлять ардуиной с ПЛК так и ардуиной управлять плк и модулями вводы вывода от овена.
позже добавлю еще про ардуино модбус мастер и модуль ввода как slave устройсво
небольшую статеечку окультурить нужно
Подтверждаете стабильность работы библиотеки?
"Измеренные значения не изменяются" - а пробовали через программу ОВЕН Конфигуратор Мх110 посмотерть значения этих каналов? Там изменяются данны? Если да, то можно повесить снифер на СОМ порт и посмотреть какие пакеты обмена идут.
Здравствуйте.
За основу взял библиотеки SimpleModbusMaster.h и SimpleModbusSlave.h. Не "разговаривали" ардуинки по причине битых модулей на max485 (половину отбраковал).
Пробный стенд:
К мастеру подключен дисплей TM1867 - на него должна приходить информация (температура) со слейва. Мастер посылает 1. К слейву подключен ds18b20. Слейв должен получить от мастера число, если это 1 то зажечь светик на ардуинке (13 пин), и посылает мастеру температуру и число (генерация случайным образом от 0 до 9). Мастер выводит температуру на TM1867 и если число от слейва = 1 то зажигает свой светик.
Что имеем: слейв отвечает мастеру, посылает ему случайное число и температуру, мастер это принимает, выводит на экран, мигает светиком. Но слейв информацию от мастера не получает, т.е 1 не приходит от мастера к слейву, соответственно он светиком не моргает.
Help!
В мастере сбор пакетов в loop - чтобы в перспективе больше 30 параметров передавать\получать.
мастер:
слейв:
Библиотеки стабильно работают. Вся работа библиотеки выполняется в фоновом режиме. Ваша программа выполнятся без задержек. Примеры и библиотеки хорошо прокомментированы и интуитивно понятны это позволит вам легко создать свой первый проект с Modbus.
Библиотеки написаны с применением объектно-ориентированного подхода, на языке C не используя C ++. Это облегчает портирование программного обеспечения библиотеки на другие платформы, который поддерживают компилятор C.
позже добавлю еще про ардуино модбус мастер и модуль ввода как slave устройсво
небольшую статеечку окультурить нужно
Организовал обмен - овеновский СПК107 (как мастер) + ардуино уно (как слейв). Библиотека slave RTU. На этой же шине висят два ПР200. Обмен норм, все стабильно. НО замечен такой момент:
#define Slave_ID 1 // Адрес Slave устройсва
пытаюсь переназначить адреса слейвов, при замене вышеуказанного ID ардуина упорно висит на первом адресе. Т.е. ставим 2 или 3 или 16, без разницы - она опрашивается мастером только по адресу слейва 1. В чем причина, кто-нибудь сталкивался? Баг пока не критичный, но как действовать при необходимости подцепить несколько ардуин на один канал?
похоже на то что овеновский мастер дает запрос слейву №1, а если вы его переиминовали то такого нет, ему это не нравится ;) и вводит его в стопар
в том то и прикол, что ID меняешь, заливаешь в ардуину, опрашиваешь по новому адресу - нет ответа. Опрашиваешь по адресу 1, есть связь. Т.е. какой ID ни ставь - адрес у ардуины все-равно 1. Загадка...)
в мастере тоже меняешь ID?
да, конечно! Заливаю в ардуину #define Slave_ID 2;
соответственно:
modbus_configure(&Serial, baud, SERIAL_8E1, Slave_ID, TxEnablePin, HOLDING_REGS_SIZE, holdingRegs);
Мастером опрашиваю слэйв 2 - тишина. Опрашиваю слэйв 1 - идет обмен. Мистика
может компилятор дуру гонит ? попробовать на другомм пк скомпилить
еще можно попробовать указать адрес без переменной Slave_ID, напрямую.
а опрашиваете чем?
пробовал принудительно адрес писать, без Slave_ID. Заливал разными компиляторами, родным ардуиновским и через AtmelStudio. Нет эффекта...) Опрашиваю с СПК107, стандартная процедура, обмен корректный в обе стороны, ардуина бодро жужжит шаговым движком по команде мастера. НО ТОЛЬКО ПО ПЕРВОМУ АДРЕСУ! Странное дело) Буду разбираться дальше. Отпишусь, когда найду в чем прикол.
надо в библиотеку смотреть, может там прписан 1-й адрес
Столкнулся с такой же фигней, только использовал две ардуины (мастер и слэйв), и тоже опрос шел только по первому адресу в независимости от того, какой адрес ставил слэйву.
Поковырялся в библиотеке, разобрался в чем дело)
В примере для Slave есть две строки, задающие параметры обмена:
modbus_configure(&Serial, baud, SERIAL_8E1,Slave_ID, TxEnablePin, HOLDING_REGS_SIZE, holdingRegs);
modbus_update_comms(baud, SERIAL_8E1, 1);
последняя единица - это тоже адрес устройства, автор видимо ставил его принудительно, без переменной.
В такой редакции: modbus_update_comms(baud, SERIAL_8E1, Slave_ID); у меня обмен пошел по всем адресам.
Может кому поможет)
Подскажите, как настроить эту библиотеку с работой через SoftawareSerial?
Приветствую всех.
А никто не пытался портировать это библиотеку под ESP32?
Решено.
Есть кто живой в этой теме? =)
Я ее прочел. Многое понятно но так же не совсем ясно несколько моментов. Вот дупустим пример основанный на бибилиотеке данной.
Сначала суть. Есть готовое устроиства на базе кристала atmega2560. У данноо устроиства 9 дискретных выходов, 9 дискретных входов, 5 аналоговых входов, а так же на борту есть еще 2а реле и так же на плате разведено подключение МК к линии 485. делал я это для своей задачи своеобразной. Теперь решил к этому делую написать прошивку. Сначала хотел делать на библиотеке ModbusRTU, но не зашло че то) Потом почел про эту и вот не задача не понимаю несколько вещей:
1. В данной бибилиотеке если я использую кристал 2560 сколько я могу регистров хранить то используя данную бибилиотеку? (TOTAL_NO_OF_REGISTERS сколько максимуму может быть в данной библиотке)
2. Из вашего опыта как лучше организовать хранение значений с моих 23 портов? (я бы хотел чтобы все значения записывались в цикле в массив и уже оперировались дальше в цикле)
3. И не могли бы вы мне сказать как в данной библиотеки писать биты и байты и читать их? Я просто увидел примеры только в целом с регистрами. Т.е. не так как организованно например в библиотеки ModbusRTU. Может есть еще какой то функционал. Но в описании библиотеки я ниче не понял ибо не сильно разбираюсь в англиском=( Заранее спасибо за советы и ответы.
Можете помочь с библиотекой кое что понять? Вроде понял всме кроме одного=( почему у меня не читаются регистры выше 4го??? скрины ниже. Код простой просто 7 регистров в каждый присваевается значение свое не важно какое. Так вот первые 4е читаются отлично. Выше же откажывается читать выдавая ошибку что типа не верный адресс.
Сколько передал в 37 строке HOLDING_REGS_SIZE, столько и получил.
Не совсем понял((( можете пояснить? Та строка разбивается на:
А типа выше я должен был описать 7 регистров и закрыть их общим названием как я описал IN1 и т.д.?
в enum
уже понял спасибо. Скажите и сколько регистров я могу сделать для кристала 2560меги? 29 всего или больше?
Ребят подскажите как Вы думаете как читать в данной библиотеке сразу два или более регистров 1 пакетом? Т.е. как бы понимаю что функция меняю но где в конце пакета надо указать локальное хранилище данных там что надо регистры через запятаю писат ьили как? Нет примера, не найду. Заранее спасибо
Очень нужна ваша подсказка. В данной библиотеке я так и не понял по инструкции как запросить сразу 7 регистров. ТОчнее не понял как их сохранить в локальное харнилище в массив? можете строчку написать. И второй вопрос про буфер в 29 регистров. Я не понял это имеется ввиду что за раз не может больше 29 запросить? или хранить не может больше 29ти значений. У меня мастер на кристале атмега 2560 но не ардуина а своя плата без загрузчика и т.д. Просто уже две неделе бьюсь. Слейвы сделал работают отчлино! А вот с мастером беда какая то. Три устроиства и желательно сделать три пакета к каждому чтобы не делать 14 пакетов. А как сохранять не ясно.
Заранее спасибо за ответ.
Добрый день, очень нужна ваша помощь по билиотеке Simple Modbus. Написал тестовый скетч, при обрыве связи, попытки обмена прекращаются через заданное число раз, и все. Как получить информацию о том что обмен остановлен? в описании к библиотеке есть упоминание соответствующих переменных но как обращатся к ним, как считать данные?
Цитата:
"Как уже упоминалось, пакет содержит всю информацию, необходимую FSM. Информация и различныесчетчики могут быть доступны пользователю для каждого пакета. Счетчики информации могут использоваться для диагностических целях. Ниже приводится краткое объяснение:
При компиляции выдает ошибку в строке проверки ошибки :
Arduino: 1.8.5 (Windows 7), Плата:"Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"
В чем воопрос как читать ошибки? их количество или в том что у вас ошибка при компиляции?
Я просто чуть в шоке) спрошу так вы сами знаете почему не компилируется? вы понимаете что Вам компилятор написал)???
Вопрос был как читать переменные ошибок ( синтаксис).
Но кажется я нашел решение:
на забугорном сайте пишут- вы можете увидеть полный статус каждого пакета со следующим синтаксисом:
Два дня голову ломал....
Ну как бы вы все верно написали изначально только применили эт овсе не правильно. Такого -> оператора нет))) То что вы щас написали последнее является правильным применением для данной библиотеки.
Я просто чуть в шоке) спрошу так вы сами знаете почему не компилируется? вы понимаете что Вам компилятор написал)???
я просто понял, что ему не нравится строка, в которой я пытался получить значение переменной с ошибками. "ERR = PACKET1->exception_errors;" -синтаксис не верен, спрашивал как правильно написать.
В русскоязычном сегменте интернета я упоминания и примеров не нашел. Может кому пригодится....
Добрый день скажите. Использую в своем проекте библиотеки SimpleModbusSlave и SimpleModbusMaster. Вопрос в данной бибилотеке мастера не постоянно слать заранее подготовленные контструкции. Т.е. чтобы МК какую то часть данных каждый цикл запрашивал и обновлял а то что касается управления чтобы по кнпоке когда надо отправлял запрос. Просто никак не въеду. Заранее спасибо
Скажите есть ли опыть отправлять данные по команде а не в цикле. Я про библиотеку SimpleModbusMaster.
тут есть живые в этой ветке?
вешай на дискретный вход кнопку, отслеживай ее в проге и по условию отправляй команды
после отправки паузу делать, чтобы за одно нажиатие не отправилось больше одной команды за раз
МОжно подробнее? У меня все пашет как бы но смысл в том что библа эта как то не очень работает очень много проходов. Т.е. если я разово запускаю функцию modbus.update то нифига не уходит ничего а если в цикле то все пашет .Как это поправить? Или в чем может быть беда тут?
Ну тут не телепаты сидят, выкладывай свой код, может кто-нибудь и поможет
Суть такая кто работал с данной библиотекой думаю сразу все поймут.
Я в setup делаю ка кобычно предустановку пакетов вот она:
и в loop я делаю просто обмен modbus_update(); Так вот все работает как и надо но есть две проблемы:
1. Работает с задержкой в 3-5 секунд
2. Если делаю отдельно по кнопке modbus_update(); то вообще не срабатывает или срабатывает с 3-10 раза почему? не ясно.
Но интересно то что если я подключаю комп как мастер через 485-USB адаптер то все шустр ои быстро без задержек делается. Вот и не могу понять как решить эти две проблемы