I recently bought an Intel Edison arduino board. After blinking the on-board LED, I wanted to do something a bit more interesting but fairly simple. After reading up online, I decided on accelerometer based tilt sensing.
Why accelerometer you ask, well accelerometers are beginning to be used in a lot of new products (read fitbit, basis etc) and I was curious to learn how these sensors work and have some fun playing with them.
In this project, the Edison board connects to a computer over WiFi and
the computer displays a live plot of the board tilt angle. Connecting with WiFi helps free up the board so that it is not restricted by a wire connecting the board to the computer. This project has just seven components, the accelerometer is quite simple to use and the project can be easily built over a weekend. I hope that this will serve as a good starting point for other curious beginners.
Step 1: Collect the Building Blocks Needed
accelerometer breakout board(uses adxl335 chip)
Personal computer running windows/Linux
PyQtGraph(for data visualization)
MRAA library (simplifies reading of sensor data)
Step 2: Prepare Your Edison Arduino Board
1) Please follow the instructions in the intel getting started guide to get your board up and running. Note that you should follow all the steps including connecting to WiFi. Edison_gettingStarted_guide
2) Note down the IP address of Edison. We will need it later. One way to do this is to log into your board using serial COM and then typing "ifconfig" from commandline. See below. (please referto getting started guide on how to connect serially)
3) Log into Edison either serially or through WiFi and install MRAA library. (Note, MRAA is already on the Edison when you flashed it, but the version is out of date last time I checked. So, you need to perform this step).
echo "src mraa-upm http://iotdk.intel.com/repos/1.1/intelgalactic" > /etc/opkg/mraa-upm.conf opkg update opkg install libmraa0<br>
4) Connect the jumpers on the Edison board as shown in the figure above.
Note: This jumper setting configures the analog reference of ADC to be 3.3V. We will be powering our accelerometer from 3.3V later. So, by setting adc reference to 3.3V, we can get full range for adc.
Step 3: Make Hardware Connections
Use two rubber-bands to secure the breadboard onto the bottom-side of the board.
Secure the battery to the breadboard using one of the rubber-bands as shown in figure3 above.
Next, connect the accelerometer to the breadboard.
Connect the battery negative (black wire) to the GND female header on the board and the battery positive (red wire) to the VIN female header on the board. After this connection, you should see the onboard LED light up.
Now it is time to connect the accelerometer to the Edison board. The accelerometer has five pins: VCC, GND, X_out, Y_out, Z_out. Accelerometer gives analog voltage reading for each of the axes (X, Y, Z). We need to convert these values to digital numbers which can then be sent to the PC.
Edison arduino board has a 12 bit ADC with 6 channels (A0 to A6 on the board). We connect the accelerometer outputs to three of these channels for conversion to digital values.
Use male jumper wires to connect:
accelerometer VCC to 3.3V header on the board
accelerometer GND to GND header on the board
accelerometer X_out to A2 header on the board
accelerometer Y_out to A1 header on the board
accelerometer Z_out to A0 header on the board
Step 4: Calibrate the Accelerometer
MRAA is a cool library which provides API to access IO on Edison and other platforms. It really helps simplify the code you write by abstracting away low level details. Refer to the attached python code "accelerometer_calibrate_v1.py" to see how to use MRAA to calibrate the accelerometer. When it is run, it prints out the 3-point average of accelerometer voltage readings.
Each axis of the accelerometer has to be calibrated seperately. I will describe the calibration procedure for X-axis. Same procedure can be followed for Y and Z axes.
- You should have the accelerometer already attached to the Edison arduino board as described earlier. Open Putty and connect to Edison over WiFi.
- Orient the X-axis of the accelerometer so that it points vertically straight down at the ground and perpendicular to ground plane. In this position, X-axis is aligned with direction of earth's gravity. I wedged the board in-between two boxes on a table so that the board remained vertical. Run the "accelerometer_calibrate_v1.py" and note down the voltage. This is Vx+
Orient the X-axis of the accelerometer so that it points UP vertically and perpendicular to ground plane. In this position, X-axis is opposing the direction of Earth's gravity. Again run the calibration code and note down the voltage. This is Vx-
- Use the highlighted equations in figure3 to get offset-voltage and sensitivity for X-axis. Plug in the offset and sensitivity into the equation in figure4 to get the acceleration reading in g's.
Step 5: Send Accelerometer Data From Edison to PC Over WiFi
I used TCP for communication over WiFi using Python
Now, before I worked on this project, I had only heard about TCP/IP and socket communication but it was like a completely foreign language for me. I read up a little bit on TCP/IP specifically for this project. I learnt just enough to be able to make my Edison talk to my PC. Here is what I know. We need a server program running on edison and a client program running on PC. We also need to know the IP address of our server, which is Edison in our case and we need to assign something called PORT number (some big number like 5000) to be used in TCP communication.
Here is how it works. Server runs on edison and keeps waiting for connections. Once it receives a connection from the PC, it calls a handler function which reads accelerometer X, Y, Z axes values from ADC and sends this data to the PC. After that, it continues listening.
Client program runs on PC. It opens a socket, connects to the edison server, gets accelerometer data, processes this data to calculate the tilt angle and puts this data-point into a queue. The last datapoint in the queue is pushed out. After this, the client closes the connection to the server. The client program periodically repeats this whole process again and again. Also, the client creates a plot of tilt-angle on Y-axis and queue position on X-axis and updates this plot every time the queue is modified. As a result, X-axis is indicative of time and we can see how the tilt-angle evolves over time.
You can find the client and server programs at the end.
Step 6: Calculate Tilt and Display
Tilt angle is calculated based on the acceleration measurements along X and Z axes.
From the figure above, we can see that angle is calculated as tan-inverse of (-Ax/Az).
There is a function in python called atan2 which takes two arguments and gives angle between -pi and pi radians based on the sign and ratio of the arguments. Below is a code snippet showing the angle calculation implementation.
# convert accelerometer readings to angle in radians and then convert radians to degrees angle = math.atan2(Ax, -1*Az) * (180 / math.pi)
Note that the sign for Ax and Az are reversed from that shown in the
figure. This is intentional. It is needed because when the accelerometer is mounted on Edison board as described earlier, the front-face of the accelerometer board which has the adxl335 chip, is facing downwards while in the figure, I have made the calculations assuming it faces upwards. I did not realize this until I had assembled everything and then testing it out. I apologize if this creates some confusion as a result of my oversight.
For live display of tilt angle, we will be using PyQtGraph module. Here is a high level overview of how the display part works:
1) plot-area, axes etc are initialized
2) A function called update() is called recursively every 50 milli-seconds which starts a client socket, gets accelerometer data from server, processes it to calculate angle, displays on the graph and closes the socket. This occurs periodically every 50ms using a timer (called QTimer).
For more details regarding the software, please refer to the full implementation of client and server programs which I have uploaded in the next step.