Skip to content

Instantly share code, notes, and snippets.

@RoyBellingan
Last active July 5, 2022 14:04
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 RoyBellingan/a8cef2383171738400ae0a5a90345932 to your computer and use it in GitHub Desktop.
Save RoyBellingan/a8cef2383171738400ae0a5a90345932 to your computer and use it in GitHub Desktop.
LPS25H.cpp
/*
To autostart
crontab -e
* * * * * cd "/wherever you put the file/" && ./FILE_NAME
(to kill use killall logger)
To compile you will need
i2c-tools
https://www.airspayce.com/mikem/bcm2835/
download latest
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.71.tar.gz
tar zxvf bcm2835-1.71.tar.gz
cd bcm2835-1.71
./configure
make
sudo make check
sudo make install
compile with
gcc logger.c -lbcm2835 -o logger
*/
#include <bcm2835.h>
#include <locale.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>
//From https://www.st.com/resource/en/datasheet/lps25h.pdf page 20
const char SENSOR_ADDR = 0x5c;
const char RES_CONF = 0x10;
const char WHO_AM_I = 0x0F;
const char DEVICE_ID = 0xBD;
const char CTRL_REG1 = 0x20;
const char CTRL_REG2 = 0x21;
//This will contain 0b1 and 0b10 to notify new data are available
const char STATUS_REG = 0x27;
const char PRESS_POUT_XL = 0x28;
const char PRESS_OUT_L = 0x29;
const char PRESS_OUT_H = 0x2a;
const char TEMP_OUT_L = 0x2b;
const char TEMP_OUT_H = 0x2c;
const char FIFO_CTRL = 0x2e;
//Bitmask
const char NEW_TEMP_DATA = 0b01;
const char NEW_PRESS_DATA = 0b10;
char I2C_readByte(char reg) {
char buf[] = {reg};
bcm2835_i2c_read_register_rs(buf, buf, 1);
return buf[0];
}
void I2C_writeByte(char reg, char val) {
char buf[] = {reg, val};
bcm2835_i2c_write(buf, 2);
}
uint8_t LPS22HB_INIT() {
printf("Please run this as root, else the internal lib will crash NOW!\n");
bcm2835_i2c_begin();
bcm2835_i2c_setSlaveAddress(SENSOR_ADDR);
bcm2835_i2c_set_baudrate(10000);
char b = I2C_readByte(WHO_AM_I);
if (b != DEVICE_ID) {
printf("Device Identification failed, expected %c got %c ! Maybe a conflict with another device ?", DEVICE_ID, b);
return 0;
}
{
/**
* page 25
* from MSB
* power on
* 1Hz mode
* wait for a read before updating
*/
char config = 0b10010100;
I2C_writeByte(CTRL_REG1, config);
}
/** as suggested in chapter 9.1 **/
//This will reset the internal averaging, reducing power consumption...
//In any case is not really needed and in case of flier is easier to detect
I2C_writeByte(RES_CONF, 0x05);
//This will set the internal mean averager buffer lenght to 1 sample
//(Roy: I am pretty sure this is the interpretation)
I2C_writeByte(FIFO_CTRL, 0xc0);
//This will enable the FIFO
I2C_writeByte(CTRL_REG2, 0x40);
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) {
//This will avoid to format decimal with , instead of .
setlocale(LC_ALL, "C");
//Force set the UTC timezone
setenv("TZ", "UTC", 1);
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;
if (!bcm2835_init()) {
printf("\nbcm2835 lib init failed\n");
return 1;
}
printf("\nPressure Sensor Test Program ...\n");
if (!LPS22HB_INIT()) {
printf("\nPressure Sensor Error Init error, aborting\n");
return 1;
}
printf("\nPressure Sensor OK\n");
//should be well enought for the sensor to start working
sleep(1);
printf("unixTs,DateTime UTC,Pressure hPa,Temperature °c\n");
while (1) {
if ((I2C_readByte(STATUS_REG) & NEW_PRESS_DATA)) {
uint8_t u8Buf[3];
u8Buf[0] = I2C_readByte(PRESS_POUT_XL);
u8Buf[1] = I2C_readByte(PRESS_OUT_L);
u8Buf[2] = I2C_readByte(PRESS_OUT_H);
PRESS_DATA = (float)((u8Buf[2] << 16) + (u8Buf[1] << 8) + u8Buf[0]) / 4096.0f;
}
if ((I2C_readByte(STATUS_REG) & NEW_TEMP_DATA)) {
int8_t u8Buf[2];
u8Buf[0] = I2C_readByte(TEMP_OUT_L);
u8Buf[1] = I2C_readByte(TEMP_OUT_H);
float raw = (u8Buf[1] << 8) + u8Buf[0];
TEMP_DATA = 42.5 + raw / 480.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