Работа с библиотекой ModbusRtu.h

redeemer
Offline
Зарегистрирован: 08.05.2015

Всем день добрый.

Не могу разобраться почему Openhab не может включить лампу на ардуинке

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

Openhab отправляет запрос на состояние 4х ячеек: 01 01 00 01 00 04 6C 09

И получает ответ:

01 01 01 00 51 88 (в данном моменте все выключено)

01 01 01 01 D0 49 (в данном моменте первый бит включен)
 
При попытке включения Openhab отправляет данные в таблицу №5 говоря 1-му (01) включиться (FF)
01 05 00 01 FF 00 DD FA
(И поменять это не возможно)
 
Но лампа не включается, хотя в таблицу он данные передал
При попытке отправить статус 5 таблицы в состояние таблицы 01 приходит значение 0
 
Подскажите пожалуйста, где я туплю

#include "ModbusRtu.h"      // Подключаем библиотеку для работы ModBusRTU
#include "Wire.h"           // Подключаем библиотеку для работы по I2C

//Описание пинов для адресации ModBus
#define Adr0 7
#define Adr1 6
#define Adr2 5
#define Adr3 4
#define Adr4 3
#define Adr5 2

//Описание пинов на вход/выход
#define io1 8               // номер входа, подключенный к кнопке 1
#define io2 9               // номер входа, подключенный к кнопке 2
#define io3 10              //
#define io4 11              //
#define io5 12              //
#define stlPin  13          // номер выхода индикатора работы


//Переменные
boolean led1 = 0, led2 = 0;               //Переменные включения освещения
boolean btnLastState1, btnLastState2;     //Переменные изменения состояния кнопка
boolean btnPress1, btnPress2;             //Переменные нажатия кнопки

int8_t state = 0;
unsigned long tempus, temptest;
unsigned long timerdelay1, timerdelay2;   //Задержка повторного нажатия
int ModBusAdr = 0;

// массив данных modbus
uint16_t au16data[11];



void setup() {

  delay(2000);               // Задержка перед включением для таймаута по чтению ModBus адреса

  // Инициализация пинов ModBus на вход
  pinMode(Adr0, INPUT);
  pinMode(Adr1, INPUT);
  pinMode(Adr2, INPUT);
  pinMode(Adr3, INPUT);
  pinMode(Adr4, INPUT);
  pinMode(Adr5, INPUT);

  // Присвоение адреса по ModBus через перемычки
  ModBusAdr = ModBusAdr + (digitalRead(Adr0) * pow(2, 0));
  ModBusAdr = ModBusAdr + (digitalRead(Adr1) * pow(2, 1));
  ModBusAdr = ModBusAdr + (digitalRead(Adr2) * pow(2, 2));
  ModBusAdr = ModBusAdr + (digitalRead(Adr3) * pow(2, 3));
  ModBusAdr = ModBusAdr + (digitalRead(Adr4) * pow(2, 4));
  ModBusAdr = ModBusAdr + (digitalRead(Adr5) * pow(2, 5));

  // Инициализация пинов на вход/выход
  pinMode(io1, INPUT_PULLUP);
  pinMode(io2, INPUT_PULLUP);
  pinMode(io3, INPUT_PULLUP);
  pinMode(io4, OUTPUT);
  pinMode(io5, OUTPUT);
  pinMode(stlPin, OUTPUT);    //Обмен по ModBus

  //Задаём ведомому адрес, последовательный порт, выход управления TX
  Modbus slave(ModBusAdr, 0, 0);
  // настраиваем последовательный порт ведомого
  slave.begin(19200);
  // зажигаем светодиод на 100 мс
  tempus = millis() + 100;
  digitalWrite(stlPin, HIGH );

}

void loop() {
  Modbus slave(ModBusAdr, 0, 0);
  // обработка сообщений
  state = slave.poll(au16data, 11);
  // если получили пакет без ошибок - зажигаем светодиод на 50 мс
  if (state > 4) {
    tempus = millis() + 50;
    digitalWrite(stlPin, HIGH);
  }
  if (millis() > tempus) digitalWrite(stlPin, LOW );
  //обновляем данные в регистрах Modbus и в пользовательской программе



  //Чтение пина 0 это 1, а 1 это 0 так как включена самоподтяжка
  if ((abs(digitalRead(io1) - 1) == 1) && (btnLastState1 == false)) {
    btnPress1 = true;
    btnLastState1 = true;
  } else {
    btnPress1 = false;
    btnLastState1 = false;
  }

  if ((abs(digitalRead(io2) - 1) == 1) && (btnLastState2 == false)) {
    btnPress2 = true;
    btnLastState2 = true;
  } else {
    btnPress2 = false;
    btnLastState2 = false;
  }


  //Изменение состояния ламп с влючено на выключено и наоборот

  if ((btnPress1 == true) &&  (millis() > timerdelay1)) {
    if (led1 == 1 ) {
      led1 = 0;
      timerdelay1 = millis() + 2000;
    } else {
      led1 = 1;
      timerdelay1 = millis() + 2000;
    }
    digitalWrite(io4, led1);
  }
  if ((btnPress2 == true) &&  (millis() > timerdelay2)) {
    if (led2 == 1 ) {
      led2 = 0;
      timerdelay2 = millis() + 2000;
    } else {
      led2 = 1;
      timerdelay2 = millis() + 2000;
    }
    digitalWrite(io5, led2);
  }


  //Копируем Coil[1] в Discrete[0]
  au16data[0] = au16data[1];


  //Выводим значение регистра 2.1 на светодиод
  if (led1 != bitRead( au16data[2], 1)) {
    led1 = bitRead( au16data[2], 1);
    digitalWrite(io4, led1);
  }

  //Сохраняем состояние лампы в регистр 0.х
  bitWrite( au16data[0], 1, led1);
  bitWrite( au16data[0], 2, led2);
  //Копируем Holding[5,6,7] в Input[2,3,4]
  au16data[2] = au16data[5];
  au16data[3] = au16data[6];
  au16data[4] = au16data[7];
  //Сохраняем в регистры отладочную информацию
  au16data[8] = slave.getInCnt();
  au16data[9] = slave.getOutCnt();
  au16data[10] = slave.getErrCnt();
}

 

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

Это что за бред в строке 89 ?


  if ((abs(digitalRead(io1) - 1) == 1)

 

 

Не проще так :


  if (!digitalRead(io1) )

 

 

Ну и дальше какая то есресь с массивами регистров модбас. 

Регистры модбас это как бы сетевые переменные, нет смысла их сравнивать и копировать друг в друга. Они для других нужд. Их отдают по запросу и используют в программе по мере надобности.

 

Дальше даже не знаю, стоит ли комментировать

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

А расскажите пожалуйста что означает строка 075 ?

И это... вы примеры использования этой библиотеки смотрели ? Прям поиском поищите "pool".

redeemer
Offline
Зарегистрирован: 08.05.2015

Kakmyc пишет:

  if (!digitalRead(io1) )

 

Буду знать, спасибо за информацию

redeemer
Offline
Зарегистрирован: 08.05.2015

brokly пишет:

А расскажите пожалуйста что означает строка 075 ?

И это... вы примеры использования этой библиотеки смотрели ? Прям поиском поищите "pool".

Строка из примера библиотеки, эту часть не правил

https://habr.com/ru/post/249043/

redeemer
Offline
Зарегистрирован: 08.05.2015

Kakmyc пишет:

Ну и дальше какая то есресь с массивами регистров модбас. 

Регистры модбас это как бы сетевые переменные, нет смысла их сравнивать и копировать друг в друга. Они для других нужд. Их отдают по запросу и используют в программе по мере надобности.

Прошу пояснить, я просто не могу до конца въехать, так как к сожалению примеров связки Modbus RTU и Openhab3 можно сказать что нет и все ссылаются на 2 версию его

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

redeemer пишет:

Строка из примера библиотеки, эту часть не правил

https://habr.com/ru/post/249043/

Из какого нахрен примера !? Я спросил, что это значит и где POOL !? А вы вместо того, что бы понять свои косяки, продолжаете просить помочь. Как вам помочь, если вы сами себе враг ?

1. Вы каждый проход цикла LOOP создаете НОВЫЙ экземпляр класса !!!! Или вы считаете что расположение строки в коде не имеет значения !?

2. Вы не даете работать мод басу потому что у вас он не обслуживается, нет POOL !!!

У вас ВСЕ не правильно. Продолжайте тупить , удачи.

redeemer
Offline
Зарегистрирован: 08.05.2015

brokly пишет:

У вас ВСЕ не правильно. Продолжайте тупить , удачи.

Спасибо за правильный пинок)

По итогу была заменена библиотека на стандартную ArduinoModbus.h и всё заработало, с учетом изменения кода. В той скачанной библиотеке отсутствовал корректный цикл по pool и обработка таблицы 05, к чему по итогу и приводили глюки.