Skip to content

Instantly share code, notes, and snippets.

@NSBum
Last active April 27, 2018 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NSBum/964979dc0be03f737163a030d613504c to your computer and use it in GitHub Desktop.
Save NSBum/964979dc0be03f737163a030d613504c to your computer and use it in GitHub Desktop.
Example of reading from Si7021 with Raspberry Pi
#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