element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Forget Me Not Design Challenge
  • Challenges & Projects
  • Design Challenges
  • Forget Me Not Design Challenge
  • More
  • Cancel
Forget Me Not Design Challenge
Blog [CaTS] ForgetMeNot - Week 4: Arduino-OpenHAB communication
  • Blog
  • Forum
  • Documents
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: fvan
  • Date Created: 24 Aug 2014 10:31 AM Date Created
  • Views 5270 views
  • Likes 5 likes
  • Comments 28 comments
  • forget_me_not
  • design_challenge
  • openhab
  • tektronix
  • iot_pet_care
  • eclipse
  • internet_of_things
  • enocean
  • cats
  • raspberrypi
  • smarthome
  • challenge
  • iot
  • enocean_pi
Related
Recommended

[CaTS] ForgetMeNot - Week 4: Arduino-OpenHAB communication

fvan
fvan
24 Aug 2014

Previous posts for this project:

  • [CaTS] ForgetMeNot - Index
  • [CaTS] ForgetMeNot - Week 0: Project Description
  • [CaTS] ForgetMeNot - Week 1: EnOceanPi and Sensors
  • [CaTS] ForgetMeNot - Week 2: Elro CoCo and Pi Cam with OpenHAB
  • [CaTS] ForgetMeNot - Week 3: Data persistence and charts with OpenHAB
  • [CaTS] ForgetMeNot - 3D Printing: EnOcean sensor bracket
  • [CaTS] ForgetMeNot - 3D Printing: EnOcean rocker switch and magnet holder
  • [CaTS] ForgetMeNot - 3D Printing: Food dispenser prototype

 

  • Introduction
  • Arduino to OpenHAB
    • Static values
      • Serial data from Arduino to Raspberry Pi
      • Serial data in OpenHAB
      • Parsing serial data
    • Dynamic values
    • Converting
  • OpenHAB to Arduino
    • Arduino sketch
    • OpenHAB rule
    • Test
  • Conclusion

 

Introduction

 

This week's post is about getting sensor data from an Arduino in OpenHAB and sending commands from OpenHAB to Arduino. The post covers the different iterations my code went through in order to achieve the desired result, giving some insight on how I tackle a specific problem until the goal is reached.

 

This post is also submitted half a day earlier than usual, so it can still have a shot at winning Dave (Forget Me Not Challenge: Minion of the Week #1), as I won't have time to make elaborate posts in the next to weeks. I'm getting married next week, and let's say my Minion bride would not appreciate it if I dared to take my laptop along on our honeymoon image (That's probably the kind of thing one could pull off after ten years of marriage, but perhaps not after one day ... Let's not try to find out.)

 

As doctorcdf pointed out, competition was indeed fierce this week, and this Minion is going all out one last time with this post image

 

image

ebay.com

 

Let's go!

 

Arduino to OpenHAB

 

Static values

 

In this first step, I'm trying to have string of data passed from the Arduino to OpenHAB. Once received in OpenHAB, it can be parsed and the values assigned to the corresponding items.

For this test, having the Arduino send a static string to OpenHAB is sufficient, as the focus is more on the reception and the parsing. In a second step, I'll be sending dynamic values, based on sensor data.

 

Serial data from Arduino to Raspberry Pi

 

First, the data from the Arduino needs to be sent to the Raspberry Pi. To do this, I plugged the Arduino in one of the USB ports of the Pi, after having configured it with the sketch below:

 

int weight = 125;
int temperature = 39;

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.print("weight:");
  Serial.print(weight);
  Serial.print("g_temperature:");
  Serial.print(temperature);
  Serial.println("C;");

  delay(10000);
}

 

On the Pi, it is possible to verify the serial data is properly received, by listening with minicom:

 

pi@webserver ~ $ sudo minicom -b 9600 -o -D /dev/ttyACM0

 

The screenshot shows the data from the Arduino is being received.

image

 

Serial data in OpenHAB

 

Just like with the EnOcean Pi, the OpenHAB "start.sh" script needs to be modified to be able to use this new serial interface.

 

pi@webserver ~ $ sudo nano /opt/openhab/start.sh

 

... -Dgnu.io.rxtx.SerialPorts=/dev/ttyAMA0:/dev/ttyACM0 ...

 

It is possible to define multiple serial ports, as long as they are delimited by ":".

 

The next step is to enable the serial binding by ensuring it is present in the addons folder:

 

pi@webserver ~ $ ls -l /opt/openhab/addons/*serial*
-rw-r--r-- 1 root root 10748 Jun 16 02:26 /opt/openhab/addons/org.openhab.binding.serial-1.5.0.jar

 

Finally, we need an item to bind the data to:

 

String Arduino "Arduino [%s]" (arduino) {serial="/dev/ttyACM0"}

 

To visualise the data, the item can also be added to the sitemap.

 

With all the necessary modifications done, I restarted OpenHAB and verified the events log:

 

pi@webserver ~ $ less /opt/openhab/logs/events.log

 

2014-08-17 17:34:17 - Arduino state updated to weight:125g_temperature:39C;
2014-08-17 17:34:27 - Arduino state updated to weight:125g_temperature:39C;
2014-08-17 17:34:37 - Arduino state updated to weight:125g_temperature:39C;
2014-08-17 17:34:47 - Arduino state updated to weight:125g_temperature:39C;
2014-08-17 17:34:57 - Arduino state updated to weight:125g_temperature:39C;

 

Data is coming in! Great!

 

Parsing serial data

 

Two additional items were created to assign the parsed data to:

 

String Arduino_weight "Weight [%s]"
String Arduino_temperature "Temperature [%s]"


The Arduino string is parsed with a rule which then updates the weight and temperature items:

 

rule "Arduino"
 when 
      Item Arduino received update
 then
      var String ArduinoUpdate = Arduino.state.toString.trim

      var int weightStartsOn = ArduinoUpdate.indexOf("weight:") + "weight:".length
      var String weight = ArduinoUpdate.mid(weightStartsOn, ArduinoUpdate.indexOf('_')-weightStartsOn)

      Arduino_weight.postUpdate(weight)

      var int temperatureStartsOn = ArduinoUpdate.indexOf("temperature:") + "temperature:".length
      var String temperature = ArduinoUpdate.mid(temperatureStartsOn, ArduinoUpdate.indexOf(';')-temperatureStartsOn)

      Arduino_temperature.postUpdate(temperature)
end

 

Checking the events log again, we can now see the weight and temperature being updated as well:

 

2014-08-17 18:47:58 - Arduino state updated to weight:125g_temperature:39C;
2014-08-17 18:47:58 - Arduino_weight state updated to 125g
2014-08-17 18:47:59 - Arduino_temperature state updated to 39C

 

A quick look in OpenHAB shows the full string and the parsed items:

image

 

Dynamic values

 

With the parsing of static data working, it was time to move to dynamic data.

 

For this test, I connected potentiometers to two different analog inputs of the Arduino, in order to simulate sensor data.

To make it more visual, I also connected two LEDs.

 

The setup used is as follows:

imageimage

 

In the Arduino sketch, two sensors are simulated:

  • a weight sensor ranging from 0-250gr
  • a temperature sensor ranging from 0-50°C

 

These are just test values to demonstrate the functionality until the real sensors arrive and are hooked up.

 

The sensor data will only be transmitted if one of the two values changes. Later on, this could be fine tuned even more by only sending the changed data.

 

const int weightSensorPin = A0;
const int temperatureSensorPin = A1;

int previousWeightSensorValue = 0;
int previousTemperatureSensorValue = 0;
int currentWeightSensorValue = 0;
int currentTemperatureSensorValue = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  currentWeightSensorValue = analogRead(weightSensorPin);
  currentTemperatureSensorValue = analogRead(temperatureSensorPin);

  currentWeightSensorValue = map(currentWeightSensorValue, 0, 1023, 0, 250); // simulate 0-250g
  currentTemperatureSensorValue = map(currentTemperatureSensorValue, 0, 1023, 0, 50); // simulate 0-50°C

  if(currentWeightSensorValue != previousWeightSensorValue || currentTemperatureSensorValue != previousTemperatureSensorValue) {
    Serial.print("weight:");
    Serial.print(currentWeightSensorValue);
    Serial.print("g_temperature:");
    Serial.print(currentTemperatureSensorValue);
    Serial.println("C;");

    previousWeightSensorValue = currentWeightSensorValue;
    previousTemperatureSensorValue = currentTemperatureSensorValue;
  }

  delay(1000);
}

 

 

I've made my very first video montage, specially for this blog post! I learned how to record my screen, create a picture-in-picture and how to add a title!

I manually tried to sync the two videos, and managed to get very close. Perhaps someone has additional tips on how to do this more accurately? image (I'm using iMovie on Mac)

 

Anyway, here's the fancy demonstration:

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

 

Converting

 

In the above steps, the data was parsed as a string of text. In order to be able to do calculations, these need to be converted to numbers. To do this, I slightly modified the rule and the items.

 

The rule has been updated to:

  • drop the unit which was passed in the string, to only keep the numeric data
  • create a new variable which converts the String data to Double

 

rule "Arduino"
 when 
       Item Arduino received update
 then
      var String ArduinoUpdate = Arduino.state.toString.trim

      var int weightStartsOn = ArduinoUpdate.indexOf("weight:") + "weight:".length
      var String weight = ArduinoUpdate.mid(weightStartsOn, ArduinoUpdate.indexOf('g_')-weightStartsOn)
      var Double weightDouble = new Double(weight)

      Arduino_weight.postUpdate(weightDouble)

      var int temperatureStartsOn = ArduinoUpdate.indexOf("temperature:") + "temperature:".length
      var String temperature = ArduinoUpdate.mid(temperatureStartsOn, ArduinoUpdate.indexOf('C;')-temperatureStartsOn)
      var Double temperatureDouble = new Double(temperature)

      Arduino_temperature.postUpdate(temperatureDouble)
end

 

Then, I updated the items to have numeric data instead of a string, like so:

 

Number Arduino_weight "Food quantity [%.1f gr]" <bowl> (Dispenser_Chart)
NumberArduino_temperature"Water temperature [%.1f °C]" <temperature> (Dispenser_Chart)

 

Et voila. The data can now be used for calculations, charts, etc ... image

 

2014-08-24 09:00:42 - Arduino_weight state updated to 57.0
2014-08-24 09:00:43 - Arduino_weight state updated to 180.0
2014-08-24 09:00:50 - Arduino_weight state updated to 73.0
2014-08-24 09:01:02 - Arduino_temperature state updated to 49.0
2014-08-24 09:01:02 - Arduino_temperature state updated to 8.0
2014-08-24 09:01:03 - Arduino_temperature state updated to 22.0

 

OpenHAB to Arduino

 

Time to do it the other way around.

 

In the first part of this blog post, the Arduino was sending data to OpenHAB, now OpenHAB will send data to the Arduino!

 

Arduino sketch

 

First, I modified my previous Arduino sketch to listen for incoming serial messages, in addition to what it was already doing.

 

I discovered  function called "SerialEvent" which is automatically executed at the end of every loop. Because of that, it is important to reduce the delays in the loop to a minimum, as this will delay the processing of the incoming serial messages. You can find more on SerialEvent here: Arduino - SerialEvent

 

My SerialEvent call looks like this:

 

String inputString = "";
boolean stringComplete = false;

void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;

    if (inChar == '\n') {
      stringComplete = true;
    }
  }
  if(inputString == "light=OFF"){
    digitalWrite(13, LOW);
  }
  else if (inputString == "light=ON"){
    digitalWrite(13, HIGH);
  }
  inputString = "";
  stringComplete = false;
}

 

In short, it will expect incoming messages equal to "light=ON" or "light=OFF" and update the status of the onboard LED accordingly.

 

OpenHAB rule

 

In OpenHAB, I defined an item called "Arduino" earlier, making use of the serial binding. This same item can be used to send data back to the Arduino, via the same serial binding.

I added an additional switch, which is meant to turn a light on or off in order to increase visibility in the Pi camera.

 

All that is needed after that is a rule that will send the expected command to the Arduino, based on the switch's state.

 

rule "Video Light"
 when 
     Item camera_light changed
 then
      var state = camera_light.state as OnOffType
      sendCommand (Arduino , "light=" + state)
end

 

With Arduino and camera_light defined as follows in the items:

 

String Arduino "Arduino [%s]" (arduino) {serial="/dev/ttyACM0"}
Switch camera_light "Video lighting" <video>

 

Test

 

With everything set up, it's time for testing!

 

Reorganising the sitemap, this is the current structure I came up with for the food/water dispenser:

image

It's populated with dummy data generated by the Arduino, until the real sensors are hooked up. The button for the light has been put just above the video, as this seemed most practical.

 

In the video below, I demonstrate the action of turning the light on and off while the camera is filming the onboard LED of the Arduino. Later on, this can trigger an LED strip, white LEDs or even IR LEDs (in combination with Pi NoIR).

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

Conclusion

 

In the past weeks, I spent a lot of time exploring OpenHAB. I've played with domains such as data collection, persistence, video, etc ...

I can now start the actual build of the project, as the software side mechanisms have been figured out and found to be working!

 

Some blog posts have been prepared to be published during my absence in the coming two weeks. The focus will gradually be shifting to the hardware side of the project.

 

Until next time!

  • Sign in to reply

Top Comments

  • mcb1
    mcb1 over 11 years ago +1
    Very nice. Boy have you been a busy Minion. Good luck with the other project and yes " would not appreciate it if I dared to take my laptop along on our honeymoon " you're probably going too far there…
  • vish
    vish over 11 years ago +1
    I'm getting married next week, and let's say my Minion bride would not appreciate it if I dared to take my laptop along on our honeymoon Wishing you a happy conjugal life! May you always find love and…
  • ravi_butani
    ravi_butani over 11 years ago +1
    Wishing you many many congratulations in advance.....
  • fvan
    fvan over 9 years ago in reply to 79kiko

    You could have the loop check for incoming ON/OFF while keeping track of the time.

    If 10 seconds have elapsed since last send, execute the additional function, else skip it.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • 79kiko
    79kiko over 9 years ago in reply to fvan

    I need change arduino code I want send temperatures every 10s from Arduino but ON/OFF from Openhab processed immediately in Arduino. Now I must wait 10s for processing ON/OFF in arduino.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fvan
    fvan over 9 years ago in reply to 79kiko
    How can I edit Arduino sketch?

     

    Can you clarify what you mean by "edit"? If you have communication between Arduino and OpenHAB, you have already programmed the Arduino, meaning you should be able to modify the sketch to suit your needs?

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • 79kiko
    79kiko over 9 years ago

    Hello, this guide is very good. Thank you. I have A Question. I have communication between Arduino -> OpenHab. I'm sending temperatures from Arduino to OpenHab and from OpenHab send status ON/OFF for relay in Arduino. I'm sending The Temperatures every 10s and then I have ON/OFF from Openhab every 10s and it is adverse. How can I edit Arduino sketch?

    Thank You

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • mcb1
    mcb1 over 9 years ago in reply to Former Member

    Cant i get the data directly in number form

    The serial connection sends an ascii representation of the number, hence it is a string.

    In other software you can define what the data you're receiving is, but obviously OpenHAB has been set to receive strings via serial.

     

    I don't have all the answers, but I'm sure if you follow what Frederick did it will work.

    It's just code  ...

     

    Mark

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube