Skip navigation

Hello, my name is Brandon Gilligan. I work for the website RFInspireD, which is a data collection database. Commonly used for RFID or barcodes, It can be used for lot's of different data collection including the weather. I did this project to show off what our website is capable of and I plan on having more projects to write about here soon. This was my first Arduino project and I had a blast with it. Really easy to set up and figure out, and you get quick results making it a really good project for beginners or weather enthusiasts. For the project I used SparkFun shields, sensors, and their own RedBoard. The RedBoard can be compared to an Arduino Uno and is programmed the same way. I would love some feedback or comments on my project. I am always looking to improve! You can read my full article at the home page of our website which I will provide a link for below. Thanks everyone!



During the Enchanted Objects design challenge I learnt quite a few things about the Arduino Yún, I thought I'd summarise and share them here. My posts in this challenge were all themed with a running story hence the strange titles.


Introduction to the Arduino Yún

Enchanted Objects Design Challenge - Yum Yum Yun at the Enchanted Cottage


Using the bridge and Curl to read pages over HTTPS

Enchanted Objects Design Challenge - Channels and a special delivery to the Enchanted Cottage


Python, Expanding the disk, using Requests library, Failure to install the Requests[Secure] library

Enchanted Objects Design Challenge - The snake, the troll and the fighting dwarves


Python and Pycurl reading HTTPS including checking the certificates

Enchanted Objects Design Challenge - Taming the Python


Turning off the Linino portion of the Yún to save power

Enchanted Objects Design Challenge - Sleeping Golem


A 3D printed adapter so that status LEDs can be seen from a top panel

Enchanted Objects Design Challenge - The Crystal Cave


Parsing the output of pretty-wifi-info.lua in Python

Enchanted Objects Design Challenge - This is not the WiFi you are looking for


Using the handshaking line to check if the Linino portion has booted

Enchanted Objects Design Challenge - A tale of two bridges


Swapping the bridge for a simpler serial communication

Swapping out the bridge


Security lockdown on the Yún

Enchanted Objects Design Challenge - Locking the doors


Starting and stopping a Python script in an init.d daemon

Enchanted Objects Design Challenge - Python Start, Python Stop


Thoughts on speeding up the booting process (not implemented)

Booting the Yún


All the code for the project is on github


I will share my design Step by Step from an Idea till working Project

see it here:




I am going do this small side project as a way to take a break from my main project.  For a basic introduction please see my original blog post at


If anyone has concerns about my project, please post them in that thread.  I have changed the design slightly after doing  some research and testing.  I am also going to have a control panel in the car with me so I can monitor things as well as manually test the lights.


The car has running lights, brake lights, and turn signals all on separate channels.  However the trailer lights only have 2 channels as the running lights also function as turn signals. My initial analysis was incorrect that the running lights also function as brake lights.


First a tentative parts list and then I will explain.

2X Arduino mini pros 16mhz boot loader

1X Raspberry Pi model B

1X 2.5" TFT touchscreen LCD

1X 4 channel mechanical relay

6X AMS1117 SO-223 5V regulators

3X NRF24L01+ wireless transceivers

1X 1.5 watt solar charger

3X enclosures

1X 20,000mAh (20Ah) 12V lead acid battery

1X hobbyking 5V/5A regulator

1X 1000 mAh 2s LIPO


Explanation of parts :

There are 3 units involved. We have the unit that reads the car's lights, the unit that controls the trailer lights, and the unit that acts as a control panel.  All 3 are connected via the wireless adapters.


2X Arduino mini pros 16mhz boot loader

These will be used for the units that read the lights and control the trailer lights.  I have some of these on hand is why I went with them and the small footprint will allow me to tuck it away nicely.


1X Raspberry Pi model B and 1X 2.5" TFT touchscreen LCD

This will function as the main control panel with a simple interface.  The Pi attaches easily to the LCD which is why I chose this route.  Its way overkill but I feel it will be useful for other projects that also need a remote or control panel.  The control panel will allow monitoring as well as manual control of the lights for testing.


1X 4 channel mechanical relay

The stock lights on my trailer pull 2A for the brakes lights per side, and 500 mA per side for the running lights.  Originally I was going to use a mosfet but I see no reason with this high of current.  The brake lights will be turned on at the same time so the relay will see 4A.  However the running lights will be on separate channels as they also function as blinkers.  The 4th channel I may use to turn on internal lights in the trailer remotely.


6X AMS1117 SO-223 5V regulators

These small regulators will be used to power the Arduinos off of the main 12V sources which come from the vehicle as well as the 12V battery in the trailer.  They are also used to read the  vehicle lights.  My plan is to splice into the lines of each light the same way I did before when installing an off the shelf light controller.  The lights will be routed to the 5v regulators which then step down the voltages to 5V for reading via the GPIO pins on the Arduino.  I will need 4 regulators to read the lights.  1 for the brake lights, 1 for the running lights, and 1 each for each turn signal.


3X NRF24L01+ wireless transceivers

These 2.4ghz transceivers are similar to an I2C connection and a serial connection combined.  Each one has an ID and you can broadcast information. I will have a small protocol in place for error correction as well as some minor tamper proofing.  I don't want a rogue 2.4ghz signal to be able to mess with my lights.  I will be using a command set that requires a sequence of bytes in order to validate commands.


1X 1.5 watt solar charger

These can be had from Harbor Freight and low cost.  I decided that the trailer might as well be "green" and charge its own battery.  Besides its just another thing for me to forget to do.


The rest of the items are self explanatory and used to house the items and power the Pi.


I may choose to get some LED based trailer lights, but I am going to stick with the stock trailer lights for now until I have a working project.

My previous post was devoted to the illustration of a digital magnetoresistive sensor. A digital sensor provides just two states: on and off. Such sensors, then, can only tell you if there is a strong enough magnetic field close to the sensor or not.


In this post I'm going to illustrate the usage of a digital compass, namely a device from Digilent called PmodCMPS, to measure the intensity of a magnetic field. The device uses the HMC5883L digital compass IC from Honeywell to measure the three components of a magnetic field along three orthogonal axis.


A magnetic field is a vector field, i.e. it has three components that can be measured along three non parallel axis. Usually those axis are taken as orthogonal to each other. The digital compass is a chip embedded, as usual, in a box and measures the intensity of the magnetic field along the axis aligned along its edges, using the principle of magnetoresistance, briefly illustrated in the previous post. Thanks to its 12 bits ADC's, it provides a very good resolution of 2 mG, and can measure fields up to 8 G. The symbol G stands for Gauss, one of the units to measure magnetic fields. The standard unit is the Tesla (T): 1 T correspond to 10000 G. The average geomagnetic field, exploited by mariners using magnetic compasses, has an intensity of about 0.5 G, i.e. 0.05 mT (milli-Tesla). Common NMR (Nuclear Magnetic Resonance) apparatus use magnetic field of the order of 1-1.5 T.


The Digilent device integrates the digital compass IC with a circuit that allows the user to read the three ADC's value using I2C, one of those many serial protocols to exchange data. A serial protocol is a way to send and receive data between a CPU and a peripheral device using just one single line (an electrical wire) called SDA (Serial DAta). Binary digits travel along this line one after the other in both directions. The communication being serial, it is important that each bit is transferred along the line at regular time intervals. A second line, called SCL (Serial CLock)  is then employed to provide a clock signal allowing both transmitter and receiver to schedule the transmission/reception of signals properly. In order to use the device, then, you just need to feed it with 5 V, and connect the two I2C lines to an I2C enabled device such as an Arduino. The device (in the picture) comes with four pins: two of them must be connected to the ground (GND) and 5 V, respec2366446-40.jpgtively, while the other two pins are marked as SDA and SCL for communication.


You can connect these four pins to the corresponding pins on an Arduino board. The I2C pins location on Arduino depend on the board flavour. On the most popular Arduino UNO board they correspond to A4 and A5 pins. In this post, however, we are going to show how to use the digital compass using an Arduino Leonardo board, where the I2C pins are located on digital pins 2 and 3. See the Arduino - Wire page for details bout other Arduino flavours. The reason for using the Leonardo board is that it comes with built-in USB communication capabilities that makes it appear as an USB keyboard or mouse to a computer, hence we are going to use this feature to show the magnetic field vector on the screen.


First of all, connect the four pins of the digital compass to the corresponding pins on Arduino, then open the Arduino IDE, select the proper port and board, if needed, and start coding. In the picture below you can see the four cables connecting the Arduino board to the device. The need for the fifth (red) cable connecting the 3.3 V pin of the Arduino with its A0 pin is explained below.




To communicate with an I2C device you need to use the Wire library, including the Wire.h header file in the sketch. In the setup() method initialise the library using the following code

void setup() {
  Wire.write(0x02); //select mode register
  Wire.write(0x00); //continuous measurement mode


where ADDRESS has been defined as a constant with

#define ADDRESS 0x1E 


Here 0x1E is the address of the device, as defined by the producer (see the data sheet). The beginTransmission() method tells the Arduino to send data to the I2C device whose address is specified. Data travel then from Arduino to the device until the communication is closed with endTransmission(). We use the write() method to send data over the line. In this case data represents commands or instructions given to the device. I2C device can be controlled via a number of registers, i.e. memory locations on board. Register 0x02 is the mode register, that can be used to configure the working mode of the device. We select the 0x00 mode, corresponding to continuous measurement (those information are found on the data sheet of the device). Now the device starts measuring the magnetic field continuously and we can read the values in the loop(). At its beginning, it reads as follows:


void loop() {
  int x,y,z;
  Wire.write(0x03); //select register 3


Looking at the data sheet, we can see that registers from 3 to 8 contain the data output. Each axis reading is represented by two bytes: there are then three bytes pairs, the first containing the most significant bits of the data and the second the least significant ones. Writing on register 3 we tell the I2C to send us the data contained in it. We should then be ready to receive the data. To do that we use the requestFrom() method. It has two parameters: the address of the device and the number of registers whose content must be transmitted.  The read() method, then, obtains the data when the device is ready to transmit it:

  //Read data from each axis, 2 registers per axis
  Wire.requestFrom(ADDRESS, 6);
  if(Wire.available()) {
    x = * 256;
    x +=; 
    z = * 256;
    z +=; 
    y = * 256;
    y +=; 


The first pair to be read is the one containing the value of the magnetic field measured along the x-axis of the device. As said, it is composed of two bytes of which the first is the most significant. The value of this component of the field is then the one read from the first register multiplied by 256, to which we add the value of the second. The second pair contains the value of the field measured along the z-axis, while the last two bytes contain the value of the field measured along the y-axis.


One can then obtain the intensity of the magnetic field computing its magnitude using Pythagoras' theorem, as the square root of the sum of the squares of x, y and z components. Our purpose, however, is to graphically represent the vector in space on the screen of our computer. To do that we exploit the capability of the Leonardo board to simulate a keyboard. We must properly format the data, transforming them into a set of characters to be transmitted to the computer.


Data come in the form of 12-bits integer numbers. For the purpose of illustrating another useful function we are going to scale them of a factor 1000, then convert them into string. We do that with

  char xstr[6];
  char ystr[6];
  char zstr[6];
  dtostrf(0.001*x, 5, 2, xstr);
  dtostrf(0.001*y, 5, 2, ystr);
  dtostrf(0.001*z, 5, 2, zstr);


the dtostrf() function takes four arguments: a floating point number, the maximum number of digits to be use to represent it, the number of non-integer digits to be shown and the address of a long enough array of characters to store the result. We then take each value, multiply it by 0.001, and store its character representation in array of characters with exactly two non-integer digits. The numbers will be then represented with five characters of which two are used for the non-integer part, one for the decimal period and the remaining two for the integer part. We then need arrays made of 6 characters: one of them, in fact, has to be used as the terminator character of the string (the NULL character, marking the end of the string).


In order to show the vector representation on the screen we use GeoGebra: an open source mathematics software freely available for download. With GeoGebra you can draw vectors on screen in a variety of ways, of which one is the following: open the 3D graphics view, then define the origin as a point whose coordinates are (0,0,0) typing in the input box




The, define a second point initially with the same coordinates




Now you can define a vector typing


vector(O, A)


You should see nothing on screen, since the vector length is zero, but if you change the coordinates of A you can see an arrow starting from the origin of the reference frame and terminating on the point located by A.


With this method we can now use the Leonardo board as the input device for GeoGebra: we simply tell it to send characters to the computer on which GeoGebra is running containing the command to define the coordinates of point A:

  sprintf(cmd, "A=(%s,%s,%s)\n", xstr, ystr, zstr);
  int l = strlen(cmd);
  int ok = analogRead(A0);
  if (ok > 400) {
    for (int i = 0; i < l; i++) {


The first sprintf() statement format a cmd string, defined as a long enough array of characters, such that the resulting string will be A=(x,y,z) where x, y and z are the content of the xstr, ystr and zstr obtained above, i.e. the readings of the compass. The second argument of sprintf tells it how to interpret what follows: normal characters are inserted in the string as such, while characters preceded by a % sign are interpreted as descriptors. The %s descriptor tells sprintf() to interpret the following parameters as strings. In plain C, the descriptor can be used to format floating point values, where n and m are, respectively, the size of the field and the number of non-integer digits to show (we should have used %5.2f). However such a descriptor is not available on Arduino and we are forced to use dtostrf().


The "\n" characters at the end of the string represent the newline character.


We can then transmit each character forming the string to the computer as if they come from a keyboard with the for loop, that takes each character in the string and transmit it over the USB cable. If the pointer of the mouse has been previously located in the GeoGebra input box, those characters are entered as if they were pressed on a keyboard and the position of the A vector changes continuously if we change the orientation of the digital compass device. Changing A makes the vector to change, as can be seen from the movie below.



We are now going to explain the reason for having the fifth cable on the Leonardo board. Imagine you upload a sketch on the board emulating a keyboard: next time you connect the same board to a computer it starts emulating the keyboard and you can no more type anything on any window. You can, in fact, type characters from your real keyboard, but they will be mixed with those typed by the Leonardo board!


You need a method to suppress this behaviour. In the snippet above you can see that we emulate the keyboard only if the analog reading of the A0 pin of the Arduino board exceeds a given threshold. Leaving the A0 pin disconnected (or better, connected to ground) prevents the board to behave like a keyboard. You can then plug the Arduino to your computer, set up GeoGebra, click on the input box, then connect the 3.3 V pin of the board to the A0 pin: the analog read returns a number close to 3.3×1024/5≈676 and the board starts behaving like a keyboard.


If you make the mistake of uploading a sketch that prevents you to use the board because it continuously transmit characters as a keyboard, scrambling your sketch as soon as you try to upload it, you can reset the board as follows: prepare a simple sketch with just empty setup() and loop() methods, then press the RESET button on the board and, keeping that button pressed, attach the board to the computer using the USB cable. Now, still keeping the RESET button pressed, click on the upload icon on the Arduino IDE and release the RESET button as soon as the word "Uploading..." appears. It may not work soon, because it depends on how fast you are: you can succeed easier if you release and press the button very fast twice.

Filter Blog

By date: By tag: