Today we are going to build a Xmas Light Control device based on Udoo board.
We are going to connect to Udoo: 4 RGB led stripes, 4 relays and a HDMI led projector.
Our project will implements the following features:
- control each led strip separately, with the possibility to set: fixed, fading, blinking and rainbow color mode.
- turn on/off at least 4 relays to control standard lights device
- play a video over HDMI channel to create a cool xmas atmosphere
To do this we need:
Hardware
First of all we prepare all the wire connections.
RGB Strip
All common RGB led strips works with a 12V power adapter so we need a led amplifier (lever shifter).
On the left plug this is the output coming from the UDOO.
- V+ ---> 3v3 reference
- R ---> red channel
- G ---> green channel
- B ---> blue channel
- POWER ---> the power plug ( can be also connect on the other side with separate wire)
On the right side we connect the led strip: color channels, and 12V power.
Relay
If we want to use or “hack” some old lights we should use some relays to switch the power.
We control the relays with 4 digital output.
Arduino
The Arduino sketch recieves 4 bytes commards from i.MX6 processor over serial.
We defined a custom protocol descibed below:
| byte 1 | byte 2 | byte 3 | byte 4 |
| OP_CODE | DATA_0 | DATA_1 | DATA_2 |
| ____ ____ | ____ ____ | ____ ____ | ____ ____ |
First byte contains the command type and strip or relay identifier.
# CMD_CODE #
# (byte 1) #
# OP_CODE | ID_CODE #
#MAIN_OP| SUB_OP| #
# __ __ | __ __ | __ __ | __ __ #
The other bytes contains data relatives to the command. For example the rgb components to play on led strips.
Last column indicates that this message will be processed only by i.mx6 side and not by sam3x microcontroller.
Every times that a 4 byte message comes to SAM3X it's parsed and it enable a led strip mode or switch a relay. At the beginning of Arduino sketch lot of constants are declared.to parse messages and decode the command.
Python script
The bridge between SAM3X and our smartphone is implemented by a python server listening over WiFi for UDP commands (it's in the Git repo under assets/udpserver.py). In fact our smartphone app will send messages containing commands for lights. When a messages come if it contains an OP_CODE encoding a REQUEST or a VIDEO command it is processed by the python script.
If there’s a different OP_CODE the message is forwarded to SAM3X microcontroller.
Let's describe how the script works. First let's import the necessary libraries.
import socket
import
serialimport
structimport
fcntl
Create a UDP socket.
try:
UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
print 'Socket created'
except socket.error, msg:
print 'Failed to create socket. Error: ' + str(msg[0]) + ' - ' + msg[1]
sys.exit()
Bind socket port.
try:
UDPSock.bind(("", 9002))
except socket.error, msg:
print 'Bind failed. Error: ' + str(msg[0]) + ' - ' + msg[1]
Set serial ports configuration.
ser = serial.Serial('/dev/ttymxc3',9600,timeout=1)
Flush the output to be sure that serial buffer is empty
ser.flushOutput()
Get our WiFi ip address.
ip_this = socket.inet_ntoa(fcntl.ioctl(UDPSock.fileno(),0x8915, struct.pack('256s',"wlan0"[:15]))[20:24])
This function launch a syscall with this command "set_alpha fb0 0". We need it to play a video in fullscreen mode with no desktop manager in background trasparency.
from subprocess import call
call(["set_alpha", "fb0", "0"])
Then we start a loop waiting for commands from our app.
while True:
First it reads four byte message from the socket (message size is fixed)
data, addr = UDPSock.recvfrom(4)
print data, ' ', addr[0], ' bytes: ', ord(data[3]), ' ', ord(data[2]), ' ', ord(data[1]), ' ', ord(data[0])
If message contains the string "ciao" we send to the source address our ip address. (ciao will be changed with a byte specific code).
if data == "ciao":
UDPSock.sendto(ip_this, addr )
If first byte is equal to 208 (11010000) it means that the last byte recieved is the id of the video to be played. So we get the video URI and launch a command that play a video at fullscreen.
elif ord(data[3]) == 208:
fileToPlay = "uri=file:///home/ubuntu/videos/" + str(ord(data[0])) + ".mp4";
from subprocess import call
call(["gst-launch-0.10", "playbin2", fileToPlay, "&"])
Otherwise messages will be forwarded to SAM3X over serial.
else:
ser.write(data)
ser.flushOutput()
Android
The Android app will connect over the WiFi and sends command to Udoo running the server.
When app starts it sends in broadcast mode over wifi a UDP message asking for the IP server address.
If a return message comes all other messages will be sent to this address.
The app is made by a main activity and three other activities, one for each service (led, relay, video).
In main activity we manage the wifi connection and the Udoo discovering system. By three button we can select the feature we want to change.
Led Activity got 4 tabs one for each strip. Here we can choose color and its playing mode.
In the relay activity we use buttons to switch between states.
In the video activity we can choose one of the video present on the board. For the moment the video are fixed, but we will update the project to show dinamically loaded videos on the Udoo.
Android Activities Description
MainActivity.java This is the main activity containing Udoo discover system and functions button.
RelayActivity.java From this activity we can switch relays state
VideoActivity.java From here we can choose the video that will be played.
LedActivity.java This activity it’s a container for 4 tab fragments representing one of each strip
LedFragment.java It contains the color selector and the buttons to launch light effects
HSVColorPickerDialog.java It’s an implementation of a color picker used in LedFragment
UDPClientBroadcastAsyncTask.java This task sends a broadcast request message over wifi and wait for an ip response from UDOO Xmas Python server.
UDPSendCommandThread.java It used to send udp command when a user choose an action
EkironjiDevice.java this class represent a Udoo device running our python script. When the service discover a Udoo it saves the server address. This object implements all methods useful to send commands to server
Setting up
First of all you need to create a UDOObuntu sd-card image.
Download sources from github.
Here you can find all Android app sources including Arduino sketch and python script.They are included in assets folder.
./assets/udpserver.py
./assets/udoo4xmas.ino
You need to download or copy them on the UDOO board in a custom location.
After that you should open .ino file with internal Arduino IDE and FLASH it into the SAM3X microcontroller.
Connect UDOO to home wifi.
You need to install a python library using this command:
sudo pip install pyserial
then you can start the server simply
python <PYTHON_SCRIPT_LOCATION>/udpserver.py
Then import Android project into eclipse and recompile the source code. You can also directly download .apk application and directly install from the smartphone.
Connecting wires
Videos
Open a terminal and create a folder called videos on ubuntu user home.mkdir /home/ubuntu/videos
Videos to be played must be put there named with sequencial numbers (e.g. 1.mp4, 2.mp4, etc...). By default the Android app launch 3 videos with a 'fixed' preview.
Future updates
Protocol updates
We want to add more features to this project as sensor reading (temperature, light, humidity...) so protocol listed in previous table should be updated.
Video list dynamically updated
For the moment the video list is static in the Android app. A video list will be sent to rhe app depending on the videos present in the videos folder.
Comments