For many years my daughter called me in the evening in her room: “Daddy, please play the barrel organ!”
I usually asked: “How fast?”
And she replied: “Full speed!”
Okay.
After about ten years – my hands have become old and tired – I knew that I need a machine. I spoke to my daughter and we began to make plans.
After hours of thinking we built a prototype with some toys:
And this is the funny result!
Attention: first you will hear nothing (or some noise from my stomach). Only when I touch my smartphone, you will hear LED ZEPPELIN! Yeah!
Here are some detailed images:
The ingredients for our openHAB Raspberry Pi Arduino XBee Led Zeppelin Music Machine:
- HABDroid running on a Samsung Galaxy smartphone
- a Raspberry Pi
- with a XBee USB dongle
- the openHAB runtime (extended with a custom XBee Binding)
- an Arduino UNO
- with a motor shield
- a wireless shield (with a XBee module fitted)
- an electric motor
- a barrel organ
The sequence of events:
- my finger pushes the “Led Zeppelin on/off” switch on the HABDroid app on my smartphone
- HABDroid sends the event over my WLAN to the openHAB runtime running on the Raspberry Pi
- my openHAB binding receives the event, connects to the XBee USB dongle and sends “1” (0x31)
- my Arduino UNO receives the “1” over the XBee receiver item on the Wireless Shield
- my Arduino UNO sends “full speed” to the connected electronic motor
- the electronic motor starts and drives the barrel organ
Here is a very basic list of what you have to do if you want to build the same crazy thing:
- Install openHAB on a Raspberry Pi (must be connected to a LAN because we want to use HABDroid on a smartphone to control the openHAB runtime) – s. notes for openHAB
- Plug a XBee USB dongle into the Raspberry Pi – s. notes for XBee
- Do some Linux configuration on your Raspberry Pi – I use Raspbian – s. notes for Raspbian
- Configure your openHAB runtime to provide a switch for HABDroid – s. notes for openHAB
- Install a Java IDE for coding your custom XBee openHAB Binding for sending data over the XBee USB dongle and export it to your openHAB installation – s. notes for openHAB
- Place your Arduino UNO with a Motor Shield and a Wireless Shield (with a XBee module fitted)
- Install the Arduino IDE to create the “XBee” code and upload it to your Arduino – s. notes for the Arduino UNO
- Find a solution for how you can connect your Motor Shield to an electric motor and finally to the barrel organ.
- Think like a hobbyist and leave your family for two weeks to get it work!
Notes for Xbee:
For wireless commication between Raspberry Pi and the Arduino UNO we use two XBee modules. One as ZigBee Coordinator, the other one as ZigBee Router, both in API mode.
TIP: if you want to configure and test the XBee modules in a comfortable way, do it with the XCTU GUI! Here’s a screenshot:
Notes for Raspbian (or the OS which you run on your Raspberry Pi):
- Install Rxtx: sudo apt-get install librxtx-java – this installs librxtxSerial.so into /usr/lib/jni which we need for our XBee communication
- find our where your XBee USB dongle is mounted. In my case it is: /dev/ttyUSB0
- go to /dev and find out the group name of your XBee USB dongle. In my case it’s the group dialout
- add your openhab user to the dialout group
Notes for openHAB:
Edit the openHAB start scripts on your Raspberry Pi. In my case: /usr/share/openhab/bin/openhab.sh
You’ll find a part like this one:
JAVA_ARGS_DEFAULT="-Dosgi.clean=true \
-Dgnu.io.rxtx.SerialPorts=/dev/ttyUSB0 \
-Declipse.ignoreApp=true \
-Dosgi.noShutdown=true \
-Djetty.port=${HTTP_PORT} \
-Dopenhab.configfile="${OPENHAB_CONF_DIR}/configurations/openhab.cfg" \
-Dopenhab.configdir="${OPENHAB_CONF_DIR}/configurations" \
-Dopenhab.logdir="${OPENHAB_LOG_DIR}" \
-Dsmarthome.userdata="${OPENHAB_USER_DATA_DIR}"
-Djetty.home="${OPENHAB_DIR}" \
-Djetty.port.ssl=${HTTPS_PORT} \
-Djetty.config="${OPENHAB_CONF_DIR}/jetty" \
-Djetty.logs="${OPENHAB_LOG_DIR}" \
-Djetty.rundir="${OPENHAB_DIR}" \
-Dfelix.fileinstall.dir="${OPENHAB_DIR}/addons" \
-Dfelix.fileinstall.filter=.*\\.jar \
-Djava.library.path="${OPENHAB_DIR}/lib:/usr/lib/jni" \
…
[/plain]
- I added the line starting with “-Dgnu.io.rxtx.SerialPorts” (don’t forget to use the name of your XBee USB dongle mounting)
- and I extended the java.library.path parameter with the /usr/lib/jni path (s. below Rxtx installation)
The sitemap configuration:
[plain] Frame label="Music Machine" {Switch item=MusicMachineSwitch label="Led Zeppelin on/off"
}
[/plain]
My items configuration:
[plain] Switch MusicMachineSwitch "Xbee Music Machine Switch" { mzxbee }[/plain]
My setting for the openhab.cfg:
These are some configurations, which I use in my Java code. I want to communicate with 9600 baud, the mounting point for my Xbee USB dongle is /dev/ttyUSB0 and the MAC address of the receiver is “00 13 A2 00 40 A2 5A EC”
mzxbee:comPort=/dev/ttyUSB0
mzxbee:address=0013A20040A25AEC
[/plain]
For our custom XBee openHAB Binding we use this Java API:
XBee Java Library
Here’s the important part of the Java code:
[java]logger.debug("Instantiating device with comPort " + comPort + " and " + baud + " baud…");XBeeDevice myDevice = new XBeeDevice(comPort, baud);
logger.debug("Opening device…");
myDevice.open();
logger.debug("Instantiating address…");
XBee64BitAddress addr64 = new XBee64BitAddress(address);
logger.debug("Instantiating RemoteXBeeDevice device…");
RemoteXBeeDevice myRemoteXBeeDevice = new RemoteXBeeDevice(myDevice, addr64);
logger.debug("********************* Sending sync data: " + value + " > byte value: " + Character.digit(value,16));
myDevice.sendData(myRemoteXBeeDevice, new byte[]{ (byte)value });
logger.debug("Closing device…");
myDevice.close();[/java]
value can be 1 to turn the music machine on and 0 to turn it off.
Notes for the Arduino UNO
This is the code for the Arduino UNO. I want to let a LED blink, when the Arduino starts. The same LED shall light, when the music plays.
[c] #include <XBee.h>int incomingByte = 0; // for incoming serial data
int dirA = 12;
int brake = 9;
int mspeed = 3;
const int led = 7;
Rx16Response zbRx = Rx16Response();
XBee xbee = XBee();
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
xbee.setSerial(Serial);
pinMode(led, OUTPUT);
pinMode(dirA, OUTPUT);
pinMode(brake, OUTPUT);
pinMode(mspeed, OUTPUT);
// blink twice at startup
digitalWrite(led, LOW);
delay(1000);
digitalWrite(led, HIGH); // first blink
delay(50);
digitalWrite(led, LOW);
delay(200);
digitalWrite(led, HIGH); // second blink
delay(50);
digitalWrite(led, LOW);
}
void loop() {
digitalWrite(dirA, LOW);
digitalWrite(brake, LOW);
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
if(incomingByte == ‘0’){
digitalWrite(led, LOW);
analogWrite(mspeed, 0);
}
else if(incomingByte == ‘1’){
digitalWrite(led, HIGH);
analogWrite(mspeed, 255);
}
}
}
[/c]To-Dos:
- add speed control! More speed! Much more!
- … ideas …?
Comments 1
LOL! What an amazing project!
Made my day!