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

end-to-end

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.

You have to configure i2c module

Follow wiring for Accelerometer and RaspberryPi part:

Warning

I am using LSM303 from Adafruit, but the wiring looks the same

You can also use from Olivier LD this plan

Wire LSM303

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

For more information

Wire LCD

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 !!!