ModbusRTU, ModbusTCP Arduino и OWEN PLC
- Войдите на сайт для отправки комментариев
ModbusRTU, ModbusTCP Arduino и OWEN PLC
В этой теме я постараюсь описать свои эксперементы с промышленным протоколом Modbus для локальной сети и RS485 мне удалось как управлять ардуиной с ПЛК так и ардуиной управлять плк и модулями вводы вывода от овена.
SimpleModbus - Modbus библиотеки для Ардуино, которые позволяют Вам предавать посылки по последовательному интерфейсу с использованием протокола Modbus RTU. Обе библиотеки SimpleModbusMaster и SimpleModbusSlave поддерживают Modbus функции 3 и 16, кроме того, SimpleModbusMaster поддерживают Modbus функции 1, 2, 4 и 15. Передача поддерживает на обеих библиотеках функции 16 и 15. Обе библиотеки имеют похожий интерфейс. Есть всего две необходимых функции modbus_update () и modbus_configure (). Обе библиотеки были проверены промышленном оборудовании: на отечественном оборудовании PLC OWEN и модулях ввода вывода. Дополнительно библиотека SimpleModbusSlave была проверена с тестером Modbus Poll.
Библиотеки стабильно работают. Вся работа библиотеки выполняется в фоновом режиме. Ваша программа выполнятся без задержек. Примеры и библиотеки хорошо прокомментированы и интуитивно понятны это позволит вам легко создать свой первый проект с Modbus.
Библиотеки написаны с применением объектно-ориентированного подхода, на языке C не используя C ++. Это облегчает портирование программного обеспечения библиотеки на другие платформы, который поддерживают компилятор C.
Библиотека мастера RTU
http://alexval2007.ucoz.ru/dowanloads/Modbus/SimpleModbusMasterV2rev2_lib.zip
Библиотека slave RTU
http://alexval2007.ucoz.ru/dowanloads/Modbus/SimpleModbusSlaveV10_lib.zip
Примеры к библиотекам
http://alexval2007.ucoz.ru/dowanloads/Modbus/SimpleModbus_examples.zip
Файлы для плк 110 овен
http://alexval2007.ucoz.ru/dowanloads/Modbus/SimpleModbus_examples.zip
Полное описание библиотеки мастера на английском
http://alexval2007.ucoz.ru/dowanloads/Modbus/SimpleModbusMaster.pdf
Для связи по RS485 я использовал шилд
RS485 Shield для Ардуино. RS485 Shield для Ардуино.
Вот такой шилд я прикупил для своего Ардуино его очень удобно использовать для создания устройств с RS485. Шилд поддерживает управление приёмом передачей в автоматическом и ручном режиме выбор переключателем.
Описание RS485 Shield V1.0
В стандарте RS-485 для передачи и приёма данных используется одна витая пара проводов, иногда сопровождаемая экранирующей оплеткой или общим проводом. Передача данных осуществляется с помощью дифференциальных сигналов.
Разница напряжений между проводниками одной полярности означает логическую единицу, разница другой полярности — ноль.
Особенности
- Питание 5.0 В
- 16 цифровой порт ввода-вывода (в том числе интерфейс I2C)
- 6 аналоговых I/O портов
- Переключатель в режима программирования
- Автоматический / ручной переключатель режима трансивера
- Светодиоды RX TX
- Стандартный интерфейс RS485, мини-интерфейс RS485 (PH2.0) и выводы RS485
- Область для прототипирования
- Кнопка сброса
- Размер 55 x 53 мм
схема шилда http://alexval2007.ucoz.ru/Smart_home/RS485_SCH.jpg
Пример программы для ардуино для работы с шилдом
Sample Code Automatic Transmission Mode /* # This sample codes is for testing the RS485 shiled(automatic transmission mode). # Editor : YouYou # Date : 2013.9.16 # Ver : 0.1 # Product: RS485 shield # SKU : DFR0259 */ int led = 13; void setup() { Serial.begin(9600); pinMode(led,OUTPUT); } void loop() { int temp; if(Serial.available()) { temp=Serial.read(); if(temp=='V'){ digitalWrite(led,1-digitalRead(led)); Serial.println("OK"); } } } Manual Transmission Mode /* # This sample codes is for testing the RS485 shiled(manual transmission mode). # EN=2; # Editor : YouYou # Date : 2013.9.16 # Ver : 0.1 # Product: RS485 shield # SKU : DFR0259 */ int led = 13; int EN = 2; //Definition RS485 shield enable terminal (the 2nd digital IO ports), //high for the sending state, the low level of receiving state void setup() { Serial.begin(9600); pinMode(led,OUTPUT); pinMode(EN,OUTPUT); } void loop() { int temp; digitalWrite(EN,LOW); //Enable low, RS485 shield waiting to receive data if(Serial.available()) { temp=Serial.read(); if(temp=='V') { digitalWrite(led,1-digitalRead(led)); digitalWrite(EN,HIGH); //Enable high, RS485 shield waiting to transmit data Serial.println("OK"); delay(10); //Delay for some time, waiting for data transmitted } } }
купить можно на Amperka.ru или Ebey
Пример работы с библиотекой мастера RTU
/* Пример будет использовать packet1, чтобы считать регистр из адреса 0 (значение adc ch0) от arduino раба (id=1). Это будет тогда использовать это значение, чтобы скорректировать яркость из вовлеченного контакт 9 использований PWM. Это будет тогда использовать packet2, чтобы записать регистр (его собственное значение adc ch0), чтобы адресоваться 1 на arduino рабе (id=1) корректировка яркости вовлеченного контакт 9 использований PWM. */ #include <SimpleModbusMaster.h> //////////////////// Макроопределения портов и настройки программы /////////////////// #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 4 // Масив пакетов modbus // Для добавления новых пакетов просто добавте ихсюда // сколько вам нужно. enum { PACKET1, PACKET2, PACKET3, PACKET4, TOTAL_NO_OF_PACKETS // эту строку неменять }; // Масив пакетов модбус 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); // чтение данных 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_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs); pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT); } // конец void setup() void loop() { modbus_update(); // запуск обмена по Modbus // если пришло 255 зажигаем светодиод analogWrite(LED1, regs[0]>>2); // чтение данных slave-master (slave адрес 1, регистр 0) // (ограничеть количесво бит данных числом 255), прочитаное значение выводим шимом на аналоговый выход pin9 if (regs[1] == 255){digitalWrite(LED2, HIGH);}else{digitalWrite(LED2, LOW);} // чтение данных slave-master (slave адрес 1, регистр 1) regs[2] = 255; // запись данных master-slave (slave адрес 1, регистр 2), запись константы regs[3] = analogRead(0); // запись данных master-slave (slave адрес 1, регистр 3), значение из аналогового входа 0 } // конец void loop()
Пример работы с библиотекой SLAVE RTU
/* SimpleModbusSlaveV10 supports function 3, 6 и 16. serial ring buffer 64 bytes or 32 registers. function 3 58 bytes or 29 registers. function 16 54 bytes or 27 registers. */ #include <SimpleModbusSlave.h> //////////////////// Макроопределения портов и настройки программы /////////////////// #define TxEnablePin 2 // Tx/Rx пин RS485 #define baud 9600 // скоростьобмена по последовательному интерфейсу. (UART) #define timeout 1000 // Длительность ожидание ответа (таймаут modbus) #define polling 200 // скорость опроса по modbus #define retry_count 10 // количесво запросов modbus до ошибки и останова обмена #define Slave_ID 1 // Адрес Slave устройсва #define LED1 13 // светодиод 1 #define LED2 9 // светодиод 2 const int buttonPin = 3; // номер входа, подключенный к кнопке // переменные int buttonState = 0; // переменная для хранения состояния кнопки //////////////// Регистры вашего Slave /////////////////// enum { //Просто добавьте или удалите регистры. Первый регистр начинается по адресу 0 slave_to_master_val_1, // с адресом массива 0 slave_to_master_val_2, // с адресом массива 1 master_to_slave_val_1, // с адресом массива 2 master_to_slave_val_2, // с адресом массива 3 HOLDING_REGS_SIZE // Это не удалять размер массива HOLDING_REGS. //общее количество регистров для функции 3 и 16 разделяет тотже самый массив регистров //т.е. то же самое адресное пространство }; unsigned int holdingRegs[HOLDING_REGS_SIZE]; // функции 3 и 16 массив регистров //////////////////////////////////////////////////////////// void setup() { // инициализируем пин, подключенный к кнопке, как вход pinMode(buttonPin, INPUT); /* parameters(HardwareSerial* SerialPort,long baudrate,unsigned char byteFormat,unsigned char ID, unsigned char transmit enable pin,unsigned int holding registers size,unsigned int* holding register array) SERIAL_8N2: 1 start bit, 8 data bits, 2 stop bits SERIAL_8E1: 1 start bit, 8 data bits, 1 Even parity bit, 1 stop bit SERIAL_8O1: 1 start bit, 8 data bits, 1 Odd parity bit, 1 stop bit SERIAL_8N1 option */ modbus_configure(&Serial, baud, SERIAL_8N1, Slave_ID, TxEnablePin, HOLDING_REGS_SIZE, holdingRegs); modbus_update_comms(baud, SERIAL_8N1, 1); pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT); }// конец void setup() void loop() { int temp; // считываем значения с входа кнопки buttonState = digitalRead(buttonPin); // проверяем нажата ли кнопка // если нажата, то buttonState будет HIGH: if (buttonState == HIGH){temp=255;}else{temp=0;} //if (temp == 255){digitalWrite(LED1, HIGH);}else{digitalWrite(LED1, LOW);} modbus_update(); // запуск обмена по Modbus holdingRegs[slave_to_master_val_1] = analogRead(A0); // запись данных slave-master // (регистр 0), значение из аналогового входа 0. holdingRegs[slave_to_master_val_2] = temp; // запись данных slave-master // (регистр 1), запись значения переменной temp. по нажатию кнопки. // чтение данных master-slave (регистр 2) if (holdingRegs[master_to_slave_val_1] == 255){digitalWrite(LED1, HIGH);}else{digitalWrite(LED1, LOW);} // если пришло 255 зажигаем светодиод analogWrite(LED2, holdingRegs[master_to_slave_val_2]>>2); // чтение данных master-slave (регистр 3) // (ограничеть количесво бит данных числом 255), прочитаное значение выводим шимом на аналоговый выход pin9 }// конец void loop() /* Использование enum инструкции не обязательно. Вы могли установить допустимый максимум размер для holdinRegs [], определяя HOLDING_REGS_SIZE, используя константу и затем доступ holdingRegs[] обращением по "Index" массива. holdingRegs[0] = analogRead(A0); analogWrite(LED, holdingRegs[1]/4); holdingRegs[ADC_VAL] = 250; // данные об обновлении, которые будут прочитаны владельцем, чтобы приспособить PWM ШИМ analogWrite(LED, holdingRegs[PWM_VAL]>>2); // ограничьте АЦП arduino значением 255 holdingRegs[ADC_VAL] = holdingRegs[PWM_VAL]; */
Вот ссылка на библиотеку Modbus TCP я ее кстати прокоментировал но версию с коментариями позже найду и выложу пока в оригенале
http://alexval2007.ucoz.ru/dowanloads/Modbus/MudbusTCP.zip
пример
#include <SPI.h> #include <Ethernet.h> #include "Mudbus.h" Mudbus Mb; //#define DEBUG uint8_t temp; //Function codes 1(read coils), 3(read registers), 5(write coil), 6(write register) //signed int Mb.R[0 to 125] and bool Mb.C[0 to 128] MB_N_R MB_N_C //Port 502 (defined in Mudbus.h) MB_PORT void setup() { uint8_t mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x51, 0x06 }; uint8_t ip[] = { 192, 168, 1, 10 }; uint8_t gateway[] = { 192, 168, 1, 2 }; uint8_t subnet[] = { 255, 255, 255, 0 }; Ethernet.begin(mac, ip, gateway, subnet); //Avoid pins 4,10,11,12,13 when using ethernet shield delay(1000); Serial.begin(9600); pinMode(8, OUTPUT); } void loop() { Mb.Run(); Mb.R[0] = 250; Mb.R[1] = 251; Mb.R[2] = 252; Mb.R[3] = 253; Mb.R[4] = 254; Mb.R[5] = 255; if (Mb.Fc_rtu == 3) { // Serial.print(Mb.Message_length_rtu, DEC); // Message length длина посылки в байтах Serial.print(" "); Serial.print(Mb.Slave_rtu, DEC); // Slave number Ид номер Слейв устройсва Serial.print(" "); Serial.print(Mb.Start_rtu, DEC); // Start address адресc регистра Serial.print(" "); Serial.print(Mb.Fc_rtu, DEC); // Function code код функции модбас Serial.print(" "); Serial.print(Mb.Length_rtu, DEC); // Length количесво опрашиваемых регистров Serial.print(" "); Serial.println(); // Mb.Message_length_rtu; // Message length длина посылки в байтах // Mb.Slave_rtu; // Ид номер Слейв устройсва // Mb.Start_rtu; // Start address адресc Стартового регистра // Mb.Fc_rtu; // код функции модбус // Mb.Length_rtu; // Length количесво опрашиваемых регистров } Mb.Fc_rtu = 0; }
позже добавлю еще про ардуино модбус мастер и модуль ввода как slave устройсво
небольшую статеечку окультурить нужно
Спасибо, уважаемый! С удовольствием будем пробовать! Хорошо когда находишь немного времени для того чтобы сделать когото чуточку умнее! :) Еще раз спасибо!
Спасибо большое, буду разбираться!!
Скажите, а что должно быть в программе на стороне ПЛК для обмена данными по Modbus RTU? Как обратиться к определенному регистру, например считать состояние дискретных выводов? У меня ПЛК 63, я правильно понимаю, что он может быть только slave и мне нужно использовать библиотеку modbus-master?
Если поделитесь примером программы для ПЛК и соответствующим скетчем для Ардуино, буду безмерно благодарен.
Заранее спасибо!
В ПЛК если он мастер мы выбираем слейв адрес устройства функцию в основном 3ю чтение и 16ю запись а также номер регистра в нашем случае в ардуино их до 29 помещается к плк63 модбус прикручивать недоводилось делал на нем проекты без сети. Надо читать знаю что он неимеет конфигуратора модбус и нужна библиотека от овена примеры для ардуино подойдут выложенные выше. Своего 63 нет только 100, 110 и спк107 так что попробовать неначем. Если же он может быть только слейвом хотя я неуверен то тогда в ардуино код мастера и настраиваем функции передачи приёма скорость обмена формат данных например 8N1 тоже и в ПЛК и с ардуино обращаемся к регистрам ПЛК по номерам от 0 до 29 и создать надо конечно эти регистры в ПЛК. Я пример выкладывал для плк110 но там в конфигураторе будет время выложу на библиотеке но позже приболел я
Вот тут как раз у меня первый затык. Я не могу задать номера регистров с 0 по 29, у меня адресное простанство начинается с 82 (см скрин)
И еще вопрос по коду мастера.
Не могу разобраться в этой функцией, READ_HOLDING_REGISTERS - это как раз 3-я функция модбас, следующий парамерт - адрес регистра, это тот адрес, который я настроил в ПЛК? И что такое локальный адрес регистра, по описанию не понятно, и почему в примере он везде нулевой?
Заранее спасибо за ответы
ЗЫ. Выздоравливайте!!!
Спасибо
Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
Итак разберемся Пакет это пакет обмена в нем может быть от 1 до нескольких регистров.
SLAVE адрес - это адрес слейва от 1 до 250
Функция это то что мы делаем READ_HOLDING_REGISTERS это 3я чтение, PRESET_MULTIPLE_REGISTERS 16я запись.
адрес регистра это порядковый номер регистра в слейве начиная с 0 если слейв на ардуино то он будет от 0 до 29 в плк или модуле может быть какой угодно хоть 54 хоть 154 мастер прочитает этот номер непроблема но всего запрашиваемых регистров может быть 30шт не больше особености приёмного буфера ардуино.
Далее идет количесво запрашиваемых регистров например мы запрашиваем в одном пакете у первого слейва на чтение по 0 адресу 1 регистр и сохраняем его в локальный регистр по адресу 0.
Локальный регистр это регистры хранения в памяти мастера тоесть масив регистров с адресами от 0 до 29
30 регистров. почему везде 0 да просто так это для примера и мненехотелось заморачиватся и раскладывать по разным регистрам в примере мало регистров использовано потому использовал только 0й локальный регистр для хранения принятой инфы.
продолжим про количесво регистров если я читаю с нулевого регистра у слейва то могу указать сколько мне нужно прочитать регитсров 1 или 10 ил 30. Столько он начиная с начального адреса и считает.
Ну вот както так.
Ну а поповоду что у вас номера регистров большие так это неважно пишите ваши главно читать не более 30 регистров как и писать. ВСЕГО 30 это важно иначе работать не будет всетаки это ардуино а не плк
Спасибо за комментарии. На выходных руки дошли, начал пробывать. К сожалению сходу не получилось.
У меня ардуино - мастер, ПЛК- слейв, читаю регистры ПЛК с ардуино, но возвращает все время одни нули. Такое впечатление, что мне надо еще ПЛК как-то конфигурить, чтобы он стал модбас-слейвом. У Вас на 110 я так понимаю специальный конфигуратор есть, а на 63 ничего похожего нет, и примеров, в котором ПЛК-слейв тоже нет. НАписал в ТП овена, может помогут.
Со второй попытки все удалось, оказывается есть одна хитрость, ПЛК нужно отключать от Кодесиса и перегружать, только тогда он начинает опрашивать 485 порт. Проверил, корректно работают и 3 и 16 функции Модбаса, все конфигурационный параметры читаются и изменяются.
Еще раз спасибо!!!
Добрый день коллеги! Очень полезная и интересная статья тут описана, почитав ее у меня возник вопрос:
modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0);
Процедура которая формирует пакет на отправку, в ней указывается адрес регистра который нужно прочитать. В какой системе исчисления должен быть указан адрес? в десятичной или шестнадцатиричной?
Это инструкция по Autonics TM4 (Терморегулятор), смотрим 20 страницу, описание регистров и функиций. Меня интересует чтение входных регистров (функция 04 Read Input Register). В инструкции указан адрес 301019 (03FA) входного 4-го канала, где подключен датчик температуры. Я хочу прочитать показания этого датчика. Если смотреть адрес 03FA то это 1018 (дес.сист). Если же брать весь номер 301019 - то это значение выходит за границы целочисленной переменной.... Толи я че не понимаю, толи лыжи не едут )))) Помогите разобраться.
https://www.instrumart.com/assets/Autonics-TM-commmanual.pdf
P.S. я написал программу на Delphi которая корректно опрашивает аутоникс через преобразователь порта Овен АС4. Формат отправленного пакета выглядит как набор следующих бит: 04 04 03FA 0001 CR CR. Дак вот хочу теперь чтобы без компа все работало - через ардуино, чтобы она всем управляла сама. Получила информацию от датчика, послала комманду вкл/выкл нагрев/охлаждение...
....
Еще хочу сказать что я не силен в С++, я больше delphi(pascal), прошу сильно не бить за глупые вопросы))
Добрый день коллеги! Очень полезная и интересная статья тут описана, почитав ее у меня возник вопрос:
modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0);
Процедура которая формирует пакет на отправку, в ней указывается адрес регистра который нужно прочитать. В какой системе исчисления должен быть указан адрес? в десятичной или шестнадцатиричной?
Я пока в этой теме темный, но есть профессиональный интерес, накачал кучу софта и мануалов раных, заказал железки и читаю уже несколько дней по этой теме. В первом посте, автор привел все необходимые данные. По ссылке есть описание библиотеки, там описаны полностью все типы и параметры. Конкретно эта строка разобрана на 9 странице.
В ДЕСЯТИЧНОЙ СИСТЕМЕ НАСКОЛЬКО Я ПОМНЮ ТОЕСТЬ 1018 ПОПРОБОВАТЬ СЕЙЧАС НЕМОГУ НА РАБОТЕ ЗАВАЛ И ДОМАШНИЙ НОУТ СО ВСЕМ СОФТОМ В РЕМОНТЕ
Ура товарищи!!! ЗАРАБОТАЛО!!! ))))))))) Как мастер все гуд! Теперь надо изучить слейв )) Спасибо за помощь!
Есть еще вопрос )) а можно совместить две библиотеки в одном скрейче? SimpleModbusSlave.h и SimpleModbusMaster.h ??
У них много общего ))) но как они будут дружить интересно...
НЕЗНАЮ ПРОБУЙТЕ ЕСЛИ ВДРУГ СИЛЬНО НУЖНО НЕУВЕРНЕ ЧТО ПОЛУЧИТСЯ БЕЗ СКРЕЩИВАНИЯ БИБЛИОТЕК МЕЖДУ СОБОЙ ГЕМОРОЙНОЕ ЗАНЯТИ КОГДА СОЕДИНЯЛ МОДБУС ТСП С МОДБУС РТУ НАМУЧАЛСЯ
Подскажите, эт библиотеки можно использовать только с ардуино или любым другим микроконтроллером AVR ?
В какой среде разработки они могу использоваться, в любой где есть си-комилятор ? CodeVisionAVR будет их понимать?
спасбо
к сожелению эти библиотеки расчитаны на ардуино но если их взятся и переписать то они будут работать и с другими контролерами AVR. Библиотек почти вся написана на си но коегде встречаются вещи на с++ которые надо заменить аналогом на чистом си и некоторые вещи самой ардуино например работа с последоветельным портом и управление пином приём передача контролера это все можно заменить и будет вам щастье но работы будет много. Я сам хотел портировать её на нормальный си для всех авр но нехватает постоянно времени
а в чем отличие контроллеров ардуино от других AVR ? если я не ошибаюсь они же использую теже самые чипы Атмеги или я ошибаюсь? То есть может быть можно использовать Среду разработки ардуино для обычных АВР ?
Если нет, то какой самый дешевый контроллер ардуино потянет обмен по rs ?
вот это оно ? http://ru.aliexpress.com/item/Best-prices-high-quality-UNO-R3-MEGA328P-for-Arduino-UNO-R3-NO-USB-CABLE/32651758642.html?spm=2114.30010708.3.19.nVmyg4&ws_ab_test=searchweb201556_7,searchweb201602_4_10039_10037_10033_507_10032_10020_10017_10021_10022_10009_10008_10018_10019_101,searchweb201603_3&btsid=0422503a-ef22-4a33-8ee7-bd0339db6f55
а в чем отличие контроллеров ардуино от других AVR ? если я не ошибаюсь они же использую теже самые чипы Атмеги или я ошибаюсь? То есть может быть можно использовать Среду разработки ардуино для обычных АВР ?
Если нет, то какой самый дешевый контроллер ардуино потянет обмен по rs ?
вот это оно ? http://ru.aliexpress.com/item/Best-prices-high-quality-UNO-R3-MEGA328P-for-Arduino-UNO-R3-NO-USB-CABLE/32651758642.html?spm=2114.30010708.3.19.nVmyg4&ws_ab_test=searchweb201556_7,searchweb201602_4_10039_10037_10033_507_10032_10020_10017_10021_10022_10009_10008_10018_10019_101,searchweb201603_3&btsid=0422503a-ef22-4a33-8ee7-bd0339db6f55
я сейчас делаю на NANO (по 120 руб + 60 модуль RS485), в принцепе очень даже работает (только меня сам ModBus не устроил, по этому дописываю свой протокол), наверно скоро выложу и схемы и программы...
Микроконтролеры в принципе теже отличие в том что библиотека написана под среду разработки ардуино в ардуино активно используется с++ в обычных компиляторах это просто Си
Atmega 8 или atmega168 если записать бутлайдер ардуино в контролер то он будет поинимать загрузку скетча или програматором самим записать hex файл в контролер полученный в ардуино
так это то что мн нужно :)
а можете поделться примером кода для работы с modbus ?
а, хотя выше же есть примеры, разберусь
alexval2007, сможешь помочь?
http://arduino.ru/forum/ishchu-ispolnitelya/ishchu-nastavnika-arduino-co...
А можно пример как опрашивать несколько устройств?
Добрый день.
Помогите плиз. По modbus RTU на запрос получаю (hex 42 8c) 17036. А в OPC сервере, пишет что переменная равна 700.
hex ответ прибора на arduino и от OPC сервера одинаковый.
Не пойму к какому типу переменной надо int конвертировать?!
По modbus RTU на запрос получаю (hex 42 8c) 17036. А в OPC сервере, пишет что переменная равна 700.
Можно подробнее весь пакет запроса и ответа
Можно:
А в ардуино в функции setup() можно использовать условия?. Допустим у меня два слейв-устройства, и в зависимости от переключателя на дискретном входе выбирать тот или иной modbus_construct()..
или просто тупо сделать два modbus_construct, просто один будет возвращать ошибку тогда.
Кстати, есть ли в библиотеке обработка ошибок, хотя бы если нет ответа от устройства(адрес другой например)? А то будешь получать нули и не знать что ты ничего не читаешь на самом деле..
в описании есть только это:
As mentioned a packet contains all the information needed by the FSM. The information and various counters can be accessed by the user for each packet. The information counters can be used for diagnostic purposes. A brief explanation follows:
requests - contains the total requests to a slave
successful_requests - contains the total successful requests
failed_requests - general frame errors, checksum failures and buffer failures. These will result in a timeout.
retries - contains the number of retries
exception_errors - contains the specific modbus exception response count. These are normally illegal function, illegal address, illegal data value or a miscellaneous error response.
And finally there is a variable called "connection" that at any given moment contains the current connection status of the packet. If true then the connection is active. If false then communication will be stopped on this packet until the programmer sets the connection variable to true explicitly
а примеров нет, или выше это и есть названия переменных, которые можно читать..?
..
взято из библиотеки, то есть обращатсья к счетчикам наверное так: Packet.failed_requests или packet->failed_requests
у кого рабочие проекты есть, проверьте плз на обрыв связи, будет ли переменная connection меняться
Можно:
Так же нашел установку в OPC сервере = Порядок байт - Старшим байтом вперед.
Помогите пожалуйста преобразовать данные в IEEE754...
кстати, а можно юзать монитор последовательного порта в Arduino IDE для моинторинга получаемых данных по модбас, или это один и тот же порт работает на плате?
кстати, а можно юзать монитор последовательного порта в Arduino IDE для моинторинга получаемых данных по модбас, или это один и тот же порт работает на плате?
#include <SoftwareSerial.h> можно использовать для консоли отслеживания данных.
Или по внешнему 485-usb через serial port monitor
и еще вопрос - что за слэйв устройство у вас? Хочу его даташиту почитать
накопал )) http://floatingpoint.ru/value/float/41FBE2F8 гляди как это высчитывается
байты только местами поменять = 41FB E2F8
читаем здесь https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%BE%D0%B...
Столкнулся с проблемой - под win10 версия Ардуино 1.6.10 ругается на библиотеки, соответственно не компилирует
версия 1.6.5 под win XP на библиотеки не ругается, но при компиляции валится с ошибкой.
Подскажите в какой версии нормально работает?
поблему решил подменой файла ld.exe с версии 1.0.6
накопал )) http://floatingpoint.ru/value/float/41FBE2F8 гляди как это высчитывается
байты только местами поменять = 41FB E2F8
Да спасибо, все получилось :)
Здравствуйте! Изучаю вашу тему -и она мне очень интересна! Но подскажите пожалуйста к какким пинам на ардуино подключать RS485? (имею в виду А и В).
Все вроде пересмотрел но в скетчах так и не понял как конфигурировать? За ранее спасибо всем,кто откликнется!
pin0 pin1 и не напрямую а через микросхему max485
да спасибо! понял что на rx и tx
Еще подскажите пожалуйста! можно ли значения 4 шт переменных хранить как пишут в 0 локальном адресе?
шестой пункт пакета
Кому еще интересно по стандарту IEEE754 почитать (как преобразовывать и хранить)- нашел замечательную подробную статью:
http://www.softelectro.ru/ieee754.html
Насколько я помню 1 локальный адрес одна переменнная
Задам еще раз свой вопрос, раз в теме оживление.
Не пойму как опрашивать несколько устройств, кто нибудь может кинуть живой пример?
Задам еще раз свой вопрос, раз в теме оживление.
Не пойму как опрашивать несколько устройств, кто нибудь может кинуть живой пример?
я так понял что просто задавать нужные адреса в конструкторе
modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0);
Но мне бы например хотелось выбирать нужный адрес по кнопке прикрученой к дискретному входу, то есть перебирать например список. но как это сделать - хз, то есть как бы программно выбирать нужный мне адрес допустим из заданных 4-х.
Можно опрашивать только все сразу получается, но что если один или несколько при этом будут недоступны, как поведет себя программа - пока не проверял. хотя проверить не сложно вобщем-то
#define retry_count 10 - этот параметр определяет количество неудачных опросов modbus регистра. После 10 неудач, перестает его опрашивать, сброс через ресет.
Решил сделать на базе ардуино и дисплея 128х128 мастера по RS 485. Чтобы опрашивать устройство .стандарт протокола оставлю 8N1 и скорость стандартную 9600 ,она у всех I/O модулей по умолчанию почти. А на экране задавать регистр переменной и считывать . Думаю многим будет интересно! Будет некий пробник по RS485. Если кому интересно вечером выложу скетч-он пока сыроват(в программировании не так силен) и даже не проверял,но может совместными усилиями доведем до ума
тоже посещали мысли сделать на работу похожий тестер ток заточный на опрос и настройку конкретных устройсв
Задам еще раз свой вопрос, раз в теме оживление.
Не пойму как опрашивать несколько устройств, кто нибудь может кинуть живой пример?
я так понял что просто задавать нужные адреса в конструкторе
modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0);
Но мне бы например хотелось выбирать нужный адрес по кнопке прикрученой к дискретному входу, то есть перебирать например список. но как это сделать - хз, то есть как бы программно выбирать нужный мне адрес допустим из заданных 4-х.
Можно опрашивать только все сразу получается, но что если один или несколько при этом будут недоступны, как поведет себя программа - пока не проверял. хотя проверить не сложно вобщем-то
А получится ли менять через переменную? Пока не могу попробовать..
Но насколько я понимаю функция setup() выполняется только раз, при старте программы. То есть конструктор задается в начале, а потом лишь обновляется
А если вынуть из сетапа и основной цикл поместить и через условие если нажата кнопка #1 тогда адрес 2 а если нажата кнопка $2 то адрес 8 и тп и вобще пробовать надо если нет под рукой железок поставте протеус