Magnetic Heading Sensor
- A magnetometer. Eg: HMC5883L
For any general motion, more specifically in aerodynamics, we can characterize the angular motion into three mutually perpendicular axes. These axes are called axes of yaw, pitch and roll. The following image will make it more clear to appreciate.
While the roll and pitch data for angular acceleration and velocity and hence angle of orientation can be provided by an Accelerometer and Gyroscope combination such as the very popular MPU-6050, the yaw angle is much harder to get. The main angle data in roll and pitch directions comes from the components of gravitational forces in the direction, and by using a filter for the data from both sensors we get a fairly accurate guess on the angle. But in the yaw axis, there is no component of a measurable constant force. The only way to find an angle is to integrate the angular velocity to find angle, but over time the integration constants add up and the angle becomes highly inaccurate. In that case for finding out Yaw data, we can use the constant magnetic field of earth as a reference. As a N-S bar magnet always points to the magnetic north and magnetic south of the Earth, the magnetometer uses the data with certain modifications on magnetic declination and is able to accurately determine the angle relative to north the sensor is making.
The most common magnetometer available in the market is the HMC5883L. It enables accurate yaw data with error of max 1 degree. The magnetometer communicates with the interfacing microcontroller using a the I2C interface. The I2C is a simple two wire interface that allows for connection of (2^7)-1 devices on the same 2 wires namely SDA (Serial Data) and SCL (Serial Clock). The Microcontroller which generates the clock on the SCL is called the master. The device that is connected to the microcontroller is called the slave
The I2C would only lead to us getting the raw data from the Magnetometer. For the sake of converting into usable, yaw angle data, we use the library Adafruit HMC5883L which is a part of Adafruit Sensors for Arduino Library. Download it from this link.
Also you would require the HMC5883L module of their I2C Sensors library for Arduino. Download it from this link.
Library installation is simple. If on Windows, copy to the installation directory of Arduino/libraries in a separate folder. If on Linux, copy in the libraries section of sketchbook folder in both root and non root environment. I’ve personally seen that root environment in Linux is better for programming microcontrollers.
Once done, burn the test program from File>Examples>Adafruit_HMC_5883U to your board, connect the 3.3V,GND, SDA and SCL to the magnetometer and the Serial monitor upon firing up would show the readings of yaw angle along with components of magnetic fields in X,Y and Z directions. As a matter of fact, you would have to update the declination angle mentioned in the code to the angle at the place where you live.
Now that we know how to use the magnetometer to give accurate heading information relative to magnetic north, here’s a simple program that is one the many applications of this sensor, a servo motor, following your hand angle.
IR signal receiver and Decoder
Hardware Required: A TSOP1738 IR receiver
VS: 5V DC
Out: This is the pin from where the signals are sent to our micro controller.
IR signals are transmitted in pulses with different “on” and “off” time periods to transmit binary data in a 38kHz carrier signal. This particular receiver outputs the “on” and “off” signal by extracting it out from the 38kHz signal. The period of “on” and “off” can then be calculated using a microcontroller to give us the binary signal received. This binary signal is then converted to hexadecimal signal for easy reference.
We will be using the following library from receiving and converting the IR signal in Arduino
The following is an example code to receive simple output the Hex signal
The arena in the event will be publishing the information through the IR signals. We use “NEC” protocol for the transmission. This protocol tells us how to extract the binary data from the signal based on the “on” and “off” times of the signal we receive. The above library used for Arduino can understand the NEC protocol and it will do the extract the binary data and then convert it to HEX for you. But it is a very standard protocol and you can find tutorials online to use it incase you don’t use a library.
NEC IR Code Format
The NEC message format is quite a bit more complicated then that of Sony. It is always a 32-bit code. Which consists of 16 bits of data and 16 bits of error checking. The code is divided into four 8-bit fields.
|Device Code||Device code compliment||Function code||Function Code Compliment|
A device code will be in the range of 0 to 255 or 256 discrete device codes. The same is true of the function code. The compliment fields are the 1’s compliment of the code they represent. The device code and the device code compliment must add up to 255 or else there is an error. The same is true of the function code and the function code compliment.
In the event Sherlock, we would use NEC protocol. Since NEC protocol transmits 32 bit of data where 16 bits are real data and the other 16 bits are the 1s complement of real data used to check error during transmission. As mentioned above the distribution of bits are as follows.
8 bits: Device Code, next 8 bits for the complement of device code. The next 8 bits for function code and the following 8 bits are complement of device code.
To transmit heading which has a maximum value of 359, we need to use minimum on 9 bits. Hence we use 8 bits each from the device code and the function code together to get 16 bits for transmission. For example we need to transmit 359.
Binary of 359 is 0000000101100111.
Divide it into two 8 bits chunk 00000001 01100111
Write the 1s compliment of each chunk to its side.
00000001 11111110 01100111 10011000
Hence this is the binary we need to send as NEC: 00000001 11111110 01100111 10011000.
This binary number can then be converted to a hexadecimal number for easy reference.
The hexadecimal for the above binary code is 01FE6798
A sample Arduino code is shown below to convert heading to hex and vice versa.
In the code, we use Ken Shirriff’s IR library for Arduino.
Follow this link to learn more about the library and circuit connections as recommended by it. http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html
Sample code for IR Transmistter
The following is the Arduino Code to transmit encoded angle values through IR LED. This is a sample code for the IR transmitters that we would be using in the arena.