Button led on arduino node over modbus

Hello everyone,

i have problem because i dont know how to do button to turn on and off the led.
I have sketch on arduino and from openhab2 i can turn on and off the led but i wont have fisical button on the wall like switch to turn on anf the led and see this on openhab2, my sketch work but whem i turn on or off the led from openhab2 i must two times click the button on the wall to change state led and i do not know why, can sombody help me with this ?

Function to button is “CheckButtonState()” and communication over modbus is in function “modbus”

#include <Timers.h>
#include <ModbusRtu.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Bounce2.h>

Timers <4> akcja;
// data array for modbus network sharing
//uint16_t au16data[16] = {
//  3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, -1 };
uint16_t au16data[4];

//beg_bounce
#define BUTTON_PIN 4
Bounce debouncer = Bounce();
int ledState = LOW;
volatile byte button_state = 0;
//end_bounce

//beg_lightsensor
#define photoPin A1         // Fotorezystor
volatile int lastLightLevel;
//end_lightsensor

//beg_temp
#define COMPARE_TEMP 1 // Wysyłaj temperaturę jeśli się zmieni? 1 = YES 0 = NO
#define MAX_ATTACHED_DS18B20 1
#define ONE_WIRE_BUS 7
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;
int  resolution = 9;
unsigned long lastTempRequest = 0;
int  delayInMillis = 0;
volatile float lastTemperature[MAX_ATTACHED_DS18B20];
//end_temp
/**
 *  Modbus object declaration
 *  u8id : node id = 0 for master, = 1..247 for slave
 *  u8serno : serial port (use 0 for Serial)
 *  u8txenpin : 0 for RS-232 and USB-FTDI 
 *               or any pin number > 1 for RS-485
 */
Modbus slave(1,0,2);

void setup() {

//beg_bounce
pinMode(BUTTON_PIN, INPUT_PULLUP);
debouncer.attach(BUTTON_PIN);
debouncer.interval(5);
//end_bounce

//Temp_beg 
  sensors.begin();
  sensors.getAddress(tempDeviceAddress, 0);
  sensors.setResolution(tempDeviceAddress, resolution);
  sensors.setWaitForConversion(false); 
  delayInMillis = 750 / (1 << (12 - resolution)); 
  lastTempRequest = millis();
//Temp_end

  pinMode(11, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(photoPin, INPUT);
  digitalWrite(11, LOW );
  digitalWrite(13, LOW );
  slave.begin( 19200 ); // baud-rate at 19200
  au16data[0] = 0;
  akcja.attach(0, 1, modbus); // Komunikacja modbus
  akcja.attach(1, 300119, lightLevel); // Poziom natezenia swiatla co 5 min
  akcja.attach(2, 309469, CheckTemp); // Odczyt temperatury co 5 min
  akcja.attach(3, 2, CheckButtonState); // Odczyt buttona co 3ms
}

void loop()
{
akcja.process();
}

void CheckButtonState()
{
boolean stateChanged = debouncer.update();
int valueB = debouncer.read();
if (stateChanged &&  valueB == LOW) {
         
       if ( ledState == LOW ) {ledState = HIGH;} else {ledState = LOW;}
            digitalWrite(11,ledState);
          bitWrite( au16data[0], 0, digitalRead( 11 ));
       
    }  
}

void modbus()
{
 if (slave.poll( au16data, 4 ))
{  
// set
  digitalWrite( 11, bitRead( au16data[0], 0 ));
  digitalWrite( 13, bitRead( au16data[0], 1 ));
  
// get  
  au16data[1] = lastLightLevel;
  au16data[2] = lastTemperature[0];
}
}

void lightLevel()
{
  int lightLevel = (analogRead(photoPin)); 
  if (lightLevel != lastLightLevel) {
       lastLightLevel = lightLevel;
  }
}

void CheckTemp()
{
  
 if (millis() - lastTempRequest >= delayInMillis) // waited long enough??
  {
 sensors.requestTemperatures();
 float temperature = sensors.getTempCByIndex(0);
  
    int i=0;
    #if COMPARE_TEMP == 1
    if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
    #else
    if (temperature != -127.00 && temperature != 85.00) {
    #endif     
      // Send in the new temperature
      //temp = sensors.getTempCByIndex(i);
      // Save new temperatures for next compare
      lastTemperature[i]=temperature;
    }
    lastTempRequest = millis();
  }  
}

1 Like

I think it would be better to ask that question in an arduino forum, you might get faster answers.

Edit:

If that sketch works how do you connect your hardware to openHAB? Via MQTT? Then you should post your items definition and maybe the rules you are using …

OK i found the problem with button and them work fine :slight_smile:

Problem was in CheckButtonState() function because arduino after turn on or off the led wasnt have refresh state of PIN with led, this is correct function:

void CheckButtonState()
{
boolean stateChanged = debouncer.update();
int valueB = debouncer.read();
if (stateChanged &&  valueB == LOW) {
         ledState = digitalRead(11);
       if ( ledState == LOW ) {ledState = HIGH;} else {ledState = LOW;}
            digitalWrite(11,ledState);
            bitWrite( au16data[0], 0, digitalRead( 11 ));
            }
              
}

sihui:

my openhab2 is on raspberry pi
RPI ->USB to RS485 converter -> line A and B to MAX485 -> Arduino
and this works with modbus protocol (in openhab2 Modbus Binding i have installed)

My items are very simple to modbus:

Switch Slave1 { modbus="slave1:0" }
Switch Slave1r { modbus="slave1:1" }
Switch Slave2 { modbus="slave3:0" }
Number LightSensor  "Light Sensor [%d LUX]" { modbus="slave2:0" }
Number Temperature  "Temperature [%.1f °C]" { modbus="slave2:1" }
1 Like

Hi swiety,

Can you explain how you did the electrical connections? And also how you configure the modbus.sitemap and modbus.cfg?