Last active
June 24, 2022 12:48
-
-
Save RoyBellingan/036f288281d4c3f248ec427648197e5a to your computer and use it in GitHub Desktop.
Raspberry pi sensor hat temperature and pressure logger
This file contains 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
/* | |
To autostart | |
crontab -e | |
* * * * * cd "/wherever you put the file/" && ./FILE_NAME | |
*/ | |
#include "LPS22HB.h" | |
#include <bcm2835.h> | |
#include <math.h> | |
#include <stdio.h> | |
#include <sys/file.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <time.h> | |
#include <unistd.h> | |
char I2C_readByte(char reg) { | |
char buf[] = {reg}; | |
bcm2835_i2c_read_register_rs(buf, buf, 1); | |
return buf[0]; | |
} | |
unsigned short I2C_readU16(char reg) { | |
char buf[] = {reg, 0}; | |
bcm2835_i2c_read_register_rs(buf, buf, 2); | |
int value = buf[1] * 0x100 + buf[0]; | |
return value; | |
} | |
void I2C_writeByte(char reg, char val) { | |
char buf[] = {reg, val}; | |
bcm2835_i2c_write(buf, 2); | |
} | |
void LPS22HB_RESET() { | |
uint8_t Buf; | |
Buf = I2C_readU16(LPS_CTRL_REG2); | |
Buf |= 0x04; | |
I2C_writeByte(LPS_CTRL_REG2, Buf); //SWRESET Set 1 | |
while (Buf) { | |
Buf = I2C_readU16(LPS_CTRL_REG2); | |
Buf &= 0x04; | |
} | |
} | |
void LPS22HB_START_ONESHOT() { | |
uint8_t Buf; | |
Buf = I2C_readU16(LPS_CTRL_REG2); | |
Buf |= 0x01; //ONE_SHOT Set 1 | |
I2C_writeByte(LPS_CTRL_REG2, Buf); | |
} | |
uint8_t LPS22HB_INIT() { | |
printf("Please run this as root, else the internal lib will crash NOW!\n"); | |
bcm2835_i2c_begin(); | |
bcm2835_i2c_setSlaveAddress(LPS22HB_I2C_ADDRESS); //切记不能把I2C关掉 | |
bcm2835_i2c_set_baudrate(10000); | |
if (I2C_readByte(LPS_WHO_AM_I) != LPS_ID) | |
return 0; //Check device ID | |
LPS22HB_RESET(); //Wait for reset to complete | |
I2C_writeByte(LPS_CTRL_REG1, 0x02); //Low-pass filter disabled , output registers not updated until MSB and LSB have been read , Enable Block Data Update , Set Output Data Rate to 0 | |
return 1; | |
} | |
struct _IO_FILE* makeFile() { | |
time_t curr_time; | |
struct tm* curr_tm; | |
char dateTime[100]; | |
time(&curr_time); | |
curr_tm = localtime(&curr_time); | |
struct stat st = {0}; | |
if (stat("logs", &st) == -1) { | |
mkdir("logs", 0700); | |
} | |
strftime(dateTime, 50, "logs/%Y-%m-%d_%H:%M:%S.csv", curr_tm); | |
printf("We will print into %s\n", dateTime); | |
struct _IO_FILE* file = fopen(dateTime, "w+"); | |
if (file == 0) { | |
printf("sadNoise.wav Impossible to open file %s", dateTime); | |
exit(1); | |
} | |
return file; | |
} | |
/** | |
* Bla bla bla this will check the program is not already running using a classical technique | |
*/ | |
void fLockCheck() { | |
// check if there is another instance running... | |
int fd = open("logger.lock", O_CREAT | O_RDWR, 0666); | |
if (fd == -1) { | |
printf("impossible to open logger.lock"); | |
exit(1); | |
} | |
if (flock(fd, LOCK_EX | LOCK_NB) == -1) { | |
printf("logger.lock is already locked, I refuse to start.\n (The application is already running.)\n"); | |
exit(1); | |
} | |
} | |
int main(int argc, char** argv) { | |
fLockCheck(); | |
struct _IO_FILE* logFile = makeFile(); | |
int delay = 30; | |
if (argc == 1) { | |
} else { | |
delay = atoi(argv[1]); | |
} | |
printf("this will run with a delay of %i s \n", delay); | |
float PRESS_DATA = 0; | |
float TEMP_DATA = 0; | |
uint8_t u8Buf[3]; | |
if (!bcm2835_init()) | |
return 1; | |
printf("\nPressure Sensor Test Program ...\n"); | |
if (!LPS22HB_INIT()) { | |
printf("\nPressure Sensor Error\n"); | |
return 0; | |
} | |
printf("\nPressure Sensor OK\n"); | |
//because the first read is usually 0, we just skip it | |
LPS22HB_START_ONESHOT(); //Trigger one shot data acquisition | |
if ((I2C_readByte(LPS_STATUS) & 0x01) == 0x01) //a new pressure data is generated | |
{ | |
u8Buf[0] = I2C_readByte(LPS_PRESS_OUT_XL); | |
u8Buf[1] = I2C_readByte(LPS_PRESS_OUT_L); | |
u8Buf[2] = I2C_readByte(LPS_PRESS_OUT_H); | |
PRESS_DATA = (float)((u8Buf[2] << 16) + (u8Buf[1] << 8) + u8Buf[0]) / 4096.0f; | |
} | |
if ((I2C_readByte(LPS_STATUS) & 0x02) == 0x02) // a new pressure data is generated | |
{ | |
u8Buf[0] = I2C_readByte(LPS_TEMP_OUT_L); | |
u8Buf[1] = I2C_readByte(LPS_TEMP_OUT_H); | |
TEMP_DATA = (float)((u8Buf[1] << 8) + u8Buf[0]) / 100.0f; | |
} | |
//should be well enought for he sensor to start working | |
sleep(1); | |
printf("unixTs,DateTime,Pressure hPa,Temperature °c\n"); | |
while (1) { | |
LPS22HB_START_ONESHOT(); //Trigger one shot data acquisition | |
if ((I2C_readByte(LPS_STATUS) & 0x01) == 0x01) //a new pressure data is generated | |
{ | |
u8Buf[0] = I2C_readByte(LPS_PRESS_OUT_XL); | |
u8Buf[1] = I2C_readByte(LPS_PRESS_OUT_L); | |
u8Buf[2] = I2C_readByte(LPS_PRESS_OUT_H); | |
PRESS_DATA = (float)((u8Buf[2] << 16) + (u8Buf[1] << 8) + u8Buf[0]) / 4096.0f; | |
} | |
if ((I2C_readByte(LPS_STATUS) & 0x02) == 0x02) // a new pressure data is generated | |
{ | |
u8Buf[0] = I2C_readByte(LPS_TEMP_OUT_L); | |
u8Buf[1] = I2C_readByte(LPS_TEMP_OUT_H); | |
TEMP_DATA = (float)((u8Buf[1] << 8) + u8Buf[0]) / 100.0f; | |
} | |
char buffer[256]; | |
//this will give plain unix ts | |
time_t t = time(NULL); | |
//this will convert the unix ts in a struct with the human format | |
struct tm tm = *localtime(&t); | |
sprintf(buffer, "%u,%d-%02d-%02d %02d:%02d:%02d,%7.2f,%6.2f\n", (unsigned)time(NULL), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, PRESS_DATA, TEMP_DATA); | |
printf("%s", buffer); | |
fputs(buffer, logFile); | |
fflush(logFile); | |
sleep(delay); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment