Помогите собрать шлюз для MD. Mqqt<->modbus rtu
Модератор: immortal
-
- Сообщения: 15
- Зарегистрирован: Пн фев 26, 2018 9:51 pm
- Благодарил (а): 9 раз
- Поблагодарили: 0
Помогите собрать шлюз для MD. Mqqt<->modbus rtu
Помогите собрать шлюз для MD. Mqqt<->modbus rtu
Можно на компонентах "ардуино". Или что то готовое. Пересмотрел кучу информации в Интернете, не могу собрать в голове все "до кучи".
Понял что нужно Arduino UNO + w5100 щит (это есть в наличии). Дальше не понимаю, что делать. Каким образом линия rs 485 подключится к Ардуино.
Можно на компонентах "ардуино". Или что то готовое. Пересмотрел кучу информации в Интернете, не могу собрать в голове все "до кучи".
Понял что нужно Arduino UNO + w5100 щит (это есть в наличии). Дальше не понимаю, что делать. Каким образом линия rs 485 подключится к Ардуино.
- tarasfrompir
- Сообщения: 3216
- Зарегистрирован: Ср мар 02, 2016 8:18 pm
- Откуда: Украина Пирятин
- Благодарил (а): 223 раза
- Поблагодарили: 816 раз
Re: Помогите собрать шлюз для MD. Mqqt<->modbus rtu
Ну для этого надо преобразователь rs 485 to rs 232 а дальше это как то из дуйки дуть на мажорика... А не проще обычный преобразователь рс 485 то юсб на сервак зацепить ?
Спасибо нам ПОМОЖЕТ..!
-
- Сообщения: 15
- Зарегистрирован: Пн фев 26, 2018 9:51 pm
- Благодарил (а): 9 раз
- Поблагодарили: 0
Re: Помогите собрать шлюз для MD. Mqqt<->modbus rtu
Можно напрямую в rapsberry usb вставить? Мне кажется usb не надежно.
- tarasfrompir
- Сообщения: 3216
- Зарегистрирован: Ср мар 02, 2016 8:18 pm
- Откуда: Украина Пирятин
- Благодарил (а): 223 раза
- Поблагодарили: 816 раз
Re: Помогите собрать шлюз для MD. Mqqt<->modbus rtu
А ты хоть так хоть так получиш данные через юсб хоть с дуньки а хоть с конвертера.
Сунь в распбери - хотя где то здесь читал что тут не все так гладко с линуксом. Вроде не всегда дрова ставятся... Я купил месяц назад но до испытаний ещё не дошёл... всегда так
Сунь в распбери - хотя где то здесь читал что тут не все так гладко с линуксом. Вроде не всегда дрова ставятся... Я купил месяц назад но до испытаний ещё не дошёл... всегда так
Спасибо нам ПОМОЖЕТ..!
- blackangel
- Сообщения: 148
- Зарегистрирован: Пт окт 21, 2016 2:00 pm
- Благодарил (а): 31 раз
- Поблагодарили: 13 раз
Re: Помогите собрать шлюз для MD. Mqqt<->modbus rtu
У меня система в квартире работает на модбасе (что то на Ардуино, что то на ПЛК delta), ну и визуализация на RPi MD. Но у меня есть ещё замечательная штука, панель оператора weintek на ней тоже визуализация и самое главное она же шлюз с modbas rtu на modbas tcp. Наверное посоветую тоже поискать шлюз с rtu на tcp так надежнее и правильнее.смотря конечно на чем у вас MD, если на ПК то можно покурить тему скада, и сделать программный шлюз на ПК.
-
- Сообщения: 52
- Зарегистрирован: Пт июн 09, 2017 8:39 pm
- Благодарил (а): 4 раза
- Поблагодарили: 1 раз
Re: Помогите собрать шлюз для MD. Mqqt<->modbus rtu
СпойлерПоказать
Код: Выделить всё
* avp ot 11/01/2018 02:54
*/
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>
#include <SoftwareSerial.h> // Modbus RTU pins D7(13),D8(15)
#include <ModbusMaster.h>
#define SUBSCRIBETOPIC "/modbusDetscie/termostat/#" // топик на который подписываемся
#define PUBLISHTOPIC1 "/modbusDetscie/termostat/status" // первый публикуемый топик значения 90/165 включение/отключения термостата
#define PUBLISHTOPIC2 "/modbusDetscie/termostat/taimer" // публикуемый топик значения 0/1 включение/отключения термостата в ручную или по таймеру
#define PUBLISHTOPIC3 "/modbusDetscie/termostat/tempDatchkPol" // публикуемый топик внешний датчик температуры пол
#define PUBLISHTOPIC4 "/modbusDetscie/termostat/tempDatchkWnech" // публикуемый топик температура в помещении
#define PUBLISHTOPIC5 "/modbusDetscie/termostat/tempUstan" // публикуемый топик температура установленная на термостате умножить на 2
#define PUBLISHTOPIC6 "/modbusDetscie/termostat/timeM" // публикуемый топик время в минутах на термостате
#define PUBLISHTOPIC7 "/modbusDetscie/termostat/timeH" // публикуемый топик время в часах на термостате
#define PUBLISHTOPIC8 "/modbusDetscie/termostat/DniNedeli" // публикуемый топик день недели с 1 до 7
#define PUBLISHTOPIC9 "/modbusDetscie/termostat/send_interval" // публикуемый топик интервал отправки данных
#define IDDEVAIS 1 // Адрес MODBUS девайса
#define COLTOPIC 8 // Кол-во элементов для чтения и записи/передаваемых и принемаемых топиков
#define MAX485_DE_RE 12
//#define BUFFER_SIZE 120
WiFiClient espClient;
PubSubClient client_MQTT (espClient);
SoftwareSerial swSer(13, 15, false, 256);
//SoftwareSerial swSer(13, 15);
// Instantiate ModbusMaster object as slave ID 1
ModbusMaster node;
const char* ssid = "Network_Bel";
const char* password = "123456789";
const char* mqtt_server = "192.168.1.80"; /// example 192.168.0.19
int mqtt_port = 1883;
unsigned int tdelay = 2 ; /// delay
String Holding_to_MQTT[COLTOPIC];
String MQTT_to_Holding[COLTOPIC]; // Array recepcion valores MQTT // Array reception MQTT values
unsigned int send_interval = 100; //интервал отправки показаний на сервер по-умолчанию 100 секунд
unsigned long last_time = 0; //текущее время для таймера
unsigned long last_time_pyat = 0; //текущее время для таймера
unsigned int adres0Status; // переменная для считывания данных статуса
unsigned int adres0Status2; // переменная для сравнения данных статуса
unsigned int adres4Val;
unsigned int adres5Val;
unsigned int adres6Val;
unsigned int adres7Val;
//bool val0adres;
bool time0,time1,time2,time3,time4,time5,time6,time7;
void preTransmission()
{
digitalWrite(MAX485_DE_RE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_DE_RE, 0);
}
/*
*
* Funcion que realiza la reconexion de cliente MQTT
* Function that performs MQTT client reconnection
*
* enable/habilita client_MQTT.subscribe("MQTT_Holding_Array");
*/
void reconnect(void)
{
// Loop until we're reconnected // Bucle hasta que se vuelva a conectar
while (!client_MQTT.connected()) {
if (client_MQTT.connect("ESP8266ModbusDetscie")) {
Serial.println("MQTT Online");
//// Topico para recibir Holding Registers desde MQTT // Topic to receive Holding Registers from MQTT --- return data in callback funtion
client_MQTT.subscribe(SUBSCRIBETOPIC);
} else {
//Serial.print("failed, rc=");
//Serial.print(client_MQTT.state());
}
}
}
void callback(char* topic, byte* payload, unsigned int length)
{
for (int i = 0; i < COLTOPIC; i++) {MQTT_to_Holding[i]="";} //limpia cadenas recibidas // Cleans received strings
//преобразуем тему(topic) и значение (payload) в строку
payload[length] = '\0';
String strTopic = String(topic);
String strPayload = String((char*)payload);
unsigned int tmp = strPayload.toInt();
//Исследуем что "прилетело" от сервера по подписке:
if(strTopic == PUBLISHTOPIC1){ // значения 90/165 включение/отключения термостата
if(tmp == 90 || tmp == 165){
MQTT_to_Holding[0] += String((char*)payload); // адрес 40001
}
}
else if(strTopic == PUBLISHTOPIC5){ // публикуемый топик температура установленная на термостате умножить на 2
if(tmp > 20 && tmp < 64){
MQTT_to_Holding[4] += String((char*)payload); // адрес 40005
}
}
else if(strTopic == PUBLISHTOPIC6){ // публикуемый топик время в минутах на термостате
if(tmp > 0 && tmp < 60){
MQTT_to_Holding[5] += String((char*)payload); // адрес 40006
}
}
else if(strTopic == PUBLISHTOPIC7){ // публикуемый топик время в часах на термостате
if(tmp >= 0 && tmp < 24){
MQTT_to_Holding[6] += String((char*)payload); // адрес 40007
}
}
else if(strTopic == PUBLISHTOPIC8){ // публикуемый топик день недели с 1 до 7 на термостате
if(tmp > 0 && tmp < 8){
MQTT_to_Holding[7] += String((char*)payload); // адрес 40008
}
}
else if(strTopic == PUBLISHTOPIC9){ //Изменение интервала опроса
if(tmp == 0) {
send_interval = 100;
}else{ send_interval = strPayload.toInt();}
}
//Serial.print("topic [");
//Serial.print(topic);
//Serial.print("-");
//Serial.print(tmp);
//Serial.println("] ");
//Serial.println(chipId);
}
void loopPublishMQTTclientRegistr0(void) // функция обработки 0 регистра статус
{
bool to_MQTT0 = 0;
bool to_TIME0 = 0;
char buf0[10];
if(millis() > (last_time_pyat + 20*1000)){ // Прочитываем регистер каждые 5 секунд на предмет изменений статуса
node.readHoldingRegisters(0, 1); // Адрес регистра 40001, Кол-во элементов 1
adres0Status = String(node.getResponseBuffer(0)).toInt();
node.clearResponseBuffer(); /// Limpiar buffer modbus RTU /// Clean modbus RTU buffer
if(adres0Status != adres0Status2){
adres0Status2 = adres0Status;
to_TIME0 = 1;
}
last_time_pyat = millis();
}
if(MQTT_to_Holding[0].toInt() == 90 || MQTT_to_Holding[0].toInt() == 165){
if(adres0Status != MQTT_to_Holding[0].toInt()){
node.writeSingleRegister(0, MQTT_to_Holding[0].toInt() );
delay(10);
to_MQTT0 = 1;
}
}
if(time0 || to_MQTT0 || to_TIME0){ // если подошло время time0 или чтото прилетело в топик или поменялось значение
node.readHoldingRegisters(0, 1); // Адрес регистра 40001, Кол-во элементов 1
adres0Status = String(node.getResponseBuffer(0)).toInt();
if(adres0Status){
String(node.getResponseBuffer(0)).toCharArray(buf0, sizeof(buf0)); /// String a char para mensaje MQTT /// String to char for MQTT message
client_MQTT.publish(PUBLISHTOPIC1,buf0);
time0 = 0;
}
node.clearResponseBuffer();
delay(tdelay);
}
}
// публикуемый топик температура установленная на термостате
void loopPublishMQTTclientRegistr4(void) // функция обработки 4 регистра установленная температура
{
bool to_MQTT4 = 0;
char buf4[10];
if(MQTT_to_Holding[4].toInt() > 30 && MQTT_to_Holding[4].toInt() < 65){
if(adres4Val != MQTT_to_Holding[4].toInt()){
node.writeSingleRegister(4, MQTT_to_Holding[4].toInt());
delay(10);
//Serial.print("adres4Val-"); Serial.println(adres4Val);
//Serial.print("MQTT_to_Holding[4].toInt()-"); Serial.println(MQTT_to_Holding[4].toInt());
//MQTT_to_Holding[4] = "";
to_MQTT4 = 1;
}
}
if(time4 || to_MQTT4){ // если подошло время time0 или чтото прилетело в топик или поменялось значение
node.readHoldingRegisters(4, 1); // Адрес регистра 40004, Кол-во элементов 1
adres4Val = String(node.getResponseBuffer(0)).toInt();
if(adres4Val){
String(node.getResponseBuffer(0)).toCharArray(buf4, sizeof(buf4)); /// String a char para mensaje MQTT /// String to char for MQTT message
client_MQTT.publish(PUBLISHTOPIC5,buf4);
time4 = 0;
}
node.clearResponseBuffer();
delay(tdelay);
}
}
void loopPublishMQTTclientRegistr5(void) // функция обработки 5 регистра время минуты
{
bool to_MQTT5 = 0;
char buf5[10];
if(MQTT_to_Holding[5].toInt() > 0 && MQTT_to_Holding[5].toInt() < 60){
if(adres5Val != MQTT_to_Holding[5].toInt()){
node.writeSingleRegister(5, MQTT_to_Holding[5].toInt());
delay(10);
//Serial.print("adres5Val-"); Serial.println(adres5Val);
//Serial.print("MQTT_to_Holding[5].toInt()-"); Serial.println(MQTT_to_Holding[5].toInt());
to_MQTT5 = 1;
}
}
if(time5 || to_MQTT5){ // если подошло время time0 или чтото прилетело в топик или поменялось значение
node.readHoldingRegisters(5, 1); // Адрес регистра 40006, Кол-во элементов 1
adres5Val = String(node.getResponseBuffer(0)).toInt();
if(adres5Val){
String(node.getResponseBuffer(0)).toCharArray(buf5, sizeof(buf5)); /// String a char para mensaje MQTT /// String to char for MQTT message
client_MQTT.publish(PUBLISHTOPIC6,buf5);
time5 = 0;
}
node.clearResponseBuffer();
delay(tdelay);
}
}
void loopPublishMQTTclientRegistr6(void) // функция обработки 6 регистра время часы
{
bool to_MQTT6 = 0;
char buf6[10];
if(MQTT_to_Holding[6].toInt() > 0 && MQTT_to_Holding[6].toInt() < 24){
if(adres6Val != MQTT_to_Holding[6].toInt()){
node.writeSingleRegister(6, MQTT_to_Holding[6].toInt());
delay(10);
//Serial.print("adres6Val-"); Serial.println(adres6Val);
//Serial.print("MQTT_to_Holding[6].toInt()-"); Serial.println(MQTT_to_Holding[6].toInt());
to_MQTT6 = 1;
}
}
if(time6 || to_MQTT6){ // усли подошло время time0 или чтото прилетело в топик или поменялось значение
node.readHoldingRegisters(6, 1); // Адрес регистра 40007, Кол-во элементов 1
adres6Val = String(node.getResponseBuffer(0)).toInt();
if(adres6Val){
String(node.getResponseBuffer(0)).toCharArray(buf6, sizeof(buf6)); /// String a char para mensaje MQTT /// String to char for MQTT message
client_MQTT.publish(PUBLISHTOPIC7,buf6);
time6 = 0;
}
node.clearResponseBuffer();
delay(tdelay);
}
}
void loopPublishMQTTclientRegistr7(void) // функция обработки 7 регистра дни недели
{
bool to_MQTT7 = 0;
char buf7[10];
if(MQTT_to_Holding[7].toInt() > 0 && MQTT_to_Holding[7].toInt() < 8){
if(adres7Val != MQTT_to_Holding[7].toInt()){
node.writeSingleRegister(7, MQTT_to_Holding[7].toInt());
delay(10);
to_MQTT7 = 1;
}
}
if(time7 || to_MQTT7){ // усли подошло время time0 или чтото прилетело в топик или поменялось значение
node.readHoldingRegisters(7, 1); // Адрес регистра 40008, Кол-во элементов 1
adres7Val = String(node.getResponseBuffer(0)).toInt();
if(adres7Val){
String(node.getResponseBuffer(0)).toCharArray(buf7, sizeof(buf7)); /// String a char para mensaje MQTT /// String to char for MQTT message
client_MQTT.publish(PUBLISHTOPIC8,buf7);
time7 = 0;
}
node.clearResponseBuffer();
delay(tdelay);
}
}
void loopPublishMQTTclient(void)
{
bool to_MQTT1,to_MQTT2,to_MQTT3;
char buf[10];
if(time1){
node.readHoldingRegisters(1, 1); // Адрес регистра 40002, Кол-во элементов 1
//Serial.print("[1] ");
//Serial.print(node.getResponseBuffer(0));
String(node.getResponseBuffer(0)).toCharArray(buf, sizeof(buf)); /// String a char para mensaje MQTT /// String to char for MQTT message
client_MQTT.publish(PUBLISHTOPIC2,buf);
node.clearResponseBuffer(); /// Limpiar buffer modbus RTU /// Clean modbus RTU buffer
time1=0;
delay(tdelay);
}
else if(time2){ // публикуемый топик внешний датчик температуры пол
node.readHoldingRegisters(2, 1); // Адрес регистра 40003, Кол-во элементов 1
//Serial.print("[2] ");
//Serial.print(node.getResponseBuffer(0));
String(node.getResponseBuffer(0)/2).toCharArray(buf, sizeof(buf)); /// String a char para mensaje MQTT /// String to char for MQTT message
client_MQTT.publish(PUBLISHTOPIC3,buf);
node.clearResponseBuffer(); /// Limpiar buffer modbus RTU /// Clean modbus RTU buffer
time2=0;
delay(tdelay);
}
else if(time3){ //публикуемый топик внешний датчик температуры пол
node.readHoldingRegisters(3, 1); // Адрес регистра 40004, Кол-во элементов 1
//Serial.print("[3] ");
//Serial.print(node.getResponseBuffer(0));
String(node.getResponseBuffer(0)/2).toCharArray(buf, sizeof(buf)); /// String a char para mensaje MQTT /// String to char for MQTT message
client_MQTT.publish(PUBLISHTOPIC4,buf);
node.clearResponseBuffer(); /// Limpiar buffer modbus RTU /// Clean modbus RTU buffer
time3=0;
delay(tdelay);
}
}
void looplast_time(void) // интервал публикации топиков
{
if(millis() > (last_time + send_interval*1000)){
time0 = 1; time1 = 1;
time2 = 1; time3 = 1;
time4 = 1; time5 = 1;
time6 = 1; time7 = 1;
last_time = millis();
}
}
void setup(void)
{
pinMode(MAX485_DE_RE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_DE_RE, 0);
Serial.begin(9600);
delay(100);
swSer.begin(9600);
node.begin(IDDEVAIS, swSer);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
delay(100);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
client_MQTT.setServer(mqtt_server, mqtt_port);
client_MQTT.setCallback(callback);
delay(100);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
//Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
// No authentication by default
//ArduinoOTA.setPassword((const char *)"123");
ArduinoOTA.onStart([]() {
//Serial.println("Start");
});
ArduinoOTA.onEnd([]() {
//Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
//Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
/*
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
*/
});
ArduinoOTA.begin();
//Serial.println("Ready");
//Serial.print("IP address: ");
//Serial.println(WiFi.localIP());
}
void loop(void)
{
ArduinoOTA.handle();
if (!client_MQTT.connected()) {
reconnect(); /// reconection MQTT
}
//Проверка входящих соединений по подписке
client_MQTT.loop();
// интервал публикации топиков
looplast_time();
// Публикуем топики
loopPublishMQTTclient();
loopPublishMQTTclientRegistr0();
loopPublishMQTTclientRegistr4();
loopPublishMQTTclientRegistr5();
loopPublishMQTTclientRegistr6(); // функция обработки 6 регистра время часы
loopPublishMQTTclientRegistr7(); // функция обработки 7 регистра дни недели
}
-
- Сообщения: 52
- Зарегистрирован: Пт июн 09, 2017 8:39 pm
- Благодарил (а): 4 раза
- Поблагодарили: 1 раз
Re: Помогите собрать шлюз для MD. Mqqt<->modbus rtu
У меня так работает, единственное в библиотеку <ModbusMaster.h> нужно внести изменения
// Modbus timeout [milliseconds]
static const uint16_t ku16MBResponseTimeout = 2000; ///< Modbus timeout [milliseconds]
поменять на
// Modbus timeout [milliseconds]
static const uint16_t ku16MBResponseTimeout = 200; ///< Modbus timeout [milliseconds]
// Modbus timeout [milliseconds]
static const uint16_t ku16MBResponseTimeout = 2000; ///< Modbus timeout [milliseconds]
поменять на
// Modbus timeout [milliseconds]
static const uint16_t ku16MBResponseTimeout = 200; ///< Modbus timeout [milliseconds]
-
- Сообщения: 52
- Зарегистрирован: Ср май 31, 2017 3:06 am
- Откуда: odinwolk@gmail.com
- Благодарил (а): 193 раза
- Поблагодарили: 18 раз