Last active
April 27, 2018 09:00
-
-
Save NSBum/964979dc0be03f737163a030d613504c to your computer and use it in GitHub Desktop.
Example of reading from Si7021 with Raspberry Pi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <bcm2835.h> | |
#include <string.h> | |
/*+---------------------------------------------------------+ | |
| | | |
| si7021.c - Read Si7021 temperature and humidity | | |
| over I2C bus using Raspberry Pi | | |
| | | |
| Requires the bcm2835 library. | | |
| | | |
| | | |
+---------------------------------------------------------+ | |
*/ | |
#define SI7021_ADDR 0x40 | |
// I2C COMMANDS | |
#define SI7021_MRH_HOLD 0xE5 | |
#define SI7021_MRH_NOHOLD 0xF5 | |
#define SI7021_MT_HOLD 0xE3 // measure temp, hold master | |
#define SI7021_MT_NOHOLD 0xF3 // measure temp, no hold master | |
#define SI7021_RT_PREV 0xE0 // read temp from last RH measurement | |
#define SI7021_RESET 0xFE // reset | |
#define SI7021_WR_USER1 0xE6 // write RH/T user register 1 | |
#define SI7021_RD_USER1 0xE7 // read RH/T user register 1 | |
#define SI7021_WR_HCTL 0x51 // write heater control register | |
#define SI7021_RD_HCTL 0x11 // read heater control register | |
#define SI7021_RD_ID1 0xFA 0x0F // read electronic ID 1st byte | |
#define SI7021_RD_ID2 0xFC 0xC9 // read electronic ID 2nd byte | |
#define SI7021_RD_REV 0x84 0xB8 // read firmware revision | |
#define SI7021_OK 0x00 // return code OK | |
#define SI7021_FAIL 0x01 // return code fail | |
void setTimeout(uint16_t timeout) { | |
volatile uint32_t* stimeout = bcm2835_bsc1 + BCM2835_BSC_CLKT / 4; | |
bcm2835_peri_write(stimeout, timeout); | |
} | |
// | |
// Read the current temperature | |
// | |
float readTemperature(uint8_t *status) { | |
uint8_t buf[4] = { SI7021_MT_HOLD }; | |
if( bcm2835_i2c_read_register_rs(buf,buf,3) != BCM2835_I2C_REASON_OK ) { | |
*status = SI7021_FAIL; | |
return 0.0; | |
} | |
uint8_t msb = buf[0]; | |
uint8_t lsb = buf[1]; | |
unsigned int data16 = ((unsigned int) msb << 8) | (unsigned int) (lsb & 0xFC); | |
float temp = (float) (-46.85 + (175.72 * data16 / (float) 65536)); | |
*status = SI7021_OK; | |
return temp; | |
} | |
// | |
// Read the humidity | |
// | |
float readHumidity() { | |
uint8_t buf[4] = { SI7021_MRH_NOHOLD }; | |
bcm2835_i2c_write(buf,1); | |
while( bcm2835_i2c_read(buf,3) == BCM2835_I2C_REASON_ERROR_NACK ) { | |
bcm2835_delayMicroseconds(500); | |
} | |
uint8_t msb = buf[0]; uint8_t lsb = buf[1]; | |
uint16_t data16 = ((unsigned int) msb << 8) | (unsigned int) (lsb & 0xFC); | |
float hum = -6 + (125.0 * (float) data16) / 65536; | |
return hum; | |
} | |
// | |
// Read the device serial number and return as string | |
// | |
uint8_t readSerialNumber(char *instr) { | |
uint8_t buf[8] = {0xFA,0x0F}; | |
char *str = (char *) malloc(25); | |
char *str2 = (char * ) malloc(13); | |
if( bcm2835_i2c_write(buf,2) != BCM2835_I2C_REASON_OK ) { | |
return SI7021_FAIL; | |
} | |
if( bcm2835_i2c_read(buf,8) != BCM2835_I2C_REASON_OK ) { | |
printf("Read failed\n" ); | |
return SI7021_FAIL; | |
} | |
sprintf(str,"%02X %02X %02X %02X ",buf[0],buf[2],buf[4],buf[6]); | |
buf[0] = 0xFC; buf[1] = 0xC9; | |
bcm2835_i2c_write(buf,2); | |
bcm2835_i2c_read(buf,8); | |
sprintf(str2,"%02X %02X %02X %02X\0",buf[0],buf[2],buf[4],buf[6]); | |
strcpy(instr, strcat(str,str2)); | |
return SI7021_OK; | |
} | |
int main(int argc, char** argv) { | |
if (!bcm2835_init()) | |
return 1; | |
bcm2835_i2c_begin(); | |
bcm2835_i2c_setSlaveAddress(SI7021_ADDR); | |
bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_626); | |
setTimeout(40000); | |
uint8_t status; | |
float temp = readTemperature(&status); | |
printf("Temperature %f C \n\r", temp); | |
float humidity = readHumidity(); | |
printf("Humidity = %f%%\n",humidity ); | |
// read the device serial number | |
char * sstr = (char *) malloc(26); | |
readSerialNumber(sstr); | |
printf("%s\n",sstr); | |
bcm2835_i2c_end(); | |
return (EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment