Contents:
Part2: Monitering Temperature with Xtrinsic Sensor <-- You are here
Part3: Capture sensor data to database ..
Once done with webserver i was looking out to measure temperature.
I found one xtrinsic sensor from a previous setup.
The Xtrinsic sensorXtrinsic sensor is available in community and has good support freescale MCUs.
Its an overkill to use xtrinsic for just temperature, but i thought to give it a try.
In fact its not an overkill, the Sensor board comes with multiple sensing stuff
MPL3115A2 - high-precision sensor used to provide accurate pressure and altitude data
MAG3110 - small, low-power, digital 3-axis magnetometer
MMA8491Q - low voltage, 3-axis low-g accelerometer
Setting up the Hardware
Lets start with the pin mapping of Xtrinsic and Riotboard.
For this setup we need 7 pins in Xtrinsic to be connected to Riotboard .
Pin Mapping
I am using Male-to-Female jumpers to connect Pins in Riotboard Expansion connector to Xtrinsic.
We will be bypassing the breadboard connection stuff to keep this simple.
Connecting female headers in Xtrinsic CN2 Connector.
Connecting female headers in CN1 Connector.
Connecting Male headers in Riotboard (J13)
My setup looks something like this ..
I wrote a small user-space driver to access the temperature sensor.
#include <stdio.h> #include <stdint.h> #include <linux/i2c.h> #include <linux/i2c-dev.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <string.h> static int write_register(int file,unsigned char address,unsigned char reg,unsigned char data) { unsigned char output_buffer[2]; struct i2c_rdwr_ioctl_data packets; struct i2c_msg messages[1]; messages[0].addr = address; messages[0].flags = 0; messages[0].len = sizeof(output_buffer); messages[0].buf = output_buffer; output_buffer[0] = reg; output_buffer[1] = data; packets.msgs = messages; packets.nmsgs = 1; if(ioctl(file, I2C_RDWR, &packets) < 0) { perror("Error sending data"); return 1; } return 0; } static int read_register(int file, unsigned char address, unsigned char reg, unsigned char *data) { unsigned char input_buffer, output_buffer; struct i2c_rdwr_ioctl_data packets; struct i2c_msg messages[2]; output_buffer = reg; messages[0].addr = address; messages[0].flags = 0; messages[0].len = sizeof(output_buffer); messages[0].buf = &output_buffer; messages[1].addr = address; messages[1].flags = I2C_M_RD; messages[1].len = sizeof(input_buffer); messages[1].buf = &input_buffer; packets.msgs = messages; packets.nmsgs = 2; if(ioctl(file, I2C_RDWR, &packets) < 0) { perror("Error sending data"); return 1; } *data = input_buffer; return 0; } int main() { int file, i; unsigned char data; int val1; int val2; int t_m; int choice; int DBG_ENABLE = 0; char string[200]; printf("Enable Debugging [1-Enable/0-Disable] :"); scanf("%d",&choice); if (choice == 1) DBG_ENABLE = 1; else if (choice == 0) DBG_ENABLE = 0; else { printf("Unknown choice \n Exiting... \n"); exit(1); } if ((file = open("/dev/i2c-3", O_RDWR)) < 0) { perror("Error openning file!"); exit(1); } if(DBG_ENABLE == 0) printf("Debugging Disabled \n"); else if(DBG_ENABLE == 1) printf("Debugging Enabled \n"); else printf("No idea"); //0x0C who_am_i , factory programmed device id if(read_register(file, 0x60, 0x0C, &data)) exit(1); else { if(DBG_ENABLE == 1) { printf("GET:Register[0x%02X]: 0x%02X\n" , 12 , data); } } //0x26 set ctrlreg1 ACTIVE if(read_register(file, 0x60, 0x26, &data)) exit(1); else { if(DBG_ENABLE == 1) { printf("GET:Register[0x%02X]: 0x%02X\n" , 38 , data); } } if(write_register(file, 0x60, 0x26, 0x03)) exit(1); else { if(read_register(file, 0x60, 0x26, &data)) exit(1); else { if(DBG_ENABLE == 1) { printf("SET/GET:Register[0x%02X]: 0x%02X\n" , 38 , data); } } } while(1) { //read temperature MSB/LSB if(read_register(file, 0x60, 0x04, &data)) exit(1); else { if(DBG_ENABLE == 1) { printf("Register[0x%02X]: 0x%02X\n" , 4 , data); } } val2 = (int)data; if(DBG_ENABLE == 1) printf("val2: initial :%d:\n",val2); val2 <<=8; if(DBG_ENABLE == 1) printf("val2: shift :%d:\n",val2); if(read_register(file, 0x60, 0x05, &data)) exit(1); else { if(DBG_ENABLE == 1) printf("Register[0x%02X]: 0x%02X\n" , 5 , data); } val2 = val2+ (int)data; if(DBG_ENABLE == 1) { printf("val2 :%d:\n",val2); } t_m = (val2 >> 8) & 0xff; printf("temperature :%d: \n",t_m); system(string); sleep(1); } close(file); return 0; }
A delay of 1 sec has been introduced to prevent ouput msgs flooding terminal window .
Compiling the program :
On Riotboard:
gcc xtrinsic_temp.c -o xtrinsic_temp
On PC:
<PATH_TO_TOOLCHAIN>/fsl-linaro-toolchain/bin/arm-fsl-linux-gnueabi-gcc xtrinsic_temp.c -o xtrinsic_temp
There are two ways to use the program:
1. Get Temperature as only output.
2. Enable debug to check register values (Just for fun) ..
Once Compiled we will execute . To access a device file "/dev/i2c-3" (check line 92 above ) we need to be root.
# ./xtrinsic_temp
It will ask for debug option.
Enter 0 to disable debugging (recommended)
Enter 1 to enable debugging.
Ok seems like we got the setup right
Testing a bit more.
We need :
- something very hot (I got a Soldering Iron)
- above setup
Identify the MPL3115 Sensor ( U1 - at centre of board)
Power on the Solder Iron and place near the MPL3115 Sensor
You can see a rapid rise in the Temperature
[Click on below pic to see temp rise]
So we completed integration of xtrinsic temperature sensor with Riotboard
Next time we shall see how to capture sensor data in a database.