Control sensors on arduino connected to Raspberry over USB using openHAB

Hi everyone,

I was searching around and didn’t found answer or solution (maybe I missed).

I would like to control sensors (like DHT-22, Relay module…) connected directly to Arduino nano, which is connected to Raspberry only over USB and controlling them using openHAB?

I saw a lot of solutions sending data with MQTT transport over WiFi or Ethernet, but not USB only (USB to USB).

Any answer or link to that kind of solution is welcome.

Best regards

Any reason you’re not connecting the DHT22 etc directly to the Raspberry PI?

I’m doing this using MySensors. You’re able to use the library and binding with a Nano and attached sensors via USB.

@psyciknz Yes, I am using some analog sensors as well, that is one of the reasons using Arduino
@TimO Can you post any link to some tutorial / example.

Thanks

I’m using the following combination:

  1. Arduino Nano with 12 SSR (5 shutter, 2 lights) and 1 ACS 712 connected:
// Enable debug prints to serial monitor
#define MY_DEBUG 


// Enable serial gateway
#define MY_GATEWAY_SERIAL

#include <MySensor.h>  

#define SSR_ON 1
#define SSR_OFF 0
#define NUMBER_OF_SSR 12

// How long should the relay stay active?
#define SSR_ACTIVE_DURATION_1 100
#define SSR_ACTIVE_DURATION_2 120000

#define CURRENT_MEASURE_INTERVAL 5000

#define ACS712_PIN A4
#define MV_PER_AMP 100

#define CHILD_ID_COVER_1 0
#define CHILD_ID_COVER_2 1
#define CHILD_ID_COVER_3 2
#define CHILD_ID_COVER_4 3
#define CHILD_ID_COVER_5 4
#define CHILD_ID_LIGHT_1 5
#define CHILD_ID_LIGHT_2 6
#define CHILD_ID_POWER_1 7


unsigned long ssr_active_duration[] = {
  SSR_ACTIVE_DURATION_2,
  SSR_ACTIVE_DURATION_2,
  SSR_ACTIVE_DURATION_2,
  SSR_ACTIVE_DURATION_2,
  SSR_ACTIVE_DURATION_2,
  SSR_ACTIVE_DURATION_2,
  SSR_ACTIVE_DURATION_2,
  SSR_ACTIVE_DURATION_2,
  SSR_ACTIVE_DURATION_2,
  SSR_ACTIVE_DURATION_2,
  SSR_ACTIVE_DURATION_1,
  SSR_ACTIVE_DURATION_1,
};

unsigned int ssr_pins[] = {2, 3, 4, 5, 6, 7, 8, 9, A0, A1, A2, A3};

unsigned long ssr_last_change[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned int ssr_status[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

unsigned long lastCurrentMeasurement = 0;
unsigned long lastWatts = 0;

int lastSendLight1Status = 0;

MyMessage wattMsg(CHILD_ID_POWER_1,V_WATT);
MyMessage light1Msg(CHILD_ID_LIGHT_1, V_STATUS);

void setup() { 
  for (int pin = 0; pin < NUMBER_OF_SSR; pin++) {
    pinMode(ssr_pins[pin], OUTPUT);
    digitalWrite(ssr_pins[pin], LOW);
  }
}

void presentation() {
  sendSketchInfo("RelaisKeller", "2.0");
  present(CHILD_ID_COVER_1, S_COVER);
  present(CHILD_ID_COVER_2, S_COVER);
  present(CHILD_ID_COVER_3, S_COVER);
  present(CHILD_ID_COVER_4, S_COVER);
  present(CHILD_ID_COVER_5, S_COVER);
  present(CHILD_ID_LIGHT_1, S_LIGHT);
  present(CHILD_ID_LIGHT_2, S_LIGHT);
  present(CHILD_ID_POWER_1, S_POWER);
}

void loop() { 
  for(int i = 0; i < sizeof(ssr_status); i++) {
    if(ssr_status[i] == SSR_ON) {
      if(ssr_last_change[i] + ssr_active_duration[i] < millis()) {
        digitalWrite(ssr_pins[i], SSR_OFF);
        ssr_status[i] = SSR_OFF;
      }
    }
  }

  if(lastCurrentMeasurement + CURRENT_MEASURE_INTERVAL < millis()) {
    unsigned long currentWatts = (unsigned long)readWatts();
    
    unsigned long diff = 0;
    if(currentWatts > lastWatts) {
      diff = currentWatts - lastWatts;
    } else {
      diff = lastWatts - currentWatts;
    }

    if(diff > 10) {
      send(wattMsg.set(currentWatts));
      if(currentWatts > 50) {
        if(lastSendLight1Status == 0) {
          send(light1Msg.set(1));
          lastSendLight1Status = 1;
        }
      } else {
        if(lastSendLight1Status == 1) {
          send(light1Msg.set(0));
          lastSendLight1Status = 0;
        }
      }
      lastWatts = currentWatts;
    }
    lastCurrentMeasurement = millis(); 
  }
}

float readWatts() {
  float result;
  
  int readValue;             //value read from the sensor
  int maxValue = 0;          // store max value here
  int minValue = 1024;          // store min value here
  
  uint32_t start_time = millis();
  while((millis()-start_time) < 50) //sample for 1 mSec
  {
      readValue = analogRead(ACS712_PIN);
      // see if you have a new maxValue
      if (readValue > maxValue) 
      {
          /*record the maximum sensor value*/
          maxValue = readValue;
      }
      if (readValue < minValue) 
      {
          /*record the maximum sensor value*/
          minValue = readValue;
      }
  }
   
  // Subtract min from max
  result = ((maxValue - minValue) * 5.0)/1024.0;

  float VRMS = (result/2.0) *0.707; 
  float AmpsRMS = (VRMS * 1000)/MV_PER_AMP;
      
  return AmpsRMS*230;
}

void receive(const MyMessage &message) {
  if(message.type == V_STATUS) {
    if(message.sensor == CHILD_ID_LIGHT_1) {
      digitalWrite(ssr_pins[message.sensor*2], SSR_ON);
      ssr_last_change[message.sensor*2] = millis();
      ssr_status[message.sensor*2] = SSR_ON;
    } else if(message.sensor == CHILD_ID_LIGHT_2) {
      digitalWrite(ssr_pins[message.sensor*2-1], message.getBool()?SSR_ON:SSR_OFF);
      ssr_last_change[message.sensor*2-1] = millis();
      ssr_status[message.sensor*2-1] = message.getBool()?SSR_ON:SSR_OFF;
    }
  } else if(message.type == V_UP) {
    digitalWrite(ssr_pins[message.sensor*2], SSR_ON);
    ssr_last_change[message.sensor*2] = millis();
    ssr_status[message.sensor*2] = SSR_ON;
    digitalWrite(ssr_pins[message.sensor*2 + 1], SSR_OFF);
  } else if(message.type == V_DOWN) {
    digitalWrite(ssr_pins[message.sensor*2], SSR_OFF);
    digitalWrite(ssr_pins[message.sensor*2 + 1], SSR_ON);
    ssr_last_change[message.sensor*2+1] = millis();
    ssr_status[message.sensor*2+1] = SSR_ON;
  } else if(message.type == V_STOP) {
    digitalWrite(ssr_pins[message.sensor*2], SSR_OFF);
    digitalWrite(ssr_pins[message.sensor*2 + 1], SSR_OFF);
  }
}
  1. I’m using OH2, so my things file looks like this:
Bridge mysensors:bridge-ser:MySGWKeller [ serialPort="/dev/ttyUSB0", sendDelay=100, skipStartupCheck=true ] {
    cover			kitchenShutter02 	[ nodeId="0", childId="0" ]
    cover			kitchenShutter03	[ nodeId="0", childId="1" ]
    cover			livingShutter01 	[ nodeId="0", childId="2" ]
    cover			livingShutter02 	[ nodeId="0", childId="3" ]
    cover			kitchenShutter01 	[ nodeId="0", childId="4" ]
    light			corridorLight01		[ nodeId="0", childId="5" ]
    light			corridorLight02		[ nodeId="0", childId="6" ]
    power			corridorLight01watt	[ nodeId="0", childId="7" ]
}

There is a binding for OH1 and a binding for OH2 available: https://forum.mysensors.org/category/15/openhab

Every example from https://www.mysensors.org/build/ will work without NRF24 and with USB connection.

I’m sorry I can’t provide a simpler example.

1 Like

I’m working on building out a solution to this. Right now I only have support working for controlling the GPIO pins as digital in/out, but I plan to expand to support different sensors. It makes them available over MQTT in customizable topics.

You can find MQTTany over on github. For the moment the documentation is largely found in the config file. I will be making a breaking change in the next day or two to the layout of the config file that will make defining pin configurations more user friendly.