One month ago, Henryk, Claus and I’ve started Camel Labs project. This project provides some cool new stuff for IoT community based on Camel technology/project. The stuff are new IoT components to connect electronics devices (i2c,SPI,gpio, tinkerforge) and cloud (pubnub, cloudlet, mqtt) together. In this lab, we will show how to build an end to end IoT integration with i2c device, mqtt broker and i2c lcd with few line of code.
Lab i2c sensor + gpio LED + mqtt broker + i2c LCD over RaspberryPi
In this lab, we will build two Camel routes
- 1/ to poll accelerometer informations every 2s, blink a LED on each message and send message mqtt topic
- 2/ to receive message from mqtt topic, check Z value to set header with specific color and display msg via i2c LCD device
Prerequisites
For this lab, you will need the following stuff :
- 2/two Raspberry Pi (Buy one)
- Tested with : B model and B+
- Should work with : A, A+, B+, 2B
- on same vlan
- Raspbian OS installed (Download)
- 1 - LED
- 1 - 220 Ω (ohms) Resistor
- Wires
- 1 - Breadboard
- 1 RGB LCD 16x2 Available
- 1 Accelerometer LSM303 Available
- 1 ActiveMQ default installation Installation & Configuration
Setup your Raspberry Pi
Be carefull with your device, please shutdown power before wiring. Check twice before powering on or you could damage your device.
Follow wiring for Accelerometer and RaspberryPi part:
Warning
I am using LSM303 from Adafruit, but the wiring looks the same
Follow the simplified wiring for LCD and RaspberryPi part:
Warning
With RGB LCD 16x2 from Adafruit, you just have to plug LCD component directly to RaspberryPi
You can test your wiring with wiringpi library
Install Pi4j library
First, let’s install Pi4J library.
Currently 1.0 version is available directly for RaspberryPi
$> ssh ${PI_USER}@${PI_HOST}
pi@rbpi> curl -s get.pi4j.com | sudo bash
Info
you should use a Public/Private key authentication for a faster connection to your RaspberryPi.
More information about installation here
Compile Raspberry Component
Component is still under developpement. Please feel free to test and send your feed back. Some stuff could change anytime (URI for example).
The better place to build camel-raspberry component is on your personal computer. RaspberryPi is be too slow to compile.
Checkout code and build it :
$> git clone https://github.com/camel-labs/camel-labs.git
You need to compile Accelerometer part program Accel2MQTT to iot/components/camel-pi4j/src/main/java/com/github/camellabs/component/pi4j directory
You need to compile LCD part program MQTT2LCD to iot/components/camel-pi4j/src/main/java/com/github/camellabs/component/pi4j directory
Compilation command line
$> mvn package -Dmaven.test.skip=true -P CopyDependencyforLab
Push binaries to RaspberryPis
Copy jar and dependencies files to your two Raspberry Pi devices.
$> ssh ${PI_USER}@${PI_HOST_ACCEL} 'mkdir -p /home/pi/camel'
$> scp iot/components/camel-pi4j/target/*.jar ${PI_USER}@${PI_HOST_ACCEL}:/home/pi/camel
$> ssh ${PI_USER}@${PI_HOST_LCD} 'mkdir -p /home/pi/camel'
$> scp iot/components/camel-pi4j/target/*.jar ${PI_USER}@${PI_HOST_LCD}:/home/pi/camel
Install program Camel Program to your Raspberry Pi
Copy log4.properties to ${PI_HOST}:/home/pi/camel directory
#
# The logging properties used
#
log4j.rootLogger=INFO, out
# uncomment the following line to turn on Camel debugging
#log4j.logger.org.apache.camel=DEBUG
log4j.logger.org.pi4j=ALL
log4j.logger.com.github.camellabs.component.pi4j=ALL
# CONSOLE appender not used by default
log4j.appender.out=org.apache.log4j.ConsoleAppender
log4j.appender.out.layout=org.apache.log4j.PatternLayout
log4j.appender.out.layout.ConversionPattern=%d{ISO8601} [%30.30t] %-30.30c{1} %-5p %m%n
#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
Start MQTT broker via ActiveMQ implementation
Run MQTT broker via command line below
$mqtt.acme.com> cd $ACTIVEMQ_HOME/bin
$mqtt.acme.com> ./activemq start
INFO: Loading '/Users/XXXXXX/Application/activemq/apache-activemq-5.11.1/bin/env'
INFO: Using java '/usr/bin/java'
INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details
INFO: pidfile created : '/Users/XXXXXX/Application/activemq/apache-activemq-5.11.1/data/activemq.pid' (pid '4958')
Start Up Accelerometer and mqtt sender part
The first part of this lab is to collect every 2s X,Y,Z values from accelerometer via I2C bus, flash a LED and send X,Y,Z vector to MQTT topic.
The command line
$> ssh ${PI_USER}@${PI_HOST_ACCEL}
pi@rbpi> cd camel
pi@rbpi> pi4j -r com.github.camellabs.component.pij4.Accel2MQTT
/dev/out from ${PI_HOST_ACCEL}
pi@rbpi8 ~/camel $ pi4j -r com.github.camellabs.component.pi4j.Accel2MQTT
+ sudo java -classpath '.:classes:*:classes:/opt/pi4j/lib/*' com.github.camellabs.component.pi4j.Accel2MQTT
19:45:30,979 [ main] Accel2MQTT INFO main
19:45:33,185 [ main] DefaultCamelContext INFO Apache Camel 2.15.2 (CamelContext: camel-1) is starting
19:45:33,200 [ main] ManagedManagementStrategy INFO JMX is enabled
19:45:36,620 [ main] DefaultTypeConverter INFO Loaded 188 type converters
19:45:38,347 [ main] GPIOEndpoint DEBUG Endpoint[pi4j-gpio://12?action=BLINK&mode=DIGITAL_OUTPUT&state=LOW]
19:45:38,353 [ main] GPIOEndpoint DEBUG Pin Id > 12
19:45:38,360 [ main] GPIOEndpoint TRACE Field 12 not found in class class com.pi4j.io.gpio.RaspiPin
19:45:40,048 [ main] DefaultCamelContext INFO AllowUseOriginalMessage is enabled. If access to the original message is not needed, then its recommended to turn this option off as it may improve performance.
19:45:40,050 [ main] DefaultCamelContext INFO StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
19:45:40,115 [ main] GPIOProducer DEBUG Starting producer: Producer[pi4j-gpio://12?action=BLINK&mode=DIGITAL_OUTPUT&state=LOW]
19:45:40,499 [ main] MQTTEndpoint INFO Connecting to tcp://mac-mini.autric.net:1883 using 10 seconds timeout
19:45:40,895 [ hawtdispatch-DEFAULT-1] MQTTEndpoint WARN No topic subscriptions were specified in configuration
19:45:40,909 [ hawtdispatch-DEFAULT-1] MQTTEndpoint INFO MQTT Connection connected to tcp://mac-mini.autric.net:1883
19:45:41,495 [ main] LSM303AccelerometerConsumer DEBUG Starting consumer: Consumer[pi4j-i2c://1/0x19?delay=500&driver=lsm303-accel]
19:45:41,620 [ main] DefaultCamelContext INFO Route: route1 started and consuming from: Endpoint[pi4j-i2c://1/0x19?delay=500&driver=lsm303-accel]
19:45:41,625 [ main] DefaultCamelContext INFO Total 1 routes, of which 1 is started.
19:45:41,651 [ main] DefaultCamelContext INFO Apache Camel 2.15.2 (CamelContext: camel-1) started in 8.478 seconds
19:45:42,624 [ thread #0 - pi4j-i2c://1/0x19] LSM303AccelerometerConsumer DEBUG [16,120,1069]
19:45:42,850 [ (camel-1) thread #1 - WireTap] GPIOProducer TRACE Exchange[Message: [16,120,1069]]
19:45:42,859 [ (camel-1) thread #1 - WireTap] GPIOProducer TRACE action= BLINK
19:45:42,930 [ thread #0 - pi4j-i2c://1/0x19] pi4j INFO Exchange[
, Id: ID-rbpi8-44586-1432064731732-0-2
, ExchangePattern: InOnly
, Properties: {CamelCreatedTimestamp=Tue May 19 19:45:42 UTC 2015, CamelMessageHistory=[DefaultMessageHistory[routeId=route1, node=wireTap1], DefaultMessageHistory[routeId=route1, node=to1]], CamelToEndpoint=log://com.github.camellabs.component.pi4j?multiline=true&showAll=true}
, Headers: {breadcrumbId=ID-rbpi8-44586-1432064731732-0-1}
, BodyType: com.github.camellabs.component.pi4j.i2c.driver.LSM303Value
, Body: [16,120,1069]
, Out: null:
]
19:45:43,630 [ thread #0 - pi4j-i2c://1/0x19] LSM303AccelerometerConsumer DEBUG [14,120,1071]
19:45:43,641 [ (camel-1) thread #3 - WireTap] GPIOProducer TRACE Exchange[Message: [14,120,1071]]
19:45:43,643 [ (camel-1) thread #3 - WireTap] GPIOProducer TRACE action= BLINK
19:45:43,642 [ thread #0 - pi4j-i2c://1/0x19] pi4j INFO Exchange[
, Id: ID-rbpi8-44586-1432064731732-0-6
, ExchangePattern: InOnly
, Properties: {CamelCreatedTimestamp=Tue May 19 19:45:43 UTC 2015, CamelMessageHistory=[DefaultMessageHistory[routeId=route1, node=wireTap1], DefaultMessageHistory[routeId=route1, node=to1]], CamelToEndpoint=log://com.github.camellabs.component.pi4j?multiline=true&showAll=true}
, Headers: {breadcrumbId=ID-rbpi8-44586-1432064731732-0-5}
, BodyType: com.github.camellabs.component.pi4j.i2c.driver.LSM303Value
, Body: [14,120,1071]
, Out: null:
]
19:45:44,220 [ thread #0 - pi4j-i2c://1/0x19] LSM303AccelerometerConsumer DEBUG [38,140,1069]
19:45:44,231 [ (camel-1) thread #5 - WireTap] GPIOProducer TRACE Exchange[Message: [38,140,1069]]
19:45:44,233 [ (camel-1) thread #5 - WireTap] GPIOProducer TRACE action= BLINK
Start Up MQTT reception and LCD display part
The second part of this lab receives X,Y,Z vector from MQTT topic, check Z value (STABLE or ERROR zone) change color for LCD, and send message to LCD.
The command line
$> ssh ${PI_USER}@${PI_HOST_LCD}
pi@rbpi> cd camel
pi@rbpi> pi4j -r com.github.camellabs.component.pi4j.MQTT2LCD
/dev/out from ${PI_HOST_LCD}
pi@rbpi2 ~/camel $ pi4j -r com.github.camellabs.component.pi4j.MQTT2LCD
+ sudo java -classpath '.:classes:*:classes:/opt/pi4j/lib/*' com.github.camellabs.component.pi4j.MQTT2LCD
19:45:33,277 [ main] MQTT2LCD INFO main
19:45:35,516 [ main] DefaultCamelContext INFO Apache Camel 2.15.2 (CamelContext: camel-1) is starting
19:45:35,530 [ main] ManagedManagementStrategy INFO JMX is enabled
19:45:38,969 [ main] DefaultTypeConverter INFO Loaded 188 type converters
19:45:41,902 [ main] DefaultCamelContext INFO AllowUseOriginalMessage is enabled. If access to the original message is not needed, then its recommended to turn this option off as it may improve performance.
19:45:41,903 [ main] DefaultCamelContext INFO StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
19:45:42,117 [ main] MCP23017LCD DEBUG doStart
19:45:43,007 [ main] MQTTEndpoint INFO Connecting to tcp://mac-mini.autric.net:1883 using 10 seconds timeout
19:45:44,655 [ hawtdispatch-DEFAULT-1] MQTTEndpoint INFO MQTT Connection connected to tcp://mac-mini.autric.net:1883
19:45:44,789 [ main] DefaultCamelContext INFO Route: route1 started and consuming from: Endpoint[mqtt://pi4j?subscribeTopicName=i2c/accel&host=tcp://mac-mini.autric.net:1883]
19:45:44,792 [ main] DefaultCamelContext INFO Total 1 routes, of which 1 is started.
19:45:44,843 [ main] DefaultCamelContext INFO Apache Camel 2.15.2 (CamelContext: camel-1) started in 9.314 seconds
19:45:45,120 [ hawtdispatch-DEFAULT-1] pi4j INFO Exchange[
, Id: ID-rbpi2-56870-1432064734049-0-2
, ExchangePattern: InOnly
, Properties: {CamelCreatedTimestamp=Tue May 19 19:45:44 UTC 2015, CamelMessageHistory=[DefaultMessageHistory[routeId=route1, node=process1], DefaultMessageHistory[routeId=route1, node=to1]], CamelToEndpoint=log://com.github.camellabs.component.pi4j?multiline=true&showAll=true}
, Headers: {breadcrumbId=ID-rbpi2-56870-1432064734049-0-1, CamelLCDBlinkCursor=false, CamelLCDColor=GREEN, CamelLCDCursor=false, CamelMQTTSubscribeTopic=i2c/accel}
, BodyType: String
, Body: [12,147,1064]
, Out: null:
]
19:45:45,128 [ hawtdispatch-DEFAULT-1] MCP23017LCD DEBUG >> Exchange[Message: [12,147,1064]]
19:45:45,403 [ hawtdispatch-DEFAULT-1] pi4j INFO Exchange[
, Id: ID-rbpi2-56870-1432064734049-0-4
, ExchangePattern: InOnly
, Properties: {CamelCreatedTimestamp=Tue May 19 19:45:45 UTC 2015, CamelMessageHistory=[DefaultMessageHistory[routeId=route1, node=process1], DefaultMessageHistory[routeId=route1, node=to1]], CamelToEndpoint=log://com.github.camellabs.component.pi4j?multiline=true&showAll=true}
, Headers: {breadcrumbId=ID-rbpi2-56870-1432064734049-0-3, CamelLCDBlinkCursor=false, CamelLCDColor=GREEN, CamelLCDCursor=false, CamelMQTTSubscribeTopic=i2c/accel}
, BodyType: String
, Body: [3,136,1066]
, Out: null:
]
19:45:45,407 [ hawtdispatch-DEFAULT-1] MCP23017LCD DEBUG >> Exchange[Message: [3,136,1066]]
19:45:45,965 [ hawtdispatch-DEFAULT-1] pi4j INFO Exchange[
, Id: ID-rbpi2-56870-1432064734049-0-6
, ExchangePattern: InOnly
, Properties: {CamelCreatedTimestamp=Tue May 19 19:45:45 UTC 2015, CamelMessageHistory=[DefaultMessageHistory[routeId=route1, node=process1], DefaultMessageHistory[routeId=route1, node=to1]], CamelToEndpoint=log://com.github.camellabs.component.pi4j?multiline=true&showAll=true}
, Headers: {breadcrumbId=ID-rbpi2-56870-1432064734049-0-5, CamelLCDBlinkCursor=false, CamelLCDColor=GREEN, CamelLCDCursor=false, CamelMQTTSubscribeTopic=i2c/accel}
, BodyType: String
, Body: [-3,133,1069]
, Out: null:
]
19:45:45,969 [ hawtdispatch-DEFAULT-1] MCP23017LCD DEBUG >> Exchange[Message: [-3,133,1069]]
..... OMIT ......
19:45:57,841 [ hawtdispatch-DEFAULT-1] pi4j INFO Exchange[
, Id: ID-rbpi2-56870-1432064734049-0-44
, ExchangePattern: InOnly
, Properties: {CamelCreatedTimestamp=Tue May 19 19:45:57 UTC 2015, CamelMessageHistory=[DefaultMessageHistory[routeId=route1, node=process1], DefaultMessageHistory[routeId=route1, node=to1]], CamelToEndpoint=log://com.github.camellabs.component.pi4j?multiline=true&showAll=true}
, Headers: {breadcrumbId=ID-rbpi2-56870-1432064734049-0-43, CamelLCDBlinkCursor=false, CamelLCDColor=YELLOW, CamelLCDCursor=false, CamelMQTTSubscribeTopic=i2c/accel}
, BodyType: String
, Body: [-67,-411,993]
, Out: null:
]
19:45:57,844 [ hawtdispatch-DEFAULT-1] MCP23017LCD DEBUG >> Exchange[Message: [-67,-411,993]]
Video finish
et voila !!!
NB : I change LCD color switch due of low cost camera :-(
GREEN is now ON, YELLOW is still YELLOW, RED is now OFF
Conclusion
As you can see, integration Camel Labs into RaspberryPi is really easy. BMP180 driver is available for temp and pressure, TSL2561 driver is available too for light sensor. The Java CAMEL DSL simplify code for assembling and integrating IoT devices. You can switch from MQTT broker to SOAP Webserivce easily with few refactoring. Raspberry Pi can integrate and assemble severals electronics (i2c) devices and protocols (i.e. MQTT) with Camel Iot Labs components with few line of code. Raspberry Pi and Camel Iot Labs can really rock !!!
More links
- more info about me
- a colleague blog Henryk Konsek (IoT, MQTT etc…)
- thx Olivier for LSM303 stuff
- thx Marcus Hirt for java LCD driver
- Camel Labs
- Pi4j library
- Raspberry Pi
- Apache-Camel