Previous posts in this project:
Introduction
This post is mainly about setting a lot of things up: the Arduino Yun, the Infineon Shield, LED strips and the Raspberry Pi.
You can jump to the topic of interest using the table of content links above. Enjoy!
Arduino
Intro
This will be my first time working with the Yun. The thing that prevented me from getting one, was mainly the price: at approximately €70, it is not cheap!
But thanks to this Road Test, I can finally find out what the Yun is all about.
The UNO on the other hand is much more affordable (€30). It does not have the networking capabilities built-in, but is a great starting point for anyone interested in microcontrollers.
I've worked with it many times before, but haven't planned to use it in this project.
IDE
To find out more about the Yun, I headed over to the Arduino website's "getting started" page. At some point, it is mentioned that a special beta version of the IDE is to be used when working with the Yun.
Download and installation were straightforward.
OpenWrt
When scrolling further down the page, to the "other software" paragraph, there is another piece of software relevant for the Yun: an updated openWrt image.
OpenWrt is a linux distribution for embedded devices. If you want to learn more about OpenWrt, go to https://openwrt.org/.
The OpenWrt image for the Yun can be installed in two ways:
- using the web interface
- using the command line interface (via SSH)
You can find both procedures described in detail here: Arduino - YunSysupgrade
There are two ways to connect to the Yun:
- connect an ethernet cable to the Yun and have it receive an IP address via DHCP
- connect to the Yun wifi access point
Once connected via either way, you should be able to access http://arduino.local/
The following page should appear:
The password is not mentioned in the procedure. I first tried to log in without entering any password, but that was refused. Next, I tried "arduino" and I was in. Lucky guess I suppose
I pressed the big "RESET" button at the bottom of the page and waited for approximately 3 minutes for the upgrade to finish.
Once the onboard WLAN LED stopped blinking, I tried to connect to the Yun via the wired network. Unfortunately, that wasn't working, so I connected to the Yun's access point instead.
On the web interface, it reported the wired network was disconnected. I removed the ethernet cable and plugged it back in. The Yun then reported it was connected to the wired network. Strange ...
But, the Yun is now ready to go!
Infineon Shield
The infineon Shield comes without headers on the board, and none are included in the box either.
I find that rather strange. Someone buying a product usually expects to be able to use it right away, or at least have all the parts to do so.
On the other hand, this gives you the opportunity to choose your own set of headers: long, short, stackable, ...
I went for the extra long stackable headers, which I found online. I wanted to make sure there was enough clearance for the Yun's vertical USB port.
After soldering, I checked the shield with both the UNO and the Yun. Clearance was good!
One thing I missed is that my headers didn't were not for the correct number of pins, leaving the I2C pins unconnected.
And let that be the two pins required for communication with the Yun. So I came up with a small workaround to fix that.
Anyway, after the hardware, comes the software part.
It seems there is no library from Infineon available for this shield. They have a variety of examples on their website though.
Unfortunately, all example files have a ".exe" extension. Why ?? What about Linux and Mac OSX users? Plain ".ino" files would have sufficed.
Luckily, peteroakes came to the rescue with following blog post: BYOB Party #3, Infineon Library Available
He created a library to make our lives easier! Thank you, Peter!
I created a folder called "Infineon" in the libraries folder, and put his library files there. As such:
After restarting the Arduino IDE, the example was available.
Lights
I have to LED strips to experiment with:
- a non-addressable, 12V, 100cm, 60 LEDs strip (analog)
- an addressable, 5V, 100cm, 60 LEDs strip (digital)
The analog stip will be controlled using the Infineon shield. The digital strip will be controlled directly by the Yun, using Adafruit's NeoPixel library.
I ordered more online, but until then, this will have to do. Experimenting with both strips will allow me to prepare the code until the new strips arrive.
Analog
Connecting the analog LED strip to the Infineon shield was easy.
I stripped off the connector, tinned the wires and plugged them into the socket. On the other side, I did the same with a barrel jack connector.
The barrel jack connector is then attached to a 12V power supply.
Digital
I connected the digital LED strip to the Yun as follows:
The nice thing about these digital strips, is that they run on 5V, which can be used to power the Yun simultaneously. On top of that, the strip only requires one pin to be controlled!
I've prepared some animations for this strip:
- setting the even LEDs to a color and the odd ones to another and then toggling
- gradually fill up the LED strip with random colors
- ...
Here's a video of the animations in action:
The functions I created are the following, feel free to use/improve them if you want
As jancumps already pointed out to me, yes, there is a tiny bug in the last animation where the last LED doesn't light up. I'll fix that by next post
Function 1
// alternate between two colors on even and odd LEDs void alternateColor(uint32_t c1, uint32_t c2, uint8_t wait) { for(uint16_t i=0; i<dstrip.numPixels(); i++) { if(i%2 == 0) { // set even LED to color 1 dstrip.setPixelColor(i, c1); } else { // set odd LED to color 2 dstrip.setPixelColor(i, c2); } } dstrip.show(); // apply the colors delay(wait); for(uint16_t i=0; i<dstrip.numPixels(); i++) { if(i%2 == 0) { // set even LED to color 2 dstrip.setPixelColor(i, c2); } else { // set odd LED to color 1 dstrip.setPixelColor(i, c1); } } dstrip.show(); // apply the colors delay(wait); }
Function 2
// gradually fill up the strip with random colors void randomColorFill(uint8_t wait) { clearStrip(); for(uint16_t i=0; i<dstrip.numPixels(); i++) { // iterate over every LED of the strip int r = random(0,255); // generate a random color int g = random(0,255); int b = random(0,255); for(uint16_t j=0; j<dstrip.numPixels()-i; j++) { // iterate over every LED of the strip, that hasn't lit up yet dstrip.setPixelColor(j-1, dstrip.Color(0, 0, 0)); // turn previous LED off dstrip.setPixelColor(j, dstrip.Color(r, g, b)); // turn current LED on dstrip.show(); // apply the colors delay(wait); } } }
Function 3
// pick a random LED to light up until entire strip is lit void randomPositionFill(uint32_t c, uint8_t wait) { clearStrip(); int used[dstrip.numPixels()]; // array to keep track of lit LEDs int lights = 0; // counter for(int i = 0; i < dstrip.numPixels(); i++){ // fill array with 0 used[i] = 0; } while(lights<dstrip.numPixels()-1) { int j = random(0,dstrip.numPixels()-1); // pick a random LED if(used[j] != 1){ // if LED not already lit, proceed dstrip.setPixelColor(j, c); used[j] = 1; // update array to remember it is lit lights++; dstrip.show(); // display delay(wait); } } }
Function 4
// Light up the strip starting from the middle void middleFill(uint32_t c, uint8_t wait) { clearStrip(); for(uint16_t i=0; i<(dstrip.numPixels()/2); i++) { // start from the middle, lighting an LED on each side dstrip.setPixelColor(dstrip.numPixels()/2 + i, c); dstrip.setPixelColor(dstrip.numPixels()/2 - i, c); dstrip.show(); delay(wait); } for(uint16_t i=0; i<(dstrip.numPixels()/2); i++) { // reverse dstrip.setPixelColor(i, dstrip.Color(0, 0, 0)); dstrip.setPixelColor(dstrip.numPixels() - i, dstrip.Color(0, 0, 0)); dstrip.show(); delay(wait); } }
Function 5
// Light up the strip starting from the sides void sideFill(uint32_t c, uint8_t wait) { clearStrip(); for(uint16_t i=0; i<(dstrip.numPixels()/2); i++) { // fill strip from sides to middle dstrip.setPixelColor(i, c); dstrip.setPixelColor(dstrip.numPixels() - i, c); dstrip.show(); delay(wait); } for(uint16_t i=0; i<(dstrip.numPixels()/2); i++) { // reverse dstrip.setPixelColor(dstrip.numPixels()/2 + i, dstrip.Color(0, 0, 0)); dstrip.setPixelColor(dstrip.numPixels()/2 - i, dstrip.Color(0, 0, 0)); dstrip.show(); delay(wait); } }
Raspberry Pi
Intro
The Raspberry Pi will be responsible to run openHAB, which will be used to:
- control the LEDs connected to the Arduino
- report sensor data from the Arduino
The Pi will also be in charge of tuning in to an internet radio channel playing exclusively Christmas music.
Raspbian
First thing to do with the Raspberry Pi, is to prepare the SD card which will run the operating system.
1) Identify the SD card
Fredericks-MacBook-Air:~ fvan1$ sudo diskUtil list /dev/disk0 #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *251.0 GB disk0 1: EFI EFI 209.7 MB disk0s1 2: Apple_CoreStorage 250.1 GB disk0s2 3: Apple_Boot Recovery HD 650.0 MB disk0s3 /dev/disk1 #: TYPE NAME SIZE IDENTIFIER 0: Apple_HFS Macintosh HD *249.8 GB disk1 Logical Volume on disk0s2 5642627E-CEC4-458D-AB8D-376EF3FB568C Unencrypted /dev/disk2 #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *7.9 GB disk2 1: Windows_FAT_32 boot 58.7 MB disk2s1 2: Linux 7.9 GB disk2s2
2) Unmount SD card
Fredericks-MacBook-Air:~ fvan1$ sudo diskUtil unmountDisk /dev/disk2 Unmount of all volumes on disk2 was successful
3) Write image to SD card
Fredericks-MacBook-Air:~ fvan1$ sudo dd if=Downloads/2014-09-09-wheezy-raspbian.img of=/dev/disk2 bs=1m 3125+0 records in 3125+0 records out 3276800000 bytes transferred in 1596.406567 secs (2052610 bytes/sec)
4) Unmount SD card
Fredericks-MacBook-Air:~ fvan1$ sudo diskUtil unmountDisk /dev/disk2 Unmount of all volumes on disk2 was successful
The SD card is now ready and can be inserted in the Raspberry Pi. I connected the Pi to the network using an ethernet cable and powered it on.
After finding out the IP address via my home router, I SSH'ed to the Pi.
Fredericks-MacBook-Air:~ fvan1$ ssh pi@192.168.0.129 The authenticity of host '192.168.0.129 (192.168.0.129)' can't be established. RSA key fingerprint is 02:4f:ed:b3:42:1d:e5:83:1c:1e:2f:7f:63:83:9c:bd. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.0.129' (RSA) to the list of known hosts. pi@192.168.0.129's password: Linux raspberrypi 3.12.28+ #709 PREEMPT Mon Sep 8 15:28:00 BST 2014 armv6l The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. NOTICE: the software on this Raspberry Pi has not been fully configured. Please run 'sudo raspi-config' pi@raspberrypi ~ $
There is a clear notice asking to run the raspi-config tool to fully configure the Pi, so I did.
I used the "raspi-config" tool to:
- expand the filesystem
- enable SSH, I2C, SPI and camera (even though not all are needed for this project)
- change the hostname
- update the system
openHAB
OK, with the system set up and updated, the next step is to install openHAB.
Step 1: Download the openHAB files:
pi@raspberrypi ~ $ wget https://github.com/openhab/openhab/releases/download/v1.6.0/distribution-1.6.0-runtime.zip pi@raspberrypi ~ $ wget https://github.com/openhab/openhab/releases/download/v1.6.0/distribution-1.6.0-addons.zip
Step 2: Deploy the openHAB runtime and addons:
pi@raspberrypi ~ $ sudo mkdir /opt/openhab pi@raspberrypi ~ $ cd /opt/openhab/ pi@raspberrypi /opt/openhab $ sudo unzip /home/pi/distribution-1.6.0-runtime.zip pi@raspberrypi /opt/openhab $ cd addons/ pi@raspberrypi /opt/openhab/addons $ sudo unzip /home/pi/distribution-1.6.0-addons.zip pi@raspberrypi /opt/openhab/addons $ sudo mkdir unused pi@raspberrypi /opt/openhab/addons $ sudo mv *.jar unused/ pi@raspberrypi /opt/openhab/addons $ cd ../configurations/ pi@raspberrypi /opt/openhab/configurations $ sudo cp openhab_default.cfg openhab.cfg
Step 3: Make it executable:
pi@raspberrypi /opt/openhab $ sudo chmod +x start.sh
sudo /opt/openhab/start.sh &
MQTT
I activated the MQTT binding by moving it from the "unused" folder to the "addons" folder:
Then, I configured the broker settings in the "openhab.cfg" file:
#
# Define your MQTT broker connections here for use in the MQTT Binding or MQTT# Persistence bundles. Replace <broker> with a id you choose.#
# URL to the MQTT broker, e.g. tcp://localhost:1883 or ssl://localhost:8883
mqtt:eclipse.url=tcp://iot.eclipse.org:1883
# Optional. Client id (max 23 chars) to use when connecting to the broker.
# If not provided a default one is generated.
mqtt:eclipse.clientId=fvanPiOpenhab
The other parameters were left untouched.
OpenHAB still requires additional configuration files such as items and sitemaps. I'll focus on those in my next post.
Conclusion
With all of this already out of the way, I can start diving deeper in the actual configurations and actions of my project.