Introduction: OpenHab & Arduino

What I wanted out of my Smart Home setup was flexibility. Sure, I wanted to automate my lights, but I also wanted to control my garage doors, watch for water in the basement, and manage my garden.

OpenHab gives me that flexibility and lets me do each part my way. My ZWave light switches work great with it, and that's what I started with. But when I wanted to automate my garage door, I balked at the limited options and cost of those options.

OpenHab can talk over a serial port (a COM port to us windows folks) quite easily, and an Arduino speaks that way right out of the box.

So I set up an Arduino UNO with a nRF24L01+ to act as a base-station that I refer to as the Hub.

Any other Arduino I set up just needs to talk back & forth with the Hub over it's own nRF24L01+

Step 1: Wiring the Hub

This part is relatively easy. On an Uno, connect:

UNO pin > nRF24L01+ pin

GND > GND

3V3 > VCC

9 > CE (you can change this in code)

10 > CSN (you can change this in code)

13 > SCK

11 > MOSI

12 > MISO

Note: IRQ is left hanging, nothing is connected to it on the nRF24L01+

Code is attached for the HUB as I use it currently with the Garage sensor example in a later step.

I've also included the STL file for the 3D Printed mounting system. It attaches to a LACK IKEA shelf, but you can get a free account with tinkercad and modify the mounting system quite easily. Here's a link to my tinkercad sketch.

Step 2: Wiring the Sensor

If you use an UNO for the sensor, you should wire it up the same way the Hub is in step 1.

If, however, you pick something like a MICRO, you'll wire it somewhat differently, as SCK/MOSI/MISO aren't wired directly to IO pins 11-13 as they are with the UNO.

MICRO pin > nRF24L01+ pin

GND > GND

3V3 > VCC

9 > CE (you can change this in code)

10 > CSN (you can change this in code)

SCK > SCK

MOSI > MOSI

MISO > MISO

Note: IRQ is left hanging again, nothing is connected to it on the nRF24L01+

Step 3: Example: Garage Sensor

I've added the following features to my first sensor:

I did this all on a mini-breadboard

A 2 channel relay, such that I can close the circuit on both garage door's opener to change the state of either garage door. Currently I only have it wired to my garage door.

Two Ultrasonic Distance Sensor Modules (one for each door, though currently I'm only using one). If placed correctly, I can use the ping time to determine if the door is up, if the door is down and the car is in the garage, or if the door is down and no car is in the garage.

The 2 channel relay is connected

GND > MICRO GND

VCC > MICRO 5V

IN1 > MICRO 7

IN2 > MICRO 8

The first sensor is set up

VCC > MICRO 2

TRIG > MICRO 3

ECHO > MICRO 4

GND > MICRO 5

Ultimately, I want to tie VCC & GND into the appropriate leads to free up space for the 2nd sensor. The nice thing about this particular setup (pins 2-5) is that you can just plug the Sensor directly into the breadboard, which makes testing easier.

Code is attached for this particular setup.

If the sensor receives a "1", it triggers my garage door to open/close/stop, and returns the distance from the sensor to the first object in decimeters.

If the sensor recieves a "2", it will (eventually) trigger my wife's garage door, and return the distance on her sensor.

If the sensor receives any other integer, it just returns the distance. (I'll need to add states 3 & 4 later to tell it which sensor to read ... but since I currently only have one sensor, this works fine).

Note: I need to design an enclosure on tinkercad, SketchUp or DesignSpark. I haven't yet, as I still have functionality to add to the unit.

Step 4: Connecting to OpenHab

I'm not going to get into the setup of OpenHab in this guide (and I'll only do one if I can't find a good one to link to). Lots of resources out there. I'm just going to talk about how to get it to talk to the Arduino Hub.

ITEMS FILE

First up, you need to set up the Arduino in your .items file. Here's the lines I use:

This sets up the connection to the Arduino's serial port (your COM port may vary, heck it may not even be called a COM port if you're on linux (I believe they call it tty or something)):

String Arduino "Arduino [%s]" (arduino) {serial="COM5"}

This sets up the button that you can press to open/close/stop your garage door

Switch Arduino_toggle "Arduino Toggle"

SITEMAP FILE

Next, you'll want to set up elements in your .sitemap file that will be your controls. Here's my stuff:

This shows an icon for a garage door, as well as the current status in text. Since the garagedoor icon expects the states "OPEN" and "CLOSED" the icon will visually change to match the door state:

Text item=Garage_Eric icon="garagedoor"

This gives you a button you can push that triggers an event, that sends "1" to the arduino, using a rule we'll discuss in the rules section.

Switch item=Garage_Eric_Button mappings=[ON="Toggle State"] icon="energy"

RULES FILE

Lastly, you'll set up a rule that tells these things what to do:

This rule says that when the Arduino sends data through it's serial port, to convert that string to a float, and then see if it's more or less than 7. For me, the door is open when it reads 2, and closed when it reads 12.

rule "Arduino"

when

Item Arduino received update

then {

var float dist = new Float(Arduino.state.toString.trim);

if (dist>7) Garage_Eric.postUpdate("CLOSED");

if (dist<=7) Garage_Eric.postUpdate("OPEN");

end

This rule says that any time you hit the button, to send "1" through the Arduino's serial port. In my code (in the garage example), if the Garage Arduino receives a 1, it triggers the door.

rule "Garage Eric"

when

Item Garage_Eric_Button received command

then

sendCommand (Arduino , "1")

end

Step 5: Future Plans

I don't like that the heartbeat for checking the door status is in the Arduino code, I really want that to be controlled by OpenHab. I just need to figure out how to tell it to do something every X seconds.

I have scene thing I'm running and I want to work the Garage door into it. Currently it reads:

rule "Scene Change"
when Item Scene received command then switch(receivedCommand) { case 1 : { //Normal sendCommand (Light_GF_Family,99) sendCommand (Light_GF_Office,99) sendCommand (Light_GF_Foyer,"OFF") } case 2 : { //Movie sendCommand (Light_GF_Family,20) sendCommand (Light_GF_Office,20) sendCommand (Light_GF_Foyer,"OFF") } case 3 : { //BedTime sendCommand (Light_GF_Family,20) sendCommand (Light_GF_Office,20) sendCommand (Light_GF_Foyer,"ON") } case 0 : { //GoodNight sendCommand (Light_GF_Family,0) sendCommand (Light_GF_Office,0) sendCommand (Light_GF_Foyer,"OFF") sendCommand (Light_GF_Porch,"OFF") sendCommand (Light_GF_Driveway,"OFF") sendNotification("eric.cantrell@gmail.com", "Good Night!") } } end

When I hit GoodNight, I want it to check if the garage door is open. If it is, I want it to tell me that and then attempt to close it.

Automation Contest

Participated in the
Automation Contest

Coded Creations

Participated in the
Coded Creations