Temperature
The final challenge, so you choose to accept it, is to integrate the code that gets the temperature using the i2c barometric sensor.. are you up to the challenge?
root@edison:~/.../I2CDL# nano lcd_temp.c
Answer (full code)
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/i2c-dev-user.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h>
#include <inttypes.h>
#define RGB_SLAVE 0x62
#define LCD_SLAVE 0x3E
#define BUS 0x06
#define REG_RED 0x04 // pwm2
#define REG_GREEN 0x03 // pwm1
#define REG_BLUE 0x02 // pwm0
#define REG_MODE1 0x00
#define REG_MODE2 0x01
#define REG_OUTPUT 0x08
// commands
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00
// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00
// flags for function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_2LINE 0x18
#define LCD_5x8DOTS 0x00
//////////////////////////////
//
//Barometer Registers
#define BAROMETER_SLAVE 0x60
#define MPL3115A2_WHO_AM_I 0x0c //Device Identification Register
#define MPL3115A2_SYSMOD 0x11 //System Mode Register || Current system mode
#define MPL3115A2_CTRL_REG1 0x26 //Control Register 1 || Modes, Oversampling
#define MPL3115A2_CTRL_REG2 0x27 //Control Register 2 || Acquisition time step
#define MPL3115A2_CTRL_REG3 0x28 //Control Register 3 || Interrupt pin configuration
#define MPL3115A2_CTRL_REG4 0x29 //Control Register 4 || Interrupt enables
#define MPL3115A2_CTRL_REG5 0x2A //Control Register 5 || Interrupt output pin assignment
#define MPL3115A2_STATUS 0x00 //Sensor Status Register
#define MPL3115A2_OFF_T 0x2C //Temperature Data Offset Register
#define MPL3115A2_BUS 0x06 //I2C bus where the device is connected
#define MPL3115A2_SLAVE 0x60 //I2C slave address of the device
#define MPL3115A2_OUT_T_MSB 0x04
#define MPL3115A2_OUT_T_LSB 0x05
#define MPL3115A2_DR_STATUS 0x06 //
#define MPL3115A2_OST_MASK 0x02
//////////////////////////////////////////////////////////
typedef struct
{
int addr; //i2c address of device
int file; //reprsents a place to do the i2c read & write
int adapter_nr; //the bus number of the device
char filename[20]; //the name of the device
}I2CCONTEXT;
I2CCONTEXT lcd;
I2CCONTEXT rgb;
I2CCONTEXT barometer;
int initContext(I2CCONTEXT *ctx, int addr_,int bus)
{
ctx->addr = addr_;
ctx->adapter_nr = bus;
snprintf(ctx->filename, 19, "/dev/i2c-%d", ctx->adapter_nr);
ctx->file = open(ctx->filename, O_RDWR);
if (ctx->file < 0)
{
/* ERROR HANDLING; you can check errno 2 c what went wrong */
printf("Error ocurred @ opening BUS: (errno:%d) %s\n",
errno,
strerror(errno));
return -errno;
}
if (ioctl(ctx->file, I2C_SLAVE, ctx->addr) < 0)
{
/* ERROR HANDLING; you can check errno 2 c what went wrong */
printf("Error ocurred @ accessing slave: (errno:%d) %s\n",
errno,
strerror(errno));
return -errno;
}
}
__s32 writeWordRegister(int file, __u8 command, __u16 value)
{
__s32 res = -1;
res = i2c_smbus_write_word_data(file, command, value);
if (res < 0)
{
/* ERROR HANDLING: i2c transaction failed */
printf("Error writing reg: 0x%x, (errno:%d),%s",
command,errno,strerror(errno));
}
return res;
}
__s32 readWordRegister(int r, int file)
{
/* Using SMBus commands */
__u8 reg = r; /* Device register to access */
__s32 res = -1;
char buf[10];
res = i2c_smbus_read_word_data(file, reg);
if (res < 0)
{
/* ERROR HANDLING: i2c transaction failed */
printf("Error reading reg: 0x%x, (errno:%d),%s",
reg,errno,strerror(errno));
}
/*
else
{
printf("result: 0x%x\n",res);
}
*/
return res;
}
__s32 writeByteRegister(int file, __u8 register_, __u8 value)
{
__s32 res = -1;
res = i2c_smbus_write_byte_data(file, register_, value);
if (res < 0)
{
/* ERROR HANDLING: i2c transaction failed */
printf("Error writing byte, (errno:%d),%s\n",errno,
strerror(errno));
}
}
__s32 readRegister(int register_, int file)
{
__u8 reg = register_;
__s32 res = -1;
char buf[10];
res = i2c_smbus_read_word_data(file, reg);
if (res < 0)
{
/* ERROR HANDLING: i2c transaction failed */
printf("Error reading reg: 0x%x, (errno:%d),%s",
reg,errno,strerror(errno));
}
return res;
}
void setRGBColor(I2CCONTEXT *rgb, int r, int g, int b)
{
writeByteRegister(rgb->file, REG_RED, r);
writeByteRegister(rgb->file, REG_GREEN, g);
writeByteRegister(rgb->file, REG_BLUE, b);
}
void initRGB(I2CCONTEXT *rgb)
{
// backlight init
writeByteRegister(rgb->file, REG_MODE1, 0);
// set LEDs controllable by both PWM and GRPPWM registers
writeByteRegister(rgb->file, REG_OUTPUT, 0xFF);
// set MODE2 values
writeByteRegister(rgb->file, REG_MODE2, 0x20);
// set the baklight Color to white :)
setRGBColor(rgb, 0xFF, 0xFF, 0xFF);
}
void turnOffRGB(I2CCONTEXT *rgb)
{
setRGBColor(rgb, 0x00, 0x00, 0x00);
}
void initLCD(I2CCONTEXT *lcd)
{
writeByteRegister(lcd->file, 0x00, LCD_FUNCTIONSET | LCD_2LINE );
usleep(100);
writeByteRegister(lcd->file, 0x00,LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSORON | LCD_BLINKOFF );
usleep(100);
writeByteRegister(lcd->file, 0x00, LCD_CLEARDISPLAY );
usleep(4000);
writeByteRegister(lcd->file, 0x00,LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT );
}
void turnOffLCD(I2CCONTEXT *lcd)
{
writeByteRegister(lcd->file, 0x00, LCD_DISPLAYCONTROL );
writeByteRegister(lcd->file, 0x00, LCD_CLEARDISPLAY );
}
void clearLCD(I2CCONTEXT *lcd)
{
writeByteRegister(lcd->file, 0x00, LCD_CLEARDISPLAY );
}
void writeToLCD(I2CCONTEXT *lcd, char *c)
{
//writeByteRegister(lcd->file, 0x80, 0x48);
//usleep(4000);
uint ascii_val=0;
int i;
int s = strlen(c);
for(i = 0 ; i < s; i++)
{
ascii_val = toascii(c[i]);
writeByteRegister(lcd->file, 0x40, ascii_val);
}
}
void doOneShot(I2CCONTEXT *barometer)
{
printf("Doing oneShot\n");
__s32 ctrl_reg1 = readWordRegister(MPL3115A2_CTRL_REG1,barometer->file);
ctrl_reg1 |= (1<<1);
writeWordRegister(barometer->file, MPL3115A2_CTRL_REG1, ctrl_reg1);
}
float getTemp(I2CCONTEXT *barometer)
{
float temperature = 0.0;
__s32 msb = 0;
__s32 lsb = 0;
__s32 ctrl_reg1 = readWordRegister(MPL3115A2_CTRL_REG1,barometer->file);
printf("OST STATUS: 0x%x\n",ctrl_reg1 & 0x02);
if((ctrl_reg1 & 0x02) == 0)
{
printf("%s\n", "no oneShoot in progress..");
doOneShot(barometer);
int contador = 0;
while((ctrl_reg1 & 0x02) == 0)
{
ctrl_reg1 = readWordRegister(MPL3115A2_CTRL_REG1,barometer->file);
}
int msb = (readWordRegister(MPL3115A2_OUT_T_MSB,barometer->file)) & 255 ;
int lsb = readWordRegister(MPL3115A2_OUT_T_LSB,barometer->file);
float templsb = (lsb>>4)/16.0; //temp, fraction of a degree
temperature = (float)msb+templsb;
printf("Temperature: %f\n",temperature);
return temperature;
}
else
{
printf("%s\n", "in progress...");
return 0;
}
}
int main()
{
/*
we pass a reference to the rgb context variable
the i2c address of the rgb controller
and the BUS which should be 1
*/
initContext(&rgb, RGB_SLAVE , BUS);
initContext(&lcd, LCD_SLAVE , BUS);
initContext(&barometer, BAROMETER_SLAVE , BUS);
/*inits the RGB controller and sets its color to White*/
initRGB(&rgb);
initLCD(&lcd);
int contador = 20;
char t[80];
while(contador > 0)
{
clearLCD(&lcd);
sprintf(t, "Temp:%.2f *C", getTemp(&barometer));
writeToLCD(&lcd, t);
contador--;
/*sleep for 1sec*/
sleep(1);
}
/*turn off RGB LEDS*/
turnOffRGB(&rgb);
turnOffLCD(&lcd);
printf("\nDONE!\n");
return 0;
}
Last updated