[M] Fix Sensors

This commit is contained in:
2022-05-28 15:06:59 +02:00
parent f05b6492b0
commit 58ba94a455
39 changed files with 14135 additions and 14103 deletions
+13 -9
View File
@@ -27,6 +27,10 @@
#define BUTTON_PIN_BITMASK 0x8000 #define BUTTON_PIN_BITMASK 0x8000
void loop_DRAW(void * pvParameters );
void loop_TOUCH(void * pvParameters );
void loop_MEASURE(void * pvParameters );
/* Global Variables -----------------------------------------------------------*/ /* Global Variables -----------------------------------------------------------*/
static WiFiMulti wifiMulti; static WiFiMulti wifiMulti;
static TwoWire I2C = TwoWire(0); static TwoWire I2C = TwoWire(0);
@@ -75,9 +79,9 @@ void IRAM_ATTR onSecondTimer() {
} }
view_update = true; view_update = true;
time_update = true; time_update = true;
tf->minuteTick();
} }
tf->tick();
} }
void IRAM_ATTR onTouch(int8_t contacts, GTPoint *points) { void IRAM_ATTR onTouch(int8_t contacts, GTPoint *points) {
if(touch->dev.holding) return; if(touch->dev.holding) return;
@@ -109,18 +113,18 @@ void setup_TIMER(){
#define REGISTER_TIMEDFUN(name,code) static void name (){code;} #define REGISTER_TIMEDFUN(name,code) static void name (){code;}
#define REGISTER_TIMEDFUN_CALL(name,min) tf->registerFun(name,min) #define REGISTER_TIMEDFUN_CALL(name,min) tf->registerFun(name,min)
REGISTER_TIMEDFUN(SENSOR_MEASURE_TF, sensor->measure()); REGISTER_TIMEDFUN(SENSOR_MEASURE_TF, do{sensor->measure();view_update = true;}while(0));
REGISTER_TIMEDFUN(OWM_MEASURE_TF, do{uint8_t i = 0;while(owm && owm[i]){owm[i]->update(); ++i;}}while(0)); REGISTER_TIMEDFUN(OWM_MEASURE_TF, do{uint8_t i = 0;while(owm && owm[i]){owm[i]->update(); ++i;}}while(0));
REGISTER_TIMEDFUN(RECORD_LOCAL_TF, iflx->record_local()); REGISTER_TIMEDFUN(RECORD_LOCAL_TF, iflx->record_local());
REGISTER_TIMEDFUN(RECORD_WEATHER_TF, iflx->record_weather()); REGISTER_TIMEDFUN(RECORD_WEATHER_TF, iflx->record_weather());
REGISTER_TIMEDFUN(NTP_TF, ntp->updateNTPtime()); REGISTER_TIMEDFUN(NTP_TF, ntp->updateNTPtime());
void setup_TIMEDFUN() { void setup_TIMEDFUN() {
REGISTER_TIMEDFUN_CALL(NTP_TF, 60); REGISTER_TIMEDFUN_CALL(NTP_TF, 60*60);
REGISTER_TIMEDFUN_CALL(SENSOR_MEASURE_TF,5); REGISTER_TIMEDFUN_CALL(SENSOR_MEASURE_TF,5);
REGISTER_TIMEDFUN_CALL(OWM_MEASURE_TF,5); REGISTER_TIMEDFUN_CALL(OWM_MEASURE_TF,5*60);
REGISTER_TIMEDFUN_CALL(RECORD_LOCAL_TF,5); // REGISTER_TIMEDFUN_CALL(RECORD_LOCAL_TF,1*60);
REGISTER_TIMEDFUN_CALL(RECORD_WEATHER_TF,5); // REGISTER_TIMEDFUN_CALL(RECORD_WEATHER_TF,5*60);
} }
void setup_POWER() { void setup_POWER() {
@@ -140,11 +144,12 @@ void setup(){
setup_TOUCH(); setup_TOUCH();
setup_TIMER(); setup_TIMER();
setup_TIMEDFUN(); setup_TIMEDFUN();
sensor->init();
iflx->check(); iflx->check();
Display::setViews(views,views_size); Display::setViews(views,views_size);
tf->updateForce(); tf->updateForce();
tf->setTick(ntp->dt.minute); tf->setTick(ntp->dt.minute*60 + ntp->dt.second);
xTaskCreatePinnedToCore( xTaskCreatePinnedToCore(
loop_MEASURE, "Task LMeasure", loop_MEASURE, "Task LMeasure",
@@ -189,8 +194,7 @@ void loop_TOUCH(void * pvParameters ){
void loop_MEASURE(void * pvParameters ){ void loop_MEASURE(void * pvParameters ){
for(;;){ for(;;){
tf->update(); tf->update();
vTaskDelay(500);
vTaskDelay(200);
} }
} }
+41 -35
View File
@@ -9,14 +9,14 @@ static int8_t view_curr = 0;
static DisplayWrapper** views = 0; static DisplayWrapper** views = 0;
void DrawMain(bool v){ void DrawMain(bool v) {
Paint_DrawIcon(89,36, ICON_LOGO, &FontIcon, BLACK, WHITE); Paint_DrawIcon(89,36, ICON_LOGO, &FontIcon, BLACK, WHITE);
Paint_DrawString_EN(29, 0, "Helcel", &Font45, WHITE, BLACK); Paint_DrawString_EN(29, 0, "Helcel", &Font45, WHITE, BLACK);
if(v) if(v)
Paint_DrawString_EN(2,EPD_2IN13_V2_WIDTH - Font16.Height,"WESP-v0.1", &Font16, WHITE, BLACK); Paint_DrawString_EN(2,EPD_2IN13_V2_WIDTH - Font16.Height,"WESP-v0.1", &Font16, WHITE, BLACK);
} }
void Display::setup(){ void Display::setup() {
DEV_Module_Init(); DEV_Module_Init();
uint16_t Imagesize = ((EPD_2IN13_V2_WIDTH % 8 == 0) ? (EPD_2IN13_V2_WIDTH / 8 ) : (EPD_2IN13_V2_WIDTH / 8 + 1)) * EPD_2IN13_V2_HEIGHT; uint16_t Imagesize = ((EPD_2IN13_V2_WIDTH % 8 == 0) ? (EPD_2IN13_V2_WIDTH / 8 ) : (EPD_2IN13_V2_WIDTH / 8 + 1)) * EPD_2IN13_V2_HEIGHT;
@@ -29,19 +29,19 @@ void Display::setup(){
EPD_2IN13_V2_DisplayPart(BlackImage); EPD_2IN13_V2_DisplayPart(BlackImage);
} }
void Display::clearTime(){ void Display::clearTime() {
Paint_ClearWindows(170, EPD_2IN13_V2_WIDTH - Font24.Height+2, 170 + Font24.Width * 4.5, EPD_2IN13_V2_WIDTH, WHITE); Paint_ClearWindows(170, EPD_2IN13_V2_WIDTH - Font24.Height+2, 170 + Font24.Width * 4.5, EPD_2IN13_V2_WIDTH, WHITE);
EPD_2IN13_V2_DisplayPart(BlackImage); EPD_2IN13_V2_DisplayPart(BlackImage);
} }
void Display::drawTime(strDateTime* dt){ void Display::drawTime(strDateTime* dt) {
clearTime(); clearTime();
if (!dt->valid) return; if (!dt->valid) return;
Paint_DrawTime(170, EPD_2IN13_V2_WIDTH - Font24.Height+2, dt, &Font24, WHITE, BLACK); Paint_DrawTime(170, EPD_2IN13_V2_WIDTH - Font24.Height+2, dt, &Font24, WHITE, BLACK);
EPD_2IN13_V2_DisplayPart(BlackImage); EPD_2IN13_V2_DisplayPart(BlackImage);
}; };
void Display::refresh(){ void Display::refresh() {
Paint_Clear(WHITE); Paint_Clear(WHITE);
EPD_2IN13_V2_Init(EPD_2IN13_V2_FULL); EPD_2IN13_V2_Init(EPD_2IN13_V2_FULL);
EPD_2IN13_V2_DisplayPartBaseImage(BlackImage); EPD_2IN13_V2_DisplayPartBaseImage(BlackImage);
@@ -49,42 +49,48 @@ void Display::refresh(){
Paint_SelectImage(BlackImage); Paint_SelectImage(BlackImage);
}; };
void Display::update(){ void Display::update() {
Paint_ClearWindows(0, 0, EPD_2IN13_V2_HEIGHT, EPD_2IN13_V2_WIDTH - Font24.Height, WHITE); Paint_ClearWindows(0, 0, EPD_2IN13_V2_HEIGHT, EPD_2IN13_V2_WIDTH - Font24.Height, WHITE);
Paint_ClearWindows(0, EPD_2IN13_V2_WIDTH - Font24.Height, 170, EPD_2IN13_V2_WIDTH, WHITE); Paint_ClearWindows(0, EPD_2IN13_V2_WIDTH - Font24.Height, 170, EPD_2IN13_V2_WIDTH, WHITE);
if(views && view_curr >=0) if(views && view_curr >=0)
views[view_curr]->drawDisplay(); views[view_curr]->drawDisplay();
EPD_2IN13_V2_DisplayPart(BlackImage); EPD_2IN13_V2_DisplayPart(BlackImage);
} }
void Display::setViews(DisplayWrapper** view_tab, int8_t size){ void Display::setViews(DisplayWrapper** view_tab, int8_t size) {
view_count = size; view_count = size;
views = view_tab; views = view_tab;
}; };
void Display::nextView(){ view_curr++; view_curr = view_curr%view_count;} void Display::nextView() {
void Display::prevView(){ view_curr--; view_curr = (view_curr+view_count) % view_count;} view_curr++;
view_curr = view_curr%view_count;
}
void Display::prevView() {
view_curr--;
view_curr = (view_curr+view_count) % view_count;
}
ICON_tpe getWeatherIcon(int id){ ICON_tpe getWeatherIcon(int id) {
if(id>=200 && id<300){ //Thunder if(id>=200 && id<300) { //Thunder
return ICON_CLOUD_THUNDER; return ICON_CLOUD_THUNDER;
}else if(id>=300 && id<400){//Drizzle } else if(id>=300 && id<400) { //Drizzle
return ICON_CLOUD_RAIN; return ICON_CLOUD_RAIN;
}else if(id>=500 && id<600){//Rain } else if(id>=500 && id<600) { //Rain
return ICON_CLOUD_RAIN; return ICON_CLOUD_RAIN;
}else if(id>=600 && id<700){//Snow } else if(id>=600 && id<700) { //Snow
return ICON_CLOUD_SNOW; return ICON_CLOUD_SNOW;
}else if(id>=700 && id<800){//Warning } else if(id>=700 && id<800) { //Warning
return ICON_WARN; return ICON_WARN;
}else if(id>=800 && id<900){//Clear & Cloudy } else if(id>=800 && id<900) { //Clear & Cloudy
if(id==800) return ICON_SUN; if(id==800) return ICON_SUN;
else if(id==801) return ICON_CLOUD_SUN; else if(id==801) return ICON_CLOUD_SUN;
else return ICON_CLOUD; else return ICON_CLOUD;
}else{ } else {
return ICON_WARN; return ICON_WARN;
} }
} }
void WeatherDisplay::drawDisplay() { void WeatherDisplay::drawDisplay() {
@@ -137,7 +143,7 @@ void AirDisplay::drawDisplay() {
// particles_50um, ///< 5.0um Particle Count // particles_50um, ///< 5.0um Particle Count
// particles_100um; ///< 10.0um Particle Count // particles_100um; ///< 10.0um Particle Count
Paint_DrawString_EN(2,EPD_2IN13_V2_WIDTH - Font16.Height,"Nominal", &Font16, WHITE, BLACK); Paint_DrawString_EN(2,EPD_2IN13_V2_WIDTH - Font16.Height,"Nominal", &Font16, WHITE, BLACK);
} }
+26 -26
View File
@@ -17,12 +17,12 @@
#include <WiFi.h> #include <WiFi.h>
#include <WiFiMulti.h> #include <WiFiMulti.h>
class DisplayWrapper { class DisplayWrapper {
public: public:
virtual void drawDisplay(); virtual void drawDisplay();
}; };
class Display { class Display {
public: public:
static void setup(); static void setup();
static void clearTime(); static void clearTime();
static void drawTime(strDateTime* dt); static void drawTime(strDateTime* dt);
@@ -36,48 +36,48 @@ class Display {
class WeatherDisplay: public DisplayWrapper { class WeatherDisplay: public DisplayWrapper {
public: public:
WeatherDisplay(OWM* o) : cowm(o){} WeatherDisplay(OWM* o) : cowm(o) {}
void drawDisplay(); void drawDisplay();
private: private:
OWM* cowm; OWM* cowm;
}; };
class TempDisplay: public DisplayWrapper { class TempDisplay: public DisplayWrapper {
public: public:
TempDisplay(Sensor* s) : sensor(s){} TempDisplay(Sensor* s) : sensor(s) {}
void drawDisplay(); void drawDisplay();
private: private:
Sensor* sensor; Sensor* sensor;
}; };
class AirDisplay: public DisplayWrapper { class AirDisplay: public DisplayWrapper {
public: public:
AirDisplay(Sensor* s) : sensor(s){} AirDisplay(Sensor* s) : sensor(s) {}
void drawDisplay(); void drawDisplay();
private: private:
Sensor* sensor; Sensor* sensor;
}; };
class LightDisplay: public DisplayWrapper { class LightDisplay: public DisplayWrapper {
public: public:
LightDisplay(Sensor* s) : sensor(s){} LightDisplay(Sensor* s) : sensor(s) {}
void drawDisplay(); void drawDisplay();
private: private:
Sensor* sensor; Sensor* sensor;
}; };
class MainDisplay: public DisplayWrapper { class MainDisplay: public DisplayWrapper {
public: public:
void drawDisplay(); void drawDisplay();
}; };
class CustomDisplay: public DisplayWrapper { class CustomDisplay: public DisplayWrapper {
public: public:
void drawDisplay(); void drawDisplay();
}; };
#endif #endif
+2 -2
View File
@@ -5,9 +5,9 @@
#define USE_DEBUG 0 #define USE_DEBUG 0
#if USE_DEBUG #if USE_DEBUG
#define Debug(__info) Serial.print(__info) #define Debug(__info) Serial.print(__info)
#else #else
#define Debug(__info) #define Debug(__info)
#endif #endif
#endif #endif
+13 -13
View File
@@ -1,15 +1,15 @@
#include "epd_cfg.h" #include "epd_cfg.h"
void GPIO_Config(void){ void GPIO_Config(void) {
pinMode(EPD_BUSY_PIN, INPUT); pinMode(EPD_BUSY_PIN, INPUT);
pinMode(EPD_RST_PIN , OUTPUT); pinMode(EPD_RST_PIN, OUTPUT);
pinMode(EPD_DC_PIN , OUTPUT); pinMode(EPD_DC_PIN, OUTPUT);
pinMode(EPD_SCK_PIN, OUTPUT); pinMode(EPD_SCK_PIN, OUTPUT);
pinMode(EPD_MOSI_PIN, OUTPUT); pinMode(EPD_MOSI_PIN, OUTPUT);
pinMode(EPD_CS_PIN , OUTPUT); pinMode(EPD_CS_PIN, OUTPUT);
digitalWrite(EPD_CS_PIN , HIGH); digitalWrite(EPD_CS_PIN, HIGH);
digitalWrite(EPD_SCK_PIN, LOW); digitalWrite(EPD_SCK_PIN, LOW);
} }
/****************************************************************************** /******************************************************************************
@@ -17,24 +17,24 @@ function: Module Initialize, the BCM2835 library and initialize the pins, SPI p
parameter: parameter:
Info: Info:
******************************************************************************/ ******************************************************************************/
uint8_t DEV_Module_Init(void){ uint8_t DEV_Module_Init(void) {
GPIO_Config(); GPIO_Config();
#ifdef USE_DEBUG #ifdef USE_DEBUG
Serial.begin(115200); Serial.begin(115200);
#endif #endif
return 0; return 0;
} }
/****************************************************************************** /******************************************************************************
function: function:
SPI read and write SPI read and write
******************************************************************************/ ******************************************************************************/
void DEV_SPI_WriteByte(uint8_t data){ void DEV_SPI_WriteByte(uint8_t data) {
digitalWrite(EPD_CS_PIN, GPIO_PIN_RESET); digitalWrite(EPD_CS_PIN, GPIO_PIN_RESET);
for (int i = 0; i < 8; i++){ for (int i = 0; i < 8; i++) {
if ((data & 0x80) == 0) digitalWrite(EPD_MOSI_PIN, GPIO_PIN_RESET); if ((data & 0x80) == 0) digitalWrite(EPD_MOSI_PIN, GPIO_PIN_RESET);
else digitalWrite(EPD_MOSI_PIN, GPIO_PIN_SET); else digitalWrite(EPD_MOSI_PIN, GPIO_PIN_SET);
+12 -12
View File
@@ -92,7 +92,7 @@ const unsigned char EPD_2IN13_V2_lut_partial_update[]= { //20 bytes
function : Software reset function : Software reset
parameter: parameter:
******************************************************************************/ ******************************************************************************/
static void EPD_2IN13_V2_Reset(void){ static void EPD_2IN13_V2_Reset(void) {
DEV_Digital_Write(EPD_RST_PIN, 1); DEV_Digital_Write(EPD_RST_PIN, 1);
delay(200); delay(200);
DEV_Digital_Write(EPD_RST_PIN, 0); DEV_Digital_Write(EPD_RST_PIN, 0);
@@ -106,7 +106,7 @@ function : send command
parameter: parameter:
Reg : Command register Reg : Command register
******************************************************************************/ ******************************************************************************/
static void EPD_2IN13_V2_SendCommand(uint8_t Reg){ static void EPD_2IN13_V2_SendCommand(uint8_t Reg) {
DEV_Digital_Write(EPD_DC_PIN, 0); DEV_Digital_Write(EPD_DC_PIN, 0);
DEV_Digital_Write(EPD_CS_PIN, 0); DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_SPI_WriteByte(Reg); DEV_SPI_WriteByte(Reg);
@@ -118,7 +118,7 @@ function : send data
parameter: parameter:
Data : Write data Data : Write data
******************************************************************************/ ******************************************************************************/
static void EPD_2IN13_V2_SendData(uint8_t Data){ static void EPD_2IN13_V2_SendData(uint8_t Data) {
DEV_Digital_Write(EPD_DC_PIN, 1); DEV_Digital_Write(EPD_DC_PIN, 1);
DEV_Digital_Write(EPD_CS_PIN, 0); DEV_Digital_Write(EPD_CS_PIN, 0);
DEV_SPI_WriteByte(Data); DEV_SPI_WriteByte(Data);
@@ -129,7 +129,7 @@ static void EPD_2IN13_V2_SendData(uint8_t Data){
function : Wait until the busy_pin goes LOW function : Wait until the busy_pin goes LOW
parameter: parameter:
******************************************************************************/ ******************************************************************************/
void EPD_2IN13_V2_ReadBusy(void){ void EPD_2IN13_V2_ReadBusy(void) {
Debug("e-Paper busy\r\n"); Debug("e-Paper busy\r\n");
while(DEV_Digital_Read(EPD_BUSY_PIN) == 1) { //LOW: idle, HIGH: busy while(DEV_Digital_Read(EPD_BUSY_PIN) == 1) { //LOW: idle, HIGH: busy
delay(100); delay(100);
@@ -141,7 +141,7 @@ void EPD_2IN13_V2_ReadBusy(void){
function : Turn On Display function : Turn On Display
parameter: parameter:
******************************************************************************/ ******************************************************************************/
static void EPD_2IN13_V2_TurnOnDisplay(void){ static void EPD_2IN13_V2_TurnOnDisplay(void) {
EPD_2IN13_V2_SendCommand(0x22); EPD_2IN13_V2_SendCommand(0x22);
EPD_2IN13_V2_SendData(0xC7); EPD_2IN13_V2_SendData(0xC7);
EPD_2IN13_V2_SendCommand(0x20); EPD_2IN13_V2_SendCommand(0x20);
@@ -152,7 +152,7 @@ static void EPD_2IN13_V2_TurnOnDisplay(void){
function : Turn On Display function : Turn On Display
parameter: parameter:
******************************************************************************/ ******************************************************************************/
static void EPD_2IN13_V2_TurnOnDisplayPart(void){ static void EPD_2IN13_V2_TurnOnDisplayPart(void) {
EPD_2IN13_V2_SendCommand(0x22); EPD_2IN13_V2_SendCommand(0x22);
EPD_2IN13_V2_SendData(0x0C); EPD_2IN13_V2_SendData(0x0C);
EPD_2IN13_V2_SendCommand(0x20); EPD_2IN13_V2_SendCommand(0x20);
@@ -162,7 +162,7 @@ static void EPD_2IN13_V2_TurnOnDisplayPart(void){
function : Initialize the e-Paper register function : Initialize the e-Paper register
parameter: parameter:
******************************************************************************/ ******************************************************************************/
void EPD_2IN13_V2_Init(uint8_t Mode){ void EPD_2IN13_V2_Init(uint8_t Mode) {
uint8_t count; uint8_t count;
EPD_2IN13_V2_Reset(); EPD_2IN13_V2_Reset();
@@ -261,7 +261,7 @@ void EPD_2IN13_V2_Init(uint8_t Mode){
function : Clear screen function : Clear screen
parameter: parameter:
******************************************************************************/ ******************************************************************************/
void EPD_2IN13_V2_Clear(void){ void EPD_2IN13_V2_Clear(void) {
uint16_t Width, Height; uint16_t Width, Height;
Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1); Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1);
Height = EPD_2IN13_V2_HEIGHT; Height = EPD_2IN13_V2_HEIGHT;
@@ -280,7 +280,7 @@ void EPD_2IN13_V2_Clear(void){
function : Sends the image buffer in RAM to e-Paper and displays function : Sends the image buffer in RAM to e-Paper and displays
parameter: parameter:
******************************************************************************/ ******************************************************************************/
void EPD_2IN13_V2_Display(uint8_t *Image){ void EPD_2IN13_V2_Display(uint8_t *Image) {
uint16_t Width, Height; uint16_t Width, Height;
Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1); Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1);
Height = EPD_2IN13_V2_HEIGHT; Height = EPD_2IN13_V2_HEIGHT;
@@ -299,7 +299,7 @@ function : The image of the previous frame must be uploaded, otherwise the
first few seconds will display an exception. first few seconds will display an exception.
parameter: parameter:
******************************************************************************/ ******************************************************************************/
void EPD_2IN13_V2_DisplayPartBaseImage(uint8_t *Image){ void EPD_2IN13_V2_DisplayPartBaseImage(uint8_t *Image) {
uint16_t Width, Height; uint16_t Width, Height;
Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1); Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1);
Height = EPD_2IN13_V2_HEIGHT; Height = EPD_2IN13_V2_HEIGHT;
@@ -323,7 +323,7 @@ void EPD_2IN13_V2_DisplayPartBaseImage(uint8_t *Image){
} }
void EPD_2IN13_V2_DisplayPart(uint8_t *Image){ void EPD_2IN13_V2_DisplayPart(uint8_t *Image) {
uint16_t Width, Height; uint16_t Width, Height;
Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1); Width = (EPD_2IN13_V2_WIDTH % 8 == 0)? (EPD_2IN13_V2_WIDTH / 8 ): (EPD_2IN13_V2_WIDTH / 8 + 1);
Height = EPD_2IN13_V2_HEIGHT; Height = EPD_2IN13_V2_HEIGHT;
@@ -341,7 +341,7 @@ void EPD_2IN13_V2_DisplayPart(uint8_t *Image){
function : Enter sleep mode function : Enter sleep mode
parameter: parameter:
******************************************************************************/ ******************************************************************************/
void EPD_2IN13_V2_Sleep(void){ void EPD_2IN13_V2_Sleep(void) {
EPD_2IN13_V2_SendCommand(0x22); //POWER OFF EPD_2IN13_V2_SendCommand(0x22); //POWER OFF
EPD_2IN13_V2_SendData(0xC3); EPD_2IN13_V2_SendData(0xC3);
EPD_2IN13_V2_SendCommand(0x20); EPD_2IN13_V2_SendCommand(0x20);
+103 -103
View File
@@ -94,7 +94,7 @@ parameter:
Height : The height of the picture Height : The height of the picture
Color : Whether the picture is inverted Color : Whether the picture is inverted
******************************************************************************/ ******************************************************************************/
void Paint_NewImage(uint8_t *image, uint16_t Width, uint16_t Height, uint16_t Rotate, uint16_t Color){ void Paint_NewImage(uint8_t *image, uint16_t Width, uint16_t Height, uint16_t Rotate, uint16_t Color) {
Paint.Image = NULL; Paint.Image = NULL;
Paint.Image = image; Paint.Image = image;
@@ -122,7 +122,7 @@ function: Select Image
parameter: parameter:
image : Pointer to the image cache image : Pointer to the image cache
******************************************************************************/ ******************************************************************************/
void Paint_SelectImage(uint8_t *image){ void Paint_SelectImage(uint8_t *image) {
Paint.Image = image; Paint.Image = image;
} }
@@ -131,7 +131,7 @@ function: Select Image Rotate
parameter: parameter:
Rotate : 0,90,180,270 Rotate : 0,90,180,270
******************************************************************************/ ******************************************************************************/
void Paint_SetRotate(uint16_t Rotate){ void Paint_SetRotate(uint16_t Rotate) {
if(Rotate == ROTATE_0 || Rotate == ROTATE_90 || Rotate == ROTATE_180 || Rotate == ROTATE_270) { if(Rotate == ROTATE_0 || Rotate == ROTATE_90 || Rotate == ROTATE_180 || Rotate == ROTATE_270) {
// Debug("Set image Rotate %d\r\n", Rotate); // Debug("Set image Rotate %d\r\n", Rotate);
Paint.Rotate = Rotate; Paint.Rotate = Rotate;
@@ -145,9 +145,9 @@ function: Select Image mirror
parameter: parameter:
mirror :Not mirror,Horizontal mirror,Vertical mirror,Origin mirror mirror :Not mirror,Horizontal mirror,Vertical mirror,Origin mirror
******************************************************************************/ ******************************************************************************/
void Paint_SetMirroring(uint8_t mirror){ void Paint_SetMirroring(uint8_t mirror) {
if(mirror == MIRROR_NONE || mirror == MIRROR_HORIZONTAL || if(mirror == MIRROR_NONE || mirror == MIRROR_HORIZONTAL ||
mirror == MIRROR_VERTICAL || mirror == MIRROR_ORIGIN) { mirror == MIRROR_VERTICAL || mirror == MIRROR_ORIGIN) {
Paint.Mirror = mirror; Paint.Mirror = mirror;
} else { } else {
Debug("mirror should be MIRROR_NONE, MIRROR_HORIZONTAL, \ Debug("mirror should be MIRROR_NONE, MIRROR_HORIZONTAL, \
@@ -155,17 +155,17 @@ void Paint_SetMirroring(uint8_t mirror){
} }
} }
void Paint_SetScale(uint8_t scale){ void Paint_SetScale(uint8_t scale) {
if(scale == 2){ if(scale == 2) {
Paint.Scale = scale; Paint.Scale = scale;
Paint.WidthByte = (Paint.WidthMemory % 8 == 0)? (Paint.WidthMemory / 8 ): (Paint.WidthMemory / 8 + 1); Paint.WidthByte = (Paint.WidthMemory % 8 == 0)? (Paint.WidthMemory / 8 ): (Paint.WidthMemory / 8 + 1);
}else if(scale == 4) { } else if(scale == 4) {
Paint.Scale = scale; Paint.Scale = scale;
Paint.WidthByte = (Paint.WidthMemory % 4 == 0)? (Paint.WidthMemory / 4 ): (Paint.WidthMemory / 4 + 1); Paint.WidthByte = (Paint.WidthMemory % 4 == 0)? (Paint.WidthMemory / 4 ): (Paint.WidthMemory / 4 + 1);
}else if(scale == 7) { } else if(scale == 7) {
Paint.Scale = 7; Paint.Scale = 7;
Paint.WidthByte = (Paint.WidthMemory % 2 == 0)? (Paint.WidthMemory / 2 ): (Paint.WidthMemory / 2 + 1); Paint.WidthByte = (Paint.WidthMemory % 2 == 0)? (Paint.WidthMemory / 2 ): (Paint.WidthMemory / 2 + 1);
}else { } else {
Debug("Set Scale Input parameter error\r\n"); Debug("Set Scale Input parameter error\r\n");
Debug("Scale Only support: 2 4 7\r\n"); Debug("Scale Only support: 2 4 7\r\n");
} }
@@ -177,8 +177,8 @@ parameter:
Ypoint : At point Y Ypoint : At point Y
Color : Painted colors Color : Painted colors
******************************************************************************/ ******************************************************************************/
void Paint_SetPixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color){ void Paint_SetPixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color) {
if(Xpoint > Paint.Width || Ypoint > Paint.Height){ if(Xpoint > Paint.Width || Ypoint > Paint.Height) {
Debug("Exceeding display boundaries\r\n"); Debug("Exceeding display boundaries\r\n");
return; return;
} }
@@ -221,79 +221,79 @@ void Paint_SetPixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color){
return; return;
} }
if(X > Paint.WidthMemory || Y > Paint.HeightMemory){ if(X > Paint.WidthMemory || Y > Paint.HeightMemory) {
Debug("Exceeding display boundaries\r\n"); Debug("Exceeding display boundaries\r\n");
return; return;
} }
if(Paint.Scale == 2){ if(Paint.Scale == 2) {
uint32_t Addr = X / 8 + Y * Paint.WidthByte; uint32_t Addr = X / 8 + Y * Paint.WidthByte;
uint8_t Rdata = Paint.Image[Addr]; uint8_t Rdata = Paint.Image[Addr];
if(Color == BLACK) if(Color == BLACK)
Paint.Image[Addr] = Rdata & ~(0x80 >> (X % 8)); Paint.Image[Addr] = Rdata & ~(0x80 >> (X % 8));
else else
Paint.Image[Addr] = Rdata | (0x80 >> (X % 8)); Paint.Image[Addr] = Rdata | (0x80 >> (X % 8));
}else if(Paint.Scale == 4){ } else if(Paint.Scale == 4) {
uint32_t Addr = X / 4 + Y * Paint.WidthByte; uint32_t Addr = X / 4 + Y * Paint.WidthByte;
Color = Color % 4;//Guaranteed color scale is 4 --- 0~3 Color = Color % 4;//Guaranteed color scale is 4 --- 0~3
uint8_t Rdata = Paint.Image[Addr]; uint8_t Rdata = Paint.Image[Addr];
Rdata = Rdata & (~(0xC0 >> ((X % 4)*2))); Rdata = Rdata & (~(0xC0 >> ((X % 4)*2)));
Paint.Image[Addr] = Rdata | ((Color << 6) >> ((X % 4)*2)); Paint.Image[Addr] = Rdata | ((Color << 6) >> ((X % 4)*2));
}else if(Paint.Scale == 7){ } else if(Paint.Scale == 7) {
uint16_t Width = Paint.WidthMemory*3%8 == 0 ? Paint.WidthMemory*3/8 : Paint.WidthMemory*3/8+1; uint16_t Width = Paint.WidthMemory*3%8 == 0 ? Paint.WidthMemory*3/8 : Paint.WidthMemory*3/8+1;
uint32_t Addr = (Xpoint * 3) / 8 + Ypoint * Width; uint32_t Addr = (Xpoint * 3) / 8 + Ypoint * Width;
uint8_t shift, Rdata, Rdata2; uint8_t shift, Rdata, Rdata2;
shift = (Xpoint+Ypoint*Paint.HeightMemory) % 8; shift = (Xpoint+Ypoint*Paint.HeightMemory) % 8;
switch(shift) { switch(shift) {
case 0 : case 0 :
Rdata = Paint.Image[Addr] & 0x1f; Rdata = Paint.Image[Addr] & 0x1f;
Rdata = Rdata | ((Color << 5) & 0xe0); Rdata = Rdata | ((Color << 5) & 0xe0);
Paint.Image[Addr] = Rdata; Paint.Image[Addr] = Rdata;
break; break;
case 1 : case 1 :
Rdata = Paint.Image[Addr] & 0xe3; Rdata = Paint.Image[Addr] & 0xe3;
Rdata = Rdata | ((Color << 2) & 0x1c); Rdata = Rdata | ((Color << 2) & 0x1c);
Paint.Image[Addr] = Rdata; Paint.Image[Addr] = Rdata;
break; break;
case 2 : case 2 :
Rdata = Paint.Image[Addr] & 0xfc; Rdata = Paint.Image[Addr] & 0xfc;
Rdata2 = Paint.Image[Addr + 1] & 0x7f; Rdata2 = Paint.Image[Addr + 1] & 0x7f;
Rdata = Rdata | ((Color >> 1) & 0x03); Rdata = Rdata | ((Color >> 1) & 0x03);
Rdata2 = Rdata2 | ((Color << 7) & 0x80); Rdata2 = Rdata2 | ((Color << 7) & 0x80);
Paint.Image[Addr] = Rdata; Paint.Image[Addr] = Rdata;
Paint.Image[Addr + 1] = Rdata2; Paint.Image[Addr + 1] = Rdata2;
break; break;
case 3 : case 3 :
Rdata = Paint.Image[Addr] & 0x8f; Rdata = Paint.Image[Addr] & 0x8f;
Rdata = Rdata | ((Color << 4) & 0x70); Rdata = Rdata | ((Color << 4) & 0x70);
Paint.Image[Addr] = Rdata; Paint.Image[Addr] = Rdata;
break; break;
case 4 : case 4 :
Rdata = Paint.Image[Addr] & 0xf1; Rdata = Paint.Image[Addr] & 0xf1;
Rdata = Rdata | ((Color << 1) & 0x0e); Rdata = Rdata | ((Color << 1) & 0x0e);
Paint.Image[Addr] = Rdata; Paint.Image[Addr] = Rdata;
break; break;
case 5 : case 5 :
Rdata = Paint.Image[Addr] & 0xfe; Rdata = Paint.Image[Addr] & 0xfe;
Rdata2 = Paint.Image[Addr + 1] & 0x3f; Rdata2 = Paint.Image[Addr + 1] & 0x3f;
Rdata = Rdata | ((Color >> 2) & 0x01); Rdata = Rdata | ((Color >> 2) & 0x01);
Rdata2 = Rdata2 | ((Color << 6) & 0xc0); Rdata2 = Rdata2 | ((Color << 6) & 0xc0);
Paint.Image[Addr] = Rdata; Paint.Image[Addr] = Rdata;
Paint.Image[Addr + 1] = Rdata2; Paint.Image[Addr + 1] = Rdata2;
break; break;
case 6 : case 6 :
Rdata = Paint.Image[Addr] & 0xc7; Rdata = Paint.Image[Addr] & 0xc7;
Rdata = Rdata | ((Color << 3) & 0x38); Rdata = Rdata | ((Color << 3) & 0x38);
Paint.Image[Addr] = Rdata; Paint.Image[Addr] = Rdata;
break; break;
case 7 : case 7 :
Rdata = Paint.Image[Addr] & 0xf8; Rdata = Paint.Image[Addr] & 0xf8;
Rdata = Rdata | (Color & 0x07); Rdata = Rdata | (Color & 0x07);
Paint.Image[Addr] = Rdata; Paint.Image[Addr] = Rdata;
break; break;
} }
} }
} }
@@ -302,30 +302,30 @@ function: Clear the color of the picture
parameter: parameter:
Color : Painted colors Color : Painted colors
******************************************************************************/ ******************************************************************************/
void Paint_Clear(uint16_t Color){ void Paint_Clear(uint16_t Color) {
if(Paint.Scale == 2 || Paint.Scale == 4) { if(Paint.Scale == 2 || Paint.Scale == 4) {
for (uint16_t Y = 0; Y < Paint.HeightByte; Y++) { for (uint16_t Y = 0; Y < Paint.HeightByte; Y++) {
for (uint16_t X = 0; X < Paint.WidthByte; X++ ) {//8 pixel = 1 byte for (uint16_t X = 0; X < Paint.WidthByte; X++ ) {//8 pixel = 1 byte
uint32_t Addr = X + Y*Paint.WidthByte; uint32_t Addr = X + Y*Paint.WidthByte;
Paint.Image[Addr] = Color; Paint.Image[Addr] = Color;
} }
}
} }
} if(Paint.Scale == 7) {
if(Paint.Scale == 7) { Color = (uint8_t)Color;
Color = (uint8_t)Color; uint16_t Width = (Paint.WidthMemory * 3 % 8 == 0)? (Paint.WidthMemory * 3 / 8 ): (Paint.WidthMemory * 3 / 8 + 1);
uint16_t Width = (Paint.WidthMemory * 3 % 8 == 0)? (Paint.WidthMemory * 3 / 8 ): (Paint.WidthMemory * 3 / 8 + 1); for (uint16_t Y = 0; Y < Paint.HeightByte; Y++) {
for (uint16_t Y = 0; Y < Paint.HeightByte; Y++) { for (uint16_t X = 0; X < Width; X++ ) {
for (uint16_t X = 0; X < Width; X++ ) { uint32_t Addr = X + Y * Width;
uint32_t Addr = X + Y * Width; if((X + Y * Width)%3 == 0)
if((X + Y * Width)%3 == 0) Paint.Image[Addr] = ((Color<<5) | (Color<<2) | (Color>>1));
Paint.Image[Addr] = ((Color<<5) | (Color<<2) | (Color>>1)); else if((X + Y * Width)%3 == 1)
else if((X + Y * Width)%3 == 1) Paint.Image[Addr] = ((Color<<7) | (Color<<4) | (Color<<1) | (Color>>2));
Paint.Image[Addr] = ((Color<<7) | (Color<<4) | (Color<<1) | (Color>>2)); else if((X + Y * Width)%3 == 2)
else if((X + Y * Width)%3 == 2) Paint.Image[Addr] = ((Color<<6) | (Color<<3) | Color);
Paint.Image[Addr] = ((Color<<6) | (Color<<3) | Color); }
} }
} }
}
} }
/****************************************************************************** /******************************************************************************
@@ -337,7 +337,7 @@ parameter:
Yend : y end point Yend : y end point
Color : Painted colors Color : Painted colors
******************************************************************************/ ******************************************************************************/
void Paint_ClearWindows(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color){ void Paint_ClearWindows(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, uint16_t Color) {
uint16_t X, Y; uint16_t X, Y;
for (Y = Ystart; Y < Yend; Y++) { for (Y = Ystart; Y < Yend; Y++) {
for (X = Xstart; X < Xend; X++) {//8 pixel = 1 byte for (X = Xstart; X < Xend; X++) {//8 pixel = 1 byte
@@ -356,13 +356,13 @@ parameter:
Dot_Style : point Style Dot_Style : point Style
******************************************************************************/ ******************************************************************************/
void Paint_DrawPoint(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color, void Paint_DrawPoint(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color,
DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style){ DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style) {
if (Xpoint > Paint.Width || Ypoint > Paint.Height) { if (Xpoint > Paint.Width || Ypoint > Paint.Height) {
Debug("Paint_DrawPoint Input exceeds the normal display range\r\n"); Debug("Paint_DrawPoint Input exceeds the normal display range\r\n");
return; return;
} }
int16_t XDir_Num , YDir_Num; int16_t XDir_Num, YDir_Num;
if (Dot_Style == DOT_FILL_AROUND) { if (Dot_Style == DOT_FILL_AROUND) {
for (XDir_Num = 0; XDir_Num < 2 * Dot_Pixel - 1; XDir_Num++) { for (XDir_Num = 0; XDir_Num < 2 * Dot_Pixel - 1; XDir_Num++) {
for (YDir_Num = 0; YDir_Num < 2 * Dot_Pixel - 1; YDir_Num++) { for (YDir_Num = 0; YDir_Num < 2 * Dot_Pixel - 1; YDir_Num++) {
@@ -395,7 +395,7 @@ void Paint_DrawLine(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Ye
uint16_t Color, DOT_PIXEL Line_width, LINE_STYLE Line_Style) uint16_t Color, DOT_PIXEL Line_width, LINE_STYLE Line_Style)
{ {
if (Xstart > Paint.Width || Ystart > Paint.Height || if (Xstart > Paint.Width || Ystart > Paint.Height ||
Xend > Paint.Width || Yend > Paint.Height) { Xend > Paint.Width || Yend > Paint.Height) {
Debug("Paint_DrawLine Input exceeds the normal display range\r\n"); Debug("Paint_DrawLine Input exceeds the normal display range\r\n");
return; return;
} }
@@ -446,9 +446,9 @@ parameter:
Draw_Fill : Whether to fill the inside of the rectangle Draw_Fill : Whether to fill the inside of the rectangle
******************************************************************************/ ******************************************************************************/
void Paint_DrawRectangle(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, void Paint_DrawRectangle(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend,
uint16_t Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill){ uint16_t Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill) {
if (Xstart > Paint.Width || Ystart > Paint.Height || if (Xstart > Paint.Width || Ystart > Paint.Height ||
Xend > Paint.Width || Yend > Paint.Height) { Xend > Paint.Width || Yend > Paint.Height) {
Debug("Input exceeds the normal display range\r\n"); Debug("Input exceeds the normal display range\r\n");
return; return;
} }
@@ -456,7 +456,7 @@ void Paint_DrawRectangle(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16
if (Draw_Fill) { if (Draw_Fill) {
uint16_t Ypoint; uint16_t Ypoint;
for(Ypoint = Ystart; Ypoint < Yend; Ypoint++) { for(Ypoint = Ystart; Ypoint < Yend; Ypoint++) {
Paint_DrawLine(Xstart, Ypoint, Xend, Ypoint, Color , Line_width, LINE_STYLE_SOLID); Paint_DrawLine(Xstart, Ypoint, Xend, Ypoint, Color, Line_width, LINE_STYLE_SOLID);
} }
} else { } else {
Paint_DrawLine(Xstart, Ystart, Xend, Ystart, Color, Line_width, LINE_STYLE_SOLID); Paint_DrawLine(Xstart, Ystart, Xend, Ystart, Color, Line_width, LINE_STYLE_SOLID);
@@ -478,7 +478,7 @@ parameter:
Draw_Fill : Whether to fill the inside of the Circle Draw_Fill : Whether to fill the inside of the Circle
******************************************************************************/ ******************************************************************************/
void Paint_DrawCircle(uint16_t X_Center, uint16_t Y_Center, uint16_t Radius, void Paint_DrawCircle(uint16_t X_Center, uint16_t Y_Center, uint16_t Radius,
uint16_t Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill){ uint16_t Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill) {
if (X_Center > Paint.Width || Y_Center >= Paint.Height) { if (X_Center > Paint.Width || Y_Center >= Paint.Height) {
Debug("Paint_DrawCircle Input exceeds the normal display range\r\n"); Debug("Paint_DrawCircle Input exceeds the normal display range\r\n");
return; return;
@@ -545,7 +545,7 @@ parameter:
Color_Background : Select the background color Color_Background : Select the background color
******************************************************************************/ ******************************************************************************/
void Paint_DrawChar(uint16_t Xpoint, uint16_t Ypoint, const char Acsii_Char, void Paint_DrawChar(uint16_t Xpoint, uint16_t Ypoint, const char Acsii_Char,
sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background){ sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background) {
uint16_t Page, Column; uint16_t Page, Column;
if (Xpoint > Paint.Width || Ypoint > Paint.Height) { if (Xpoint > Paint.Width || Ypoint > Paint.Height) {
@@ -576,7 +576,7 @@ void Paint_DrawChar(uint16_t Xpoint, uint16_t Ypoint, const char Acsii_Char,
} }
void Paint_DrawIcon(uint16_t Xpoint, uint16_t Ypoint, const ICON_tpe icon, void Paint_DrawIcon(uint16_t Xpoint, uint16_t Ypoint, const ICON_tpe icon,
sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background){ sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background) {
uint16_t Page, Column; uint16_t Page, Column;
if (Xpoint > Paint.Width || Ypoint > Paint.Height) { if (Xpoint > Paint.Width || Ypoint > Paint.Height) {
@@ -618,7 +618,7 @@ parameter:
Color_Background : Select the background color Color_Background : Select the background color
******************************************************************************/ ******************************************************************************/
void Paint_DrawString_EN(uint16_t Xstart, uint16_t Ystart, const char * pString, void Paint_DrawString_EN(uint16_t Xstart, uint16_t Ystart, const char * pString,
sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background){ sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background) {
uint16_t Xpoint = Xstart; uint16_t Xpoint = Xstart;
uint16_t Ypoint = Ystart; uint16_t Ypoint = Ystart;
@@ -656,8 +656,8 @@ parameter:
Color_Background : Select the background color Color_Background : Select the background color
******************************************************************************/ ******************************************************************************/
#define ARRAY_LEN 255 #define ARRAY_LEN 255
void Paint_DrawIntUnit(uint16_t Xpoint, uint16_t Ypoint, int32_t Number,const char * pString, sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background){ void Paint_DrawIntUnit(uint16_t Xpoint, uint16_t Ypoint, int32_t Number,const char * pString, sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background) {
int16_t Str_Bit = 0, Unit_Bit = 0; int16_t Str_Bit = 0, Unit_Bit = 0;
uint8_t Str_Array[ARRAY_LEN] = {0}; uint8_t Str_Array[ARRAY_LEN] = {0};
uint8_t *pStr = Str_Array; uint8_t *pStr = Str_Array;
@@ -680,8 +680,8 @@ void Paint_DrawIntUnit(uint16_t Xpoint, uint16_t Ypoint, int32_t Number,const ch
Paint_DrawString_EN(Xpoint, Ypoint, (const char*)pStr, Font, Color_Background, Color_Foreground); Paint_DrawString_EN(Xpoint, Ypoint, (const char*)pStr, Font, Color_Background, Color_Foreground);
} }
void Paint_DrawFltUnit(uint16_t Xpoint, uint16_t Ypoint, float Number,const char * pString, sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background){ void Paint_DrawFltUnit(uint16_t Xpoint, uint16_t Ypoint, float Number,const char * pString, sFONT* Font, uint16_t Color_Foreground, uint16_t Color_Background) {
int16_t Str_Bit = 0, Unit_Bit = 0; int16_t Str_Bit = 0, Unit_Bit = 0;
uint8_t Str_Array[ARRAY_LEN] = {0}; uint8_t Str_Array[ARRAY_LEN] = {0};
uint8_t *pStr = Str_Array; uint8_t *pStr = Str_Array;
@@ -716,15 +716,15 @@ parameter:
Color_Background : Select the background color Color_Background : Select the background color
******************************************************************************/ ******************************************************************************/
void Paint_DrawTime(uint16_t Xstart, uint16_t Ystart, strDateTime *pTime, sFONT* Font, void Paint_DrawTime(uint16_t Xstart, uint16_t Ystart, strDateTime *pTime, sFONT* Font,
uint16_t Color_Foreground, uint16_t Color_Background){ uint16_t Color_Foreground, uint16_t Color_Background) {
uint8_t value[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; uint8_t value[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
uint16_t Dx = Font->Width; uint16_t Dx = Font->Width;
//Write data into the cache //Write data into the cache
Paint_DrawChar(Xstart , Ystart, value[pTime->hour / 10], Font, Color_Background, Color_Foreground); Paint_DrawChar(Xstart, Ystart, value[pTime->hour / 10], Font, Color_Background, Color_Foreground);
Paint_DrawChar(Xstart + Dx , Ystart, value[pTime->hour % 10], Font, Color_Background, Color_Foreground); Paint_DrawChar(Xstart + Dx, Ystart, value[pTime->hour % 10], Font, Color_Background, Color_Foreground);
Paint_DrawChar(Xstart + Dx + Dx / 4 + Dx / 2 , Ystart, ':' , Font, Color_Background, Color_Foreground); Paint_DrawChar(Xstart + Dx + Dx / 4 + Dx / 2, Ystart, ':', Font, Color_Background, Color_Foreground);
Paint_DrawChar(Xstart + Dx * 2 + Dx / 2 , Ystart, value[pTime->minute / 10] , Font, Color_Background, Color_Foreground); Paint_DrawChar(Xstart + Dx * 2 + Dx / 2, Ystart, value[pTime->minute / 10], Font, Color_Background, Color_Foreground);
Paint_DrawChar(Xstart + Dx * 3 + Dx / 2 , Ystart, value[pTime->minute % 10] , Font, Color_Background, Color_Foreground); Paint_DrawChar(Xstart + Dx * 3 + Dx / 2, Ystart, value[pTime->minute % 10], Font, Color_Background, Color_Foreground);
} }
+8 -8
View File
@@ -64,13 +64,13 @@ typedef enum {
**/ **/
typedef enum { typedef enum {
DOT_PIXEL_1X1 = 1, // 1 x 1 DOT_PIXEL_1X1 = 1, // 1 x 1
DOT_PIXEL_2X2 , // 2 X 2 DOT_PIXEL_2X2, // 2 X 2
DOT_PIXEL_3X3 , // 3 X 3 DOT_PIXEL_3X3, // 3 X 3
DOT_PIXEL_4X4 , // 4 X 4 DOT_PIXEL_4X4, // 4 X 4
DOT_PIXEL_5X5 , // 5 X 5 DOT_PIXEL_5X5, // 5 X 5
DOT_PIXEL_6X6 , // 6 X 6 DOT_PIXEL_6X6, // 6 X 6
DOT_PIXEL_7X7 , // 7 X 7 DOT_PIXEL_7X7, // 7 X 7
DOT_PIXEL_8X8 , // 8 X 8 DOT_PIXEL_8X8, // 8 X 8
} DOT_PIXEL; } DOT_PIXEL;
#define DOT_PIXEL_DFT DOT_PIXEL_1X1 //Default dot pilex #define DOT_PIXEL_DFT DOT_PIXEL_1X1 //Default dot pilex
@@ -79,7 +79,7 @@ typedef enum {
**/ **/
typedef enum { typedef enum {
DOT_FILL_AROUND = 1, // dot pixel 1 x 1 DOT_FILL_AROUND = 1, // dot pixel 1 x 1
DOT_FILL_RIGHTUP , // dot pixel 2 X 2 DOT_FILL_RIGHTUP, // dot pixel 2 X 2
} DOT_STYLE; } DOT_STYLE;
#define DOT_STYLE_DFT DOT_FILL_AROUND //Default dot pilex #define DOT_STYLE_DFT DOT_FILL_AROUND //Default dot pilex
+1332 -1332
View File
File diff suppressed because it is too large Load Diff
+1712 -1712
View File
File diff suppressed because it is too large Load Diff
+2092 -2092
View File
File diff suppressed because it is too large Load Diff
+2472 -2472
View File
File diff suppressed because it is too large Load Diff
+2186 -2186
View File
File diff suppressed because it is too large Load Diff
+952 -952
View File
File diff suppressed because it is too large Load Diff
+12 -12
View File
@@ -40,7 +40,7 @@
#define __FONTS_H #define __FONTS_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
@@ -49,9 +49,9 @@
//ASCII //ASCII
typedef struct _tFont typedef struct _tFont
{ {
const uint8_t *table; const uint8_t *table;
uint16_t Width; uint16_t Width;
uint16_t Height; uint16_t Height;
} sFONT; } sFONT;
@@ -66,19 +66,19 @@ extern sFONT FontIcon;
typedef enum { typedef enum {
ICON_LOGO = 0, ICON_LOGO = 0,
ICON_WARN, ICON_WARN,
ICON_TEMPERATURE, ICON_DROP, ICON_SCALE, ICON_POLUTION, ICON_TEMPERATURE, ICON_DROP, ICON_SCALE, ICON_POLUTION,
ICON_SUN, ICON_SUN,
ICON_CLOUD, ICON_CLOUD_RAIN, ICON_CLOUD_SNOW, ICON_CLOUD, ICON_CLOUD_RAIN, ICON_CLOUD_SNOW,
ICON_CLOUD_THUNDER, ICON_CLOUD_SUN, ICON_CLOUD_SUNNYRAIN, ICON_CLOUD_THUNDER, ICON_CLOUD_SUN, ICON_CLOUD_SUNNYRAIN,
ICON_SUNSET, ICON_SUNRISE, ICON_SUNSET, ICON_SUNRISE,
ICON_BULB ICON_BULB
} ICON_tpe; } ICON_tpe;
+1155 -1155
View File
File diff suppressed because it is too large Load Diff
+618 -618
View File
File diff suppressed because it is too large Load Diff
+118 -118
View File
@@ -46,138 +46,138 @@ emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n\
class Influx { class Influx {
public: public:
Influx(Sensor* _sensor, OWM* _owm[]): sensor(_sensor), owm(_owm) {} Influx(Sensor* _sensor, OWM* _owm[]): sensor(_sensor), owm(_owm) {}
void check(){ void check() {
if (client.validateConnection()) { if (client.validateConnection()) {
Serial.print("Connected to InfluxDB: "); Serial.print("Connected to InfluxDB: ");
Serial.println(client.getServerUrl()); Serial.println(client.getServerUrl());
} else { } else {
Serial.print("InfluxDB connection failed: "); Serial.print("InfluxDB connection failed: ");
Serial.println(client.getLastErrorMessage()); Serial.println(client.getLastErrorMessage());
} }
}
void record() {
uint8_t i = 0;
while(owm && owm[i] != NULL) {
record_weather(owm[i]);
++i;
}
if(sensor) record_local();
}
void record(bool w, bool s) {
uint8_t i = 0;
while(w && owm && owm[i] != NULL) {
record_weather(owm[i]);
++i;
}
if(sensor && s) record_local();
}
void record_local() {
if(!sensor) return;
Serial.println("InfluxDB: Uploading Local Data");
dp.clearFields();
dp.clearTags();
dp.addTag("device", "WESP0");
dp.addTag("location", "local");
dp.addField("temperature", sensor->temp);
dp.addField("pressure", sensor->pres);
dp.addField("humidity", sensor->temp);
dp.addField("heat_index", sensor->heatidx);
dp.addField("light", sensor->light);
dp.addField("uv", sensor->uv);
dp.addField("uvi", sensor->uvi);
dp.addField("light_full", sensor->light_full);
dp.addField("light_vis", sensor->light_vis);
dp.addField("light_ir", sensor->light_ir);
dp.addField("light_lux", sensor->light_lux);
dp.addField("voc", sensor->voci);
dp.addField("pm10_standard", sensor->pmd.pm10_standard);
dp.addField("pm25_standard", sensor->pmd.pm25_standard);
dp.addField("pm100_standard", sensor->pmd.pm100_standard);
dp.addField("pm10_env", sensor->pmd.pm10_env);
dp.addField("pm25_env", sensor->pmd.pm25_env);
dp.addField("pm100_env", sensor->pmd.pm100_env);
dp.addField("particles_03um", sensor->pmd.particles_03um);
dp.addField("particles_05um", sensor->pmd.particles_05um);
dp.addField("particles_10um", sensor->pmd.particles_10um);
dp.addField("particles_25um", sensor->pmd.particles_25um);
dp.addField("particles_50um", sensor->pmd.particles_50um);
dp.addField("particles_100um", sensor->pmd.particles_100um);
client.writePoint(dp);
Serial.println("InfluxDB: OK");
}
void record_weather() {
record(true,false);
}
void record_weather(OWM* owm) {
if(!owm) return;
Serial.println("InfluxDB: Uploading OWM Data");
if(!owm->valid_weather) {
Serial.println("InfluxDB: Error, not valid weather");
return;
} }
void record(){ JsonObject weather_0 = owm->weather["weather"][0];
uint8_t i = 0; JsonObject weather_main = owm->weather["main"];
while(owm && owm[i] != NULL){ JsonObject weather_sys = owm->weather["sys"];
record_weather(owm[i]); if(!weather_0 || !weather_main || !weather_sys ) return;
++i;
}
if(sensor) record_local();
}
void record(bool w, bool s){ dp.clearFields();
uint8_t i = 0; dp.clearTags();
while(w && owm && owm[i] != NULL){ dp.addTag("device", "WESP0");
record_weather(owm[i]); dp.addTag("location", owm->location);
++i;
} dp.addField("temperature", float(weather_main["temp"]));
if(sensor && s) record_local(); dp.addField("temperature_feel",float(weather_main["feels_like"]));
} dp.addField("pressure",int32_t(weather_main["pressure"]));
dp.addField("humidity",int32_t(weather_main["humidity"]));
void record_local(){ JsonObject weather_wind = owm->weather["wind"];
if(!sensor) return; dp.addField("wind_speed",weather_wind?float(weather_wind["speed"]):0.0);
Serial.println("InfluxDB: Uploading Local Data"); dp.addField("wind_dir",weather_wind?float(weather_wind["deg"]):0.0);
dp.addField("wind_gust",weather_wind?float(weather_wind["gust"]):0.0);
dp.clearFields(); dp.addField("sunrise", uint64_t(weather_sys["sunrise"]));
dp.clearTags(); dp.addField("sunset",uint64_t(weather_sys["sunset"]));
dp.addTag("device", "WESP0"); dp.addField("suntime",uint64_t(weather_sys["sunset"])-uint64_t(weather_sys["sunrise"]));
dp.addTag("location", "local");
dp.addField("temperature", sensor->temp);
dp.addField("pressure", sensor->pres);
dp.addField("humidity", sensor->temp);
dp.addField("heat_index", sensor->heatidx);
dp.addField("light", sensor->light);
dp.addField("uv", sensor->uv);
dp.addField("uvi", sensor->uvi);
dp.addField("light_full", sensor->light_full); JsonObject weather_rain = owm->weather["rain"];
dp.addField("light_vis", sensor->light_vis); dp.addField("precipitation_rain_1h",weather_rain?float(weather_rain["1h"]):0.0);
dp.addField("light_ir", sensor->light_ir); dp.addField("precipitation_rain_3h",weather_rain?float(weather_rain["3h"]):0.0);
dp.addField("light_lux", sensor->light_lux);
dp.addField("voc", sensor->voci); JsonObject weather_snow = owm->weather["snow"];
dp.addField("precipitation_snow_1h",weather_snow?float(weather_snow["1h"]):0.0);
dp.addField("precipitation_snow_3h",weather_snow?float(weather_snow["3h"]):0.0);
dp.addField("pm10_standard", sensor->pmd.pm10_standard); client.writePoint(dp);
dp.addField("pm25_standard", sensor->pmd.pm25_standard); Serial.println("InfluxDB: OK");
dp.addField("pm100_standard", sensor->pmd.pm100_standard); }
dp.addField("pm10_env", sensor->pmd.pm10_env);
dp.addField("pm25_env", sensor->pmd.pm25_env);
dp.addField("pm100_env", sensor->pmd.pm100_env);
dp.addField("particles_03um", sensor->pmd.particles_03um);
dp.addField("particles_05um", sensor->pmd.particles_05um);
dp.addField("particles_10um", sensor->pmd.particles_10um);
dp.addField("particles_25um", sensor->pmd.particles_25um);
dp.addField("particles_50um", sensor->pmd.particles_50um);
dp.addField("particles_100um", sensor->pmd.particles_100um);
client.writePoint(dp);
Serial.println("InfluxDB: OK");
}
void record_weather(){
record(true,false);
}
void record_weather(OWM* owm){
if(!owm) return;
Serial.println("InfluxDB: Uploading OWM Data");
if(!owm->valid_weather) {
Serial.println("InfluxDB: Error, not valid weather");
return;
}
JsonObject weather_0 = owm->weather["weather"][0];
JsonObject weather_main = owm->weather["main"];
JsonObject weather_sys = owm->weather["sys"];
if(!weather_0 || !weather_main || !weather_sys ) return;
dp.clearFields();
dp.clearTags();
dp.addTag("device", "WESP0");
dp.addTag("location", owm->location);
dp.addField("temperature", float(weather_main["temp"]));
dp.addField("temperature_feel",float(weather_main["feels_like"]));
dp.addField("pressure",int32_t(weather_main["pressure"]));
dp.addField("humidity",int32_t(weather_main["humidity"]));
JsonObject weather_wind = owm->weather["wind"]; private:
dp.addField("wind_speed",weather_wind?float(weather_wind["speed"]):0.0); OWM** owm;
dp.addField("wind_dir",weather_wind?float(weather_wind["deg"]):0.0); Sensor* sensor;
dp.addField("wind_gust",weather_wind?float(weather_wind["gust"]):0.0);
dp.addField("sunrise", uint64_t(weather_sys["sunrise"])); InfluxDBClient client = InfluxDBClient(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, cert);
dp.addField("sunset",uint64_t(weather_sys["sunset"])); Point dp = Point("environment");
dp.addField("suntime",uint64_t(weather_sys["sunset"])-uint64_t(weather_sys["sunrise"]));
JsonObject weather_rain = owm->weather["rain"];
dp.addField("precipitation_rain_1h",weather_rain?float(weather_rain["1h"]):0.0);
dp.addField("precipitation_rain_3h",weather_rain?float(weather_rain["3h"]):0.0);
JsonObject weather_snow = owm->weather["snow"];
dp.addField("precipitation_snow_1h",weather_snow?float(weather_snow["1h"]):0.0);
dp.addField("precipitation_snow_3h",weather_snow?float(weather_snow["3h"]):0.0);
client.writePoint(dp);
Serial.println("InfluxDB: OK");
}
private:
OWM** owm;
Sensor* sensor;
InfluxDBClient client = InfluxDBClient(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, cert);
Point dp = Point("environment");
}; };
#endif #endif
+161 -161
View File
@@ -20,84 +20,84 @@ String _NTPserver="";
// NTPserver is the name of the NTPserver // NTPserver is the name of the NTPserver
bool NTPtime::setSendInterval(unsigned long _sendInterval_) { bool NTPtime::setSendInterval(unsigned long _sendInterval_) {
bool retVal = false; bool retVal = false;
if(_sendInterval_ <= MAX_SEND_INTERVAL) { if(_sendInterval_ <= MAX_SEND_INTERVAL) {
_sendInterval = _sendInterval_ * SEC_TO_MS; _sendInterval = _sendInterval_ * SEC_TO_MS;
retVal = true; retVal = true;
} }
return retVal; return retVal;
} }
bool NTPtime::setRecvTimeout(unsigned long _recvTimeout_) { bool NTPtime::setRecvTimeout(unsigned long _recvTimeout_) {
bool retVal = false; bool retVal = false;
if(_recvTimeout_ <= MAC_RECV_TIMEOUT) { if(_recvTimeout_ <= MAC_RECV_TIMEOUT) {
_recvTimeout = _recvTimeout_ * SEC_TO_MS; _recvTimeout = _recvTimeout_ * SEC_TO_MS;
retVal = true; retVal = true;
} }
return retVal; return retVal;
} }
NTPtime::NTPtime(String NTPserver) { NTPtime::NTPtime(String NTPserver) {
_NTPserver = NTPserver; _NTPserver = NTPserver;
_sendPhase = true; _sendPhase = true;
_sentTime = 0; _sentTime = 0;
_sendInterval = SEND_INTRVL_DEFAULT * SEC_TO_MS; _sendInterval = SEND_INTRVL_DEFAULT * SEC_TO_MS;
_recvTimeout = RECV_TIMEOUT_DEFATUL * SEC_TO_MS; _recvTimeout = RECV_TIMEOUT_DEFATUL * SEC_TO_MS;
} }
// Converts a unix time stamp to a strDateTime structure // Converts a unix time stamp to a strDateTime structure
strDateTime NTPtime::ConvertUnixTimestamp( unsigned long _tempTimeStamp) { strDateTime NTPtime::ConvertUnixTimestamp( unsigned long _tempTimeStamp) {
strDateTime _tempDateTime; strDateTime _tempDateTime;
uint8_t _year, _month, _monthLength; uint8_t _year, _month, _monthLength;
uint32_t _time; uint32_t _time;
unsigned long _days; unsigned long _days;
_time = (uint32_t)_tempTimeStamp; _time = (uint32_t)_tempTimeStamp;
_tempDateTime.second = _time % 60; _tempDateTime.second = _time % 60;
_time /= 60; // now it is minutes _time /= 60; // now it is minutes
_tempDateTime.minute = _time % 60; _tempDateTime.minute = _time % 60;
_time /= 60; // now it is hours _time /= 60; // now it is hours
_tempDateTime.hour = _time % 24; _tempDateTime.hour = _time % 24;
_time /= 24; // now it is _days _time /= 24; // now it is _days
_tempDateTime.dayofWeek = ((_time + 4) % 7) + 1; // Sunday is day 1 _tempDateTime.dayofWeek = ((_time + 4) % 7) + 1; // Sunday is day 1
_year = 0; _year = 0;
_days = 0; _days = 0;
while ((unsigned)(_days += (LEAP_YEAR(_year) ? 366 : 365)) <= _time) { while ((unsigned)(_days += (LEAP_YEAR(_year) ? 366 : 365)) <= _time) {
_year++; _year++;
} }
_tempDateTime.year = _year; // year is offset from 1970 _tempDateTime.year = _year; // year is offset from 1970
_days -= LEAP_YEAR(_year) ? 366 : 365; _days -= LEAP_YEAR(_year) ? 366 : 365;
_time -= _days; // now it is days in this year, starting at 0 _time -= _days; // now it is days in this year, starting at 0
_days = 0; _days = 0;
_month = 0; _month = 0;
_monthLength = 0; _monthLength = 0;
for (_month = 0; _month < 12; _month++) { for (_month = 0; _month < 12; _month++) {
if (_month == 1) { // february if (_month == 1) { // february
if (LEAP_YEAR(_year)) { if (LEAP_YEAR(_year)) {
_monthLength = 29; _monthLength = 29;
} else { } else {
_monthLength = 28; _monthLength = 28;
} }
} else { } else {
_monthLength = _monthDays[_month]; _monthLength = _monthDays[_month];
} }
if (_time >= _monthLength) { if (_time >= _monthLength) {
_time -= _monthLength; _time -= _monthLength;
} else { } else {
break; break;
} }
} }
_tempDateTime.month = _month + 1; // jan is month 1 _tempDateTime.month = _month + 1; // jan is month 1
_tempDateTime.day = _time + 1; // day of month _tempDateTime.day = _time + 1; // day of month
_tempDateTime.year += 1970; _tempDateTime.year += 1970;
return _tempDateTime; return _tempDateTime;
} }
@@ -106,134 +106,134 @@ strDateTime NTPtime::ConvertUnixTimestamp( unsigned long _tempTimeStamp) {
// //
boolean NTPtime::summerTime(unsigned long _timeStamp ) { boolean NTPtime::summerTime(unsigned long _timeStamp ) {
strDateTime _tempDateTime; strDateTime _tempDateTime;
_tempDateTime = ConvertUnixTimestamp(_timeStamp); _tempDateTime = ConvertUnixTimestamp(_timeStamp);
if (_tempDateTime.month < 3 || _tempDateTime.month > 10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez if (_tempDateTime.month < 3 || _tempDateTime.month > 10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez
if (_tempDateTime.month > 3 && _tempDateTime.month < 10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep if (_tempDateTime.month > 3 && _tempDateTime.month < 10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
if (_tempDateTime.month == 3 && (_tempDateTime.hour + 24 * _tempDateTime.day) >= (3 + 24 * (31 - (5 * _tempDateTime.year / 4 + 4) % 7)) || _tempDateTime.month == 10 && (_tempDateTime.hour + 24 * _tempDateTime.day) < (3 + 24 * (31 - (5 * _tempDateTime.year / 4 + 1) % 7))) if (_tempDateTime.month == 3 && (_tempDateTime.hour + 24 * _tempDateTime.day) >= (3 + 24 * (31 - (5 * _tempDateTime.year / 4 + 4) % 7)) || _tempDateTime.month == 10 && (_tempDateTime.hour + 24 * _tempDateTime.day) < (3 + 24 * (31 - (5 * _tempDateTime.year / 4 + 1) % 7)))
return true; return true;
else else
return false; return false;
} }
boolean NTPtime::daylightSavingTime(unsigned long _timeStamp) { boolean NTPtime::daylightSavingTime(unsigned long _timeStamp) {
strDateTime _tempDateTime; strDateTime _tempDateTime;
_tempDateTime = ConvertUnixTimestamp(_timeStamp); _tempDateTime = ConvertUnixTimestamp(_timeStamp);
if (_tempDateTime.month < 3 || _tempDateTime.month > 11) return false; //January, february, and december are out. if (_tempDateTime.month < 3 || _tempDateTime.month > 11) return false; //January, february, and december are out.
if (_tempDateTime.month > 3 && _tempDateTime.month < 11) return true; //April to October are in if (_tempDateTime.month > 3 && _tempDateTime.month < 11) return true; //April to October are in
int previousSunday = _tempDateTime.day - (_tempDateTime.dayofWeek - 1); // dow Sunday input was 1, int previousSunday = _tempDateTime.day - (_tempDateTime.dayofWeek - 1); // dow Sunday input was 1,
// -------------------- March --------------------------------------- // -------------------- March ---------------------------------------
//In march, we are DST if our previous Sunday was = to or after the 8th. //In march, we are DST if our previous Sunday was = to or after the 8th.
if (_tempDateTime.month == 3 ) { // in march, if previous Sunday is after the 8th, is DST if (_tempDateTime.month == 3 ) { // in march, if previous Sunday is after the 8th, is DST
// unless Sunday and hour < 2am // unless Sunday and hour < 2am
if ( previousSunday >= 8 ) { // Sunday = 1 if ( previousSunday >= 8 ) { // Sunday = 1
// return true if day > 14 or (dow == 1 and hour >= 2) // return true if day > 14 or (dow == 1 and hour >= 2)
return ((_tempDateTime.day > 14) || return ((_tempDateTime.day > 14) ||
((_tempDateTime.dayofWeek == 1 && _tempDateTime.hour >= 2) || _tempDateTime.dayofWeek > 1)); ((_tempDateTime.dayofWeek == 1 && _tempDateTime.hour >= 2) || _tempDateTime.dayofWeek > 1));
} // end if ( previousSunday >= 8 && _dateTime.dayofWeek > 0 ) } // end if ( previousSunday >= 8 && _dateTime.dayofWeek > 0 )
else else
{ {
// previousSunday has to be < 8 to get here // previousSunday has to be < 8 to get here
//return (previousSunday < 8 && (_tempDateTime.dayofWeek - 1) = 0 && _tempDateTime.hour >= 2) //return (previousSunday < 8 && (_tempDateTime.dayofWeek - 1) = 0 && _tempDateTime.hour >= 2)
return false; return false;
} // end else } // end else
} // end if (_tempDateTime.month == 3 ) } // end if (_tempDateTime.month == 3 )
// ------------------------------- November ------------------------------- // ------------------------------- November -------------------------------
// gets here only if month = November // gets here only if month = November
//In november we must be before the first Sunday to be dst. //In november we must be before the first Sunday to be dst.
//That means the previous Sunday must be before the 2nd. //That means the previous Sunday must be before the 2nd.
if (previousSunday < 1){ if (previousSunday < 1) {
// is not true for Sunday after 2am or any day after 1st Sunday any time // is not true for Sunday after 2am or any day after 1st Sunday any time
return ((_tempDateTime.dayofWeek == 1 && _tempDateTime.hour < 2) || (_tempDateTime.dayofWeek > 1)); return ((_tempDateTime.dayofWeek == 1 && _tempDateTime.hour < 2) || (_tempDateTime.dayofWeek > 1));
//return true; //return true;
}else{ } else {
// return false unless after first wk and dow = Sunday and hour < 2 // return false unless after first wk and dow = Sunday and hour < 2
return (_tempDateTime.day <8 && _tempDateTime.dayofWeek == 1 && _tempDateTime.hour < 2); return (_tempDateTime.day <8 && _tempDateTime.dayofWeek == 1 && _tempDateTime.hour < 2);
} }
} }
unsigned long NTPtime::adjustTimeZone(unsigned long _timeStamp, float _timeZone, byte _DayLightSaving) { unsigned long NTPtime::adjustTimeZone(unsigned long _timeStamp, float _timeZone, byte _DayLightSaving) {
strDateTime _tempDateTime; strDateTime _tempDateTime;
_timeStamp += (unsigned long)(_timeZone * 3600.0); // adjust timezone _timeStamp += (unsigned long)(_timeZone * 3600.0); // adjust timezone
if (_DayLightSaving ==1 && summerTime(_timeStamp)) _timeStamp += 3600; // European Summer time if (_DayLightSaving ==1 && summerTime(_timeStamp)) _timeStamp += 3600; // European Summer time
if (_DayLightSaving ==2 && daylightSavingTime(_timeStamp)) _timeStamp += 3600; // US daylight time if (_DayLightSaving ==2 && daylightSavingTime(_timeStamp)) _timeStamp += 3600; // US daylight time
return _timeStamp; return _timeStamp;
} }
strDateTime NTPtime::getNTPtime(float _timeZone, boolean _DayLightSaving) { strDateTime NTPtime::getNTPtime(float _timeZone, byte _DayLightSaving) {
Serial.println("NTP: Updating Time"); Serial.println("NTP: Updating Time");
int cb; int cb;
strDateTime _dateTime; strDateTime _dateTime;
unsigned long _unixTime = 0; unsigned long _unixTime = 0;
_dateTime.valid = false; _dateTime.valid = false;
unsigned long _currentTimeStamp; unsigned long _currentTimeStamp;
if (_sendPhase) { if (_sendPhase) {
if (_sentTime && ((millis() - _sentTime) < _sendInterval)) { if (_sentTime && ((millis() - _sentTime) < _sendInterval)) {
Serial.println("NTP: Too Fast"); Serial.println("NTP: Too Fast");
return _dateTime; return _dateTime;
} }
_sendPhase = false; _sendPhase = false;
UDPNTPClient.begin(1337); // Port for NTP receive UDPNTPClient.begin(1337); // Port for NTP receive
memset(_packetBuffer, 0, NTP_PACKET_SIZE); memset(_packetBuffer, 0, NTP_PACKET_SIZE);
_packetBuffer[0] = 0b11100011; // LI, Version, Mode _packetBuffer[0] = 0b11100011; // LI, Version, Mode
_packetBuffer[1] = 0; // Stratum, or type of clock _packetBuffer[1] = 0; // Stratum, or type of clock
_packetBuffer[2] = 6; // Polling Interval _packetBuffer[2] = 6; // Polling Interval
_packetBuffer[3] = 0xEC; // Peer Clock Precision _packetBuffer[3] = 0xEC; // Peer Clock Precision
_packetBuffer[12] = 49; _packetBuffer[12] = 49;
_packetBuffer[13] = 0x4E; _packetBuffer[13] = 0x4E;
_packetBuffer[14] = 49; _packetBuffer[14] = 49;
_packetBuffer[15] = 52; _packetBuffer[15] = 52;
UDPNTPClient.beginPacket(_NTPserver.c_str(), 123); UDPNTPClient.beginPacket(_NTPserver.c_str(), 123);
UDPNTPClient.write(_packetBuffer, NTP_PACKET_SIZE); UDPNTPClient.write(_packetBuffer, NTP_PACKET_SIZE);
UDPNTPClient.endPacket(); UDPNTPClient.endPacket();
_sentTime = millis(); _sentTime = millis();
} else { } else {
cb = UDPNTPClient.parsePacket(); cb = UDPNTPClient.parsePacket();
if (cb == 0) { if (cb == 0) {
if ((millis() - _sentTime) > _recvTimeout) { if ((millis() - _sentTime) > _recvTimeout) {
_sendPhase = true; _sendPhase = true;
_sentTime = 0; _sentTime = 0;
} }
} else { } else {
UDPNTPClient.read(_packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer UDPNTPClient.read(_packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord = word(_packetBuffer[40], _packetBuffer[41]); unsigned long highWord = word(_packetBuffer[40], _packetBuffer[41]);
unsigned long lowWord = word(_packetBuffer[42], _packetBuffer[43]); unsigned long lowWord = word(_packetBuffer[42], _packetBuffer[43]);
unsigned long secsSince1900 = highWord << 16 | lowWord; unsigned long secsSince1900 = highWord << 16 | lowWord;
const unsigned long seventyYears = 2208988800UL; const unsigned long seventyYears = 2208988800UL;
_unixTime = secsSince1900 - seventyYears; _unixTime = secsSince1900 - seventyYears;
if (_unixTime > 0) { if (_unixTime > 0) {
_currentTimeStamp = adjustTimeZone(_unixTime, _timeZone, _DayLightSaving); _currentTimeStamp = adjustTimeZone(_unixTime, _timeZone, _DayLightSaving);
_dateTime = ConvertUnixTimestamp(_currentTimeStamp); _dateTime = ConvertUnixTimestamp(_currentTimeStamp);
_dateTime.valid = true; _dateTime.valid = true;
} else } else
_dateTime.valid = false; _dateTime.valid = false;
_sendPhase = true; _sendPhase = true;
} }
} }
Serial.println("NTP: OK"); Serial.println("NTP: OK");
return _dateTime; return _dateTime;
} }
void NTPtime::updateNTPtime(){ void NTPtime::updateNTPtime() {
strDateTime ndt = getNTPtime(1.0f, true); strDateTime ndt = getNTPtime(1.0f, 1);
if(ndt.valid) dt = ndt; if(ndt.valid) dt = ndt;
}; };
+11 -11
View File
@@ -4,23 +4,23 @@
#include <WiFiUdp.h> #include <WiFiUdp.h>
struct strDateTime { struct strDateTime {
byte hour; byte hour;
byte minute; byte minute;
byte second; byte second;
int year; int year;
byte month; byte month;
byte day; byte day;
byte dayofWeek; byte dayofWeek;
boolean valid; boolean valid;
}; };
class NTPtime { class NTPtime {
public: public:
NTPtime(String NTPtime); NTPtime(String NTPtime);
strDateTime dt = {0}; strDateTime dt = {0};
strDateTime getNTPtime(float _timeZone, boolean _DayLightSaving); strDateTime getNTPtime(float _timeZone, byte _DayLightSaving);
void updateNTPtime(); void updateNTPtime();
@@ -32,7 +32,7 @@ class NTPtime {
static boolean daylightSavingTime(unsigned long _timeStamp); static boolean daylightSavingTime(unsigned long _timeStamp);
static unsigned long adjustTimeZone(unsigned long _timeStamp, float _timeZone, byte _DayLightSavingSaving); static unsigned long adjustTimeZone(unsigned long _timeStamp, float _timeZone, byte _DayLightSavingSaving);
private: private:
bool _sendPhase; bool _sendPhase;
unsigned long _sentTime; unsigned long _sentTime;
+7 -7
View File
@@ -9,15 +9,15 @@
#define OPENWEATHER_URL(loc, api) ("https://api.openweathermap.org/data/2.5/weather?q=" + loc + "&appid=" + api + "&units=metric") #define OPENWEATHER_URL(loc, api) ("https://api.openweathermap.org/data/2.5/weather?q=" + loc + "&appid=" + api + "&units=metric")
class OWM{ class OWM {
public: public:
OWM(){}; OWM() {};
OWM(String l,String k) : location(l), key(k){} OWM(String l,String k) : location(l), key(k) {}
StaticJsonDocument<1024> weather; StaticJsonDocument<1024> weather;
bool valid_weather = false; bool valid_weather = false;
bool update(){ bool update() {
Serial.println("OWWM: Updating Data"); Serial.println("OWWM: Updating Data");
String response = httpGETRequest(OPENWEATHER_URL(location,key).c_str()); String response = httpGETRequest(OPENWEATHER_URL(location,key).c_str());
@@ -30,7 +30,7 @@ class OWM{
} }
if(weather["weather"]==NULL ||weather["main"]==NULL || if(weather["weather"]==NULL ||weather["main"]==NULL ||
weather["wind"]==NULL || weather["sys"]==NULL ){ weather["wind"]==NULL || weather["sys"]==NULL ) {
Serial.println("OWWM: Error, missing fields"); Serial.println("OWWM: Error, missing fields");
valid_weather = false; valid_weather = false;
return false; return false;
@@ -59,7 +59,7 @@ private:
} }
const char* root_ca= \ const char* root_ca= \
" -----BEGIN CERTIFICATE-----\n\ " -----BEGIN CERTIFICATE-----\n\
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB\n\ MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB\n\
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n\ iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n\
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n\ cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n\
+207 -208
View File
@@ -2,302 +2,301 @@
/****************************************************************/ /****************************************************************/
bool BME280::Initialize(){ bool BME280::Initialize() {
bool success(true); bool success(true);
success &= ReadChipID(); success &= ReadChipID();
if(success){ if(success) {
success &= ReadTrim(); success &= ReadTrim();
//InitializeFilter(); //If Filter ON //InitializeFilter(); //If Filter ON
WriteSettings(); WriteSettings();
} }
m_initialized = success; m_initialized = success;
return m_initialized; return m_initialized;
} }
/****************************************************************/ /****************************************************************/
bool BME280::ReadChipID(){ bool BME280::ReadChipID() {
uint8_t id[1]; uint8_t id[1];
ReadRegister(ID_ADDR, &id[0], 1); ReadRegister(ID_ADDR, &id[0], 1);
switch(id[0]){ switch(id[0]) {
case ChipModel_BME280: case ChipModel_BME280:
m_chip_model = ChipModel_BME280; m_chip_model = ChipModel_BME280;
break; break;
case ChipModel_BMP280: case ChipModel_BMP280:
m_chip_model = ChipModel_BMP280; m_chip_model = ChipModel_BMP280;
break; break;
default: default:
m_chip_model = ChipModel_UNKNOWN; m_chip_model = ChipModel_UNKNOWN;
return false; return false;
} }
return true; return true;
} }
/****************************************************************/ /****************************************************************/
void BME280::WriteSettings(){ void BME280::WriteSettings() {
// ctrl_hum register. (ctrl_hum[2:0] = Humidity oversampling rate.) // ctrl_hum register. (ctrl_hum[2:0] = Humidity oversampling rate.)
uint8_t ctrlHum = (uint8_t)OSR_X1; uint8_t ctrlHum = (uint8_t)OSR_X1;
// ctrl_meas register. (ctrl_meas[7:5] = temperature oversampling rate, ctrl_meas[4:2] = pressure oversampling rate, ctrl_meas[1:0] = mode.) // ctrl_meas register. (ctrl_meas[7:5] = temperature oversampling rate, ctrl_meas[4:2] = pressure oversampling rate, ctrl_meas[1:0] = mode.)
uint8_t ctrlMeas = ((uint8_t)OSR_X1 << 5) | ((uint8_t)OSR_X1 << 2) | (uint8_t)Mode_Forced; uint8_t ctrlMeas = ((uint8_t)OSR_X1 << 5) | ((uint8_t)OSR_X1 << 2) | (uint8_t)Mode_Forced;
// config register. (config[7:5] = standby time, config[4:2] = filter, ctrl_meas[0] = spi enable.) // config register. (config[7:5] = standby time, config[4:2] = filter, ctrl_meas[0] = spi enable.)
uint8_t config = ((uint8_t)StandbyTime_1000ms << 5) | ((uint8_t)Filter_Off << 2) | 0; uint8_t config = ((uint8_t)StandbyTime_1000ms << 5) | ((uint8_t)Filter_Off << 2) | 0;
WriteRegister(CTRL_HUM_ADDR, ctrlHum); WriteRegister(CTRL_HUM_ADDR, ctrlHum);
WriteRegister(CTRL_MEAS_ADDR, ctrlMeas); WriteRegister(CTRL_MEAS_ADDR, ctrlMeas);
WriteRegister(CONFIG_ADDR, config); WriteRegister(CONFIG_ADDR, config);
} }
/****************************************************************/ /****************************************************************/
bool BME280::begin(){ bool BME280::begin() {
bool success = Initialize(); bool success = Initialize();
success &= m_initialized; success &= m_initialized;
return success; return success;
} }
/****************************************************************/ /****************************************************************/
bool BME280::reset(){ bool BME280::reset() {
WriteRegister(RESET_ADDR, RESET_VALUE); WriteRegister(RESET_ADDR, RESET_VALUE);
delay(2); //max. startup time according to datasheet delay(2); //max. startup time according to datasheet
return(begin()); return(begin());
} }
/****************************************************************/ /****************************************************************/
bool BME280::ReadTrim(){ bool BME280::ReadTrim() {
uint8_t ord(0); uint8_t ord(0);
bool success = true; bool success = true;
// Temp. Dig // Temp. Dig
success &= ReadRegister(TEMP_DIG_ADDR, &m_dig[ord], TEMP_DIG_LENGTH); success &= ReadRegister(TEMP_DIG_ADDR, &m_dig[ord], TEMP_DIG_LENGTH);
ord += TEMP_DIG_LENGTH; ord += TEMP_DIG_LENGTH;
// Pressure Dig // Pressure Dig
success &= ReadRegister(PRESS_DIG_ADDR, &m_dig[ord], PRESS_DIG_LENGTH); success &= ReadRegister(PRESS_DIG_ADDR, &m_dig[ord], PRESS_DIG_LENGTH);
ord += PRESS_DIG_LENGTH; ord += PRESS_DIG_LENGTH;
// Humidity Dig 1 // Humidity Dig 1
success &= ReadRegister(HUM_DIG_ADDR1, &m_dig[ord], HUM_DIG_ADDR1_LENGTH); success &= ReadRegister(HUM_DIG_ADDR1, &m_dig[ord], HUM_DIG_ADDR1_LENGTH);
ord += HUM_DIG_ADDR1_LENGTH; ord += HUM_DIG_ADDR1_LENGTH;
// Humidity Dig 2 // Humidity Dig 2
success &= ReadRegister(HUM_DIG_ADDR2, &m_dig[ord], HUM_DIG_ADDR2_LENGTH); success &= ReadRegister(HUM_DIG_ADDR2, &m_dig[ord], HUM_DIG_ADDR2_LENGTH);
ord += HUM_DIG_ADDR2_LENGTH; ord += HUM_DIG_ADDR2_LENGTH;
#ifdef DEBUG_ON return success && ord == DIG_LENGTH;
Serial.print("Dig: ");
for(int i = 0; i < 32; ++i){
Serial.print(m_dig[i], HEX);
Serial.print(" ");
}
Serial.println();
#endif
return success && ord == DIG_LENGTH;
} }
/****************************************************************/ /****************************************************************/
bool BME280::ReadData(int32_t data[SENSOR_DATA_LENGTH]){ bool BME280::ReadData(int32_t data[SENSOR_DATA_LENGTH]) {
bool success; bool success;
uint8_t buffer[SENSOR_DATA_LENGTH]; uint8_t buffer[SENSOR_DATA_LENGTH];
WriteSettings(); //IF Forced Mode WriteSettings(); //IF Forced Mode
success = ReadRegister(PRESS_ADDR, buffer, SENSOR_DATA_LENGTH); success = ReadRegister(PRESS_ADDR, buffer, SENSOR_DATA_LENGTH);
for(int i = 0; i < SENSOR_DATA_LENGTH; ++i){ for(int i = 0; i < SENSOR_DATA_LENGTH; ++i) {
data[i] = static_cast<int32_t>(buffer[i]); data[i] = static_cast<int32_t>(buffer[i]);
} }
return success; return success;
} }
/****************************************************************/ /****************************************************************/
float BME280::CalculateTemperature(int32_t raw,int32_t& t_fine){ float BME280::CalculateTemperature(int32_t raw,int32_t& t_fine) {
// Code based on calibration algorthim provided by Bosch. // Code based on calibration algorthim provided by Bosch.
int32_t var1, var2, final; int32_t var1, var2, final;
uint16_t dig_T1 = (m_dig[1] << 8) | m_dig[0]; uint16_t dig_T1 = (m_dig[1] << 8) | m_dig[0];
int16_t dig_T2 = (m_dig[3] << 8) | m_dig[2]; int16_t dig_T2 = (m_dig[3] << 8) | m_dig[2];
int16_t dig_T3 = (m_dig[5] << 8) | m_dig[4]; int16_t dig_T3 = (m_dig[5] << 8) | m_dig[4];
var1 = ((((raw >> 3) - ((int32_t)dig_T1 << 1))) * ((int32_t)dig_T2)) >> 11; var1 = ((((raw >> 3) - ((int32_t)dig_T1 << 1))) * ((int32_t)dig_T2)) >> 11;
var2 = (((((raw >> 4) - ((int32_t)dig_T1)) * ((raw >> 4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14; var2 = (((((raw >> 4) - ((int32_t)dig_T1)) * ((raw >> 4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;
t_fine = var1 + var2; t_fine = var1 + var2;
final = (t_fine * 5 + 128) >> 8; final = (t_fine * 5 + 128) >> 8;
return final/100.0; return final/100.0;
} }
/****************************************************************/ /****************************************************************/
float BME280::CalculateHumidity float BME280::CalculateHumidity
( (
int32_t raw, int32_t raw,
int32_t t_fine int32_t t_fine
) )
{ {
// Code based on calibration algorthim provided by Bosch. // Code based on calibration algorthim provided by Bosch.
int32_t var1; int32_t var1;
uint8_t dig_H1 = m_dig[24]; uint8_t dig_H1 = m_dig[24];
int16_t dig_H2 = (m_dig[26] << 8) | m_dig[25]; int16_t dig_H2 = (m_dig[26] << 8) | m_dig[25];
uint8_t dig_H3 = m_dig[27]; uint8_t dig_H3 = m_dig[27];
int16_t dig_H4 = ((int8_t)m_dig[28] * 16) | (0x0F & m_dig[29]); int16_t dig_H4 = ((int8_t)m_dig[28] * 16) | (0x0F & m_dig[29]);
int16_t dig_H5 = ((int8_t)m_dig[30] * 16) | ((m_dig[29] >> 4) & 0x0F); int16_t dig_H5 = ((int8_t)m_dig[30] * 16) | ((m_dig[29] >> 4) & 0x0F);
int8_t dig_H6 = m_dig[31]; int8_t dig_H6 = m_dig[31];
var1 = (t_fine - ((int32_t)76800)); var1 = (t_fine - ((int32_t)76800));
var1 = (((((raw << 14) - (((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * var1)) + var1 = (((((raw << 14) - (((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * var1)) +
((int32_t)16384)) >> 15) * (((((((var1 * ((int32_t)dig_H6)) >> 10) * (((var1 * ((int32_t)16384)) >> 15) * (((((((var1 * ((int32_t)dig_H6)) >> 10) * (((var1 *
((int32_t)dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) * ((int32_t)dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
((int32_t)dig_H2) + 8192) >> 14)); ((int32_t)dig_H2) + 8192) >> 14));
var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4)); var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4));
var1 = (var1 < 0 ? 0 : var1); var1 = (var1 < 0 ? 0 : var1);
var1 = (var1 > 419430400 ? 419430400 : var1); var1 = (var1 > 419430400 ? 419430400 : var1);
return ((uint32_t)(var1 >> 12))/1024.0; return ((uint32_t)(var1 >> 12))/1024.0;
} }
/****************************************************************/ /****************************************************************/
float BME280::CalculatePressure(int32_t raw,int32_t t_fine,PresUnit unit){ float BME280::CalculatePressure(int32_t raw,int32_t t_fine,PresUnit unit) {
// Code based on calibration algorthim provided by Bosch. // Code based on calibration algorthim provided by Bosch.
int64_t var1, var2, pressure; int64_t var1, var2, pressure;
float final; float final;
uint16_t dig_P1 = (m_dig[7] << 8) | m_dig[6]; uint16_t dig_P1 = (m_dig[7] << 8) | m_dig[6];
int16_t dig_P2 = (m_dig[9] << 8) | m_dig[8]; int16_t dig_P2 = (m_dig[9] << 8) | m_dig[8];
int16_t dig_P3 = (m_dig[11] << 8) | m_dig[10]; int16_t dig_P3 = (m_dig[11] << 8) | m_dig[10];
int16_t dig_P4 = (m_dig[13] << 8) | m_dig[12]; int16_t dig_P4 = (m_dig[13] << 8) | m_dig[12];
int16_t dig_P5 = (m_dig[15] << 8) | m_dig[14]; int16_t dig_P5 = (m_dig[15] << 8) | m_dig[14];
int16_t dig_P6 = (m_dig[17] << 8) | m_dig[16]; int16_t dig_P6 = (m_dig[17] << 8) | m_dig[16];
int16_t dig_P7 = (m_dig[19] << 8) | m_dig[18]; int16_t dig_P7 = (m_dig[19] << 8) | m_dig[18];
int16_t dig_P8 = (m_dig[21] << 8) | m_dig[20]; int16_t dig_P8 = (m_dig[21] << 8) | m_dig[20];
int16_t dig_P9 = (m_dig[23] << 8) | m_dig[22]; int16_t dig_P9 = (m_dig[23] << 8) | m_dig[22];
var1 = (int64_t)t_fine - 128000; var1 = (int64_t)t_fine - 128000;
var2 = var1 * var1 * (int64_t)dig_P6; var2 = var1 * var1 * (int64_t)dig_P6;
var2 = var2 + ((var1 * (int64_t)dig_P5) << 17); var2 = var2 + ((var1 * (int64_t)dig_P5) << 17);
var2 = var2 + (((int64_t)dig_P4) << 35); var2 = var2 + (((int64_t)dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12); var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12);
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)dig_P1) >> 33; var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)dig_P1) >> 33;
if (var1 == 0) { return NAN; } // Don't divide by zero. if (var1 == 0) {
pressure = 1048576 - raw; return NAN; // Don't divide by zero.
pressure = (((pressure << 31) - var2) * 3125)/var1; }
var1 = (((int64_t)dig_P9) * (pressure >> 13) * (pressure >> 13)) >> 25; pressure = 1048576 - raw;
var2 = (((int64_t)dig_P8) * pressure) >> 19; pressure = (((pressure << 31) - var2) * 3125)/var1;
pressure = ((pressure + var1 + var2) >> 8) + (((int64_t)dig_P7) << 4); var1 = (((int64_t)dig_P9) * (pressure >> 13) * (pressure >> 13)) >> 25;
var2 = (((int64_t)dig_P8) * pressure) >> 19;
pressure = ((pressure + var1 + var2) >> 8) + (((int64_t)dig_P7) << 4);
final = ((uint32_t)pressure)/256.0; final = ((uint32_t)pressure)/256.0;
// Conversion units courtesy of www.endmemo.com. // Conversion units courtesy of www.endmemo.com.
switch(unit){ switch(unit) {
case PresUnit_hPa: /* hPa */ case PresUnit_hPa: /* hPa */
final /= 100.0; final /= 100.0;
break; break;
case PresUnit_atm: /* atm */ case PresUnit_atm: /* atm */
final /= 101324.99766353; /* final pa * 1 atm/101324.99766353Pa */ final /= 101324.99766353; /* final pa * 1 atm/101324.99766353Pa */
break; break;
case PresUnit_bar: /* bar */ case PresUnit_bar: /* bar */
final /= 100000.0; /* final pa * 1 bar/100kPa */ final /= 100000.0; /* final pa * 1 bar/100kPa */
break; break;
default: /* Pa (case: 0) */ default: /* Pa (case: 0) */
break; break;
} }
return final; return final;
} }
/****************************************************************/ /****************************************************************/
float BME280::temp(){ float BME280::temp() {
if(!m_initialized) return 0; if(!m_initialized) return 0;
int32_t data[8]; int32_t data[8];
int32_t t_fine; int32_t t_fine;
if(!ReadData(data)){ return NAN; } if(!ReadData(data)) {
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4); return NAN;
return CalculateTemperature(rawTemp, t_fine); }
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
return CalculateTemperature(rawTemp, t_fine);
} }
/****************************************************************/ /****************************************************************/
float BME280::pres(PresUnit unit){ float BME280::pres(PresUnit unit) {
if(!m_initialized) return 0; if(!m_initialized) return 0;
int32_t data[8]; int32_t data[8];
int32_t t_fine; int32_t t_fine;
if(!ReadData(data)){ return NAN; } if(!ReadData(data)) {
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4); return NAN;
uint32_t rawPressure = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4); }
CalculateTemperature(rawTemp, t_fine); uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
return CalculatePressure(rawPressure, t_fine); uint32_t rawPressure = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
CalculateTemperature(rawTemp, t_fine);
return CalculatePressure(rawPressure, t_fine);
} }
/****************************************************************/ /****************************************************************/
float BME280::hum(){ float BME280::hum() {
if(!m_initialized) return 0; if(!m_initialized) return 0;
int32_t data[8]; int32_t data[8];
int32_t t_fine; int32_t t_fine;
if(!ReadData(data)){ return NAN; } if(!ReadData(data)) {
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4); return NAN;
uint32_t rawHumidity = (data[6] << 8) | data[7]; }
CalculateTemperature(rawTemp, t_fine); uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
return CalculateHumidity(rawHumidity, t_fine); uint32_t rawHumidity = (data[6] << 8) | data[7];
CalculateTemperature(rawTemp, t_fine);
return CalculateHumidity(rawHumidity, t_fine);
} }
/****************************************************************/ /****************************************************************/
void BME280::read(float& pressure,float& temp,float& humidity,PresUnit presUnit){ void BME280::read(float& pressure,float& temp,float& humidity,PresUnit presUnit) {
if(!m_initialized) return; if(!m_initialized) return;
int32_t data[8]; int32_t data[8];
int32_t t_fine; int32_t t_fine;
if(!ReadData(data)){ if(!ReadData(data)) {
pressure = temp = humidity = NAN; pressure = temp = humidity = NAN;
return; return;
} }
uint32_t rawPressure = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4); uint32_t rawPressure = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4); uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
uint32_t rawHumidity = (data[6] << 8) | data[7]; uint32_t rawHumidity = (data[6] << 8) | data[7];
temp = CalculateTemperature(rawTemp, t_fine); temp = CalculateTemperature(rawTemp, t_fine);
pressure = CalculatePressure(rawPressure, t_fine, presUnit); pressure = CalculatePressure(rawPressure, t_fine, presUnit);
humidity = CalculateHumidity(rawHumidity, t_fine); humidity = CalculateHumidity(rawHumidity, t_fine);
} }
/****************************************************************/ /****************************************************************/
BME280::ChipModel BME280::chipModel(){ BME280::ChipModel BME280::chipModel() {
return m_chip_model; return m_chip_model;
} }
/****************************************************************/ /****************************************************************/
bool BME280::WriteRegister(uint8_t addr, uint8_t data){ bool BME280::WriteRegister(uint8_t addr, uint8_t data) {
i2c->beginTransmission(BME280_ADDRESS); i2c->beginTransmission(BME280_ADDRESS);
i2c->write(addr); i2c->write(addr);
i2c->write(data); i2c->write(data);
i2c->endTransmission(); i2c->endTransmission();
return true; return true;
} }
/****************************************************************/ /****************************************************************/
bool BME280::ReadRegister bool BME280::ReadRegister
( (
uint8_t addr, uint8_t addr,
uint8_t data[], uint8_t data[],
uint8_t length uint8_t length
) )
{ {
uint8_t ord(0); uint8_t ord(0);
i2c->beginTransmission(BME280_ADDRESS); i2c->beginTransmission(BME280_ADDRESS);
i2c->write(addr); i2c->write(addr);
i2c->endTransmission(); i2c->endTransmission();
i2c->requestFrom(static_cast<uint8_t>(BME280_ADDRESS), length); i2c->requestFrom(static_cast<uint8_t>(BME280_ADDRESS), length);
while(i2c->available()) while(i2c->available())
{ {
data[ord++] = i2c->read(); data[ord++] = i2c->read();
} }
return ord == length; return ord == length;
} }
+44 -44
View File
@@ -13,57 +13,57 @@
/// Based on the data sheet provided by Bosch for /// Based on the data sheet provided by Bosch for
/// the Bme280 environmental sensor. /// the Bme280 environmental sensor.
/// ///
class BME280{ class BME280 {
public: public:
enum PresUnit{ enum PresUnit {
PresUnit_Pa, PresUnit_Pa,
PresUnit_hPa, PresUnit_hPa,
PresUnit_atm, PresUnit_atm,
PresUnit_bar, PresUnit_bar,
}; };
enum OSR{ enum OSR {
OSR_Off = 0, OSR_Off = 0,
OSR_X1 = 1, OSR_X1 = 1,
OSR_X2 = 2, OSR_X2 = 2,
OSR_X4 = 3, OSR_X4 = 3,
OSR_X8 = 4, OSR_X8 = 4,
OSR_X16 = 5 OSR_X16 = 5
}; };
enum Mode{ enum Mode {
Mode_Sleep = 0, Mode_Sleep = 0,
Mode_Forced = 1, Mode_Forced = 1,
Mode_Normal = 3 Mode_Normal = 3
}; };
enum StandbyTime{ enum StandbyTime {
StandbyTime_500us = 0, StandbyTime_500us = 0,
StandbyTime_62500us = 1, StandbyTime_62500us = 1,
StandbyTime_125ms = 2, StandbyTime_125ms = 2,
StandbyTime_250ms = 3, StandbyTime_250ms = 3,
StandbyTime_50ms = 4, StandbyTime_50ms = 4,
StandbyTime_1000ms = 5, StandbyTime_1000ms = 5,
StandbyTime_10ms = 6, StandbyTime_10ms = 6,
StandbyTime_20ms = 7 StandbyTime_20ms = 7
}; };
enum Filter{ enum Filter {
Filter_Off = 0, Filter_Off = 0,
Filter_2 = 1, Filter_2 = 1,
Filter_4 = 2, Filter_4 = 2,
Filter_8 = 3, Filter_8 = 3,
Filter_16 = 4 Filter_16 = 4
}; };
enum ChipModel{ enum ChipModel {
ChipModel_UNKNOWN = 0, ChipModel_UNKNOWN = 0,
ChipModel_BMP280 = 0x58, ChipModel_BMP280 = 0x58,
ChipModel_BME280 = 0x60 ChipModel_BME280 = 0x60
}; };
BME280(TwoWire* i2c): m_initialized(false), i2c(i2c){} BME280(TwoWire* i2c): m_initialized(false), i2c(i2c) {}
ChipModel chipModel(); ChipModel chipModel();
bool begin(); bool begin();
+84 -81
View File
@@ -2,136 +2,139 @@
/****************************************************************/ /****************************************************************/
bool LTR390::Initialize(){ bool LTR390::Initialize() {
bool success(true); bool success(true);
success &= ReadChipID(); success &= ReadChipID();
if(success){ if(success) {
WriteSettings(); WriteSettings();
} }
m_initialized = success; m_initialized = success;
return m_initialized; return m_initialized;
} }
/****************************************************************/ /****************************************************************/
bool LTR390::ReadChipID(){ bool LTR390::ReadChipID() {
uint8_t id; uint8_t id;
ReadRegister(ID_ADDR, &id, 1); ReadRegister(ID_ADDR, &id, 1);
switch(id){ switch(id) {
case ChipModel_LTR390_REV0: case ChipModel_LTR390_REV0:
m_chip_model = ChipModel_LTR390_REV0; m_chip_model = ChipModel_LTR390_REV0;
break; break;
case ChipModel_LTR390_REV1: case ChipModel_LTR390_REV1:
m_chip_model = ChipModel_LTR390_REV1; m_chip_model = ChipModel_LTR390_REV1;
break; break;
case ChipModel_LTR390_REV2: case ChipModel_LTR390_REV2:
m_chip_model = ChipModel_LTR390_REV2; m_chip_model = ChipModel_LTR390_REV2;
break; break;
case ChipModel_LTR390_REV3: case ChipModel_LTR390_REV3:
m_chip_model = ChipModel_LTR390_REV3; m_chip_model = ChipModel_LTR390_REV3;
break; break;
default: default:
m_chip_model = ChipModel_UNKNOWN; m_chip_model = ChipModel_UNKNOWN;
return false; return false;
} }
return true; return true;
} }
/****************************************************************/ /****************************************************************/
void LTR390::WriteSettings(){ void LTR390::WriteSettings() {
uint8_t ctrlMeas = LTR390_RESOLUTION_16BIT | LTR390_RATE_1000; WriteRegister(MAIN_CTRL, LTR390_ON | LTR390_MODE_UVS);
uint8_t ctrlGain = LTR390_GAIN_3; WriteRegister(MEAS_RATE, LTR390_RESOLUTION_16BIT | LTR390_RATE_1000);
uint8_t ctrlMode = LTR390_ON | LTR390_MODE_UVS; WriteRegister(GAIN, LTR390_GAIN_18);
WriteRegister(MEAS_RATE, ctrlMeas); // WriteRegister(THRESH_LOW, 100);
WriteRegister(GAIN, ctrlGain); // WriteRegister(THRESH_UP, 1000);
WriteRegister(MAIN_CTRL, ctrlMode); // WriteRegister(INT_CFG, 0x30 | 0x04);
} }
/****************************************************************/ /****************************************************************/
bool LTR390::begin(){ bool LTR390::begin() {
bool success = Initialize(); bool success = Initialize();
success &= m_initialized; success &= m_initialized;
return success; return success;
} }
/****************************************************************/ /****************************************************************/
bool LTR390::reset(){ bool LTR390::reset() {
WriteRegister(RESET_ADDR, RESET_VALUE); WriteRegister(RESET_ADDR, RESET_VALUE);
delay(10); //max. startup time according to datasheet delay(10); //max. startup time according to datasheet
return(begin()); return(begin());
} }
/****************************************************************/ /****************************************************************/
bool LTR390::ReadData(int32_t data[SENSOR_DATA_LENGTH], uint32_t addr){ bool LTR390::ReadData(int32_t data[SENSOR_DATA_LENGTH], uint32_t addr) {
bool success; bool success;
uint8_t buffer[SENSOR_DATA_LENGTH]; uint8_t buffer[SENSOR_DATA_LENGTH];
// WriteSettings(); // WriteSettings();
success = ReadRegister(addr, buffer, SENSOR_DATA_LENGTH); success = ReadRegister(addr, buffer, SENSOR_DATA_LENGTH);
for(int i = 0; i < SENSOR_DATA_LENGTH; ++i){ for(int i = 0; i < SENSOR_DATA_LENGTH; ++i) {
data[i] = static_cast<int32_t>(buffer[i]); data[i] = static_cast<int32_t>(buffer[i]);
} }
return success; return success;
} }
/****************************************************************/ /****************************************************************/
uint32_t LTR390::uv(){ uint32_t LTR390::uv() {
if(!m_initialized) return 0; if(!m_initialized) return 0;
int32_t data[SENSOR_DATA_LENGTH];
if(!ReadData(data, UVSDATA)){ return 0; } int32_t data[SENSOR_DATA_LENGTH];
uint32_t rawUV = (data[2] << 16) | (data[1] << 8) | (data[0]); if(!ReadData(data, UVSDATA)) {
return rawUV; return 0;
}
uint32_t rawUV = (data[2] << 16) | (data[1] << 8) | (data[0]);
return rawUV;
} }
void LTR390::read(uint32_t& uvs, uint32_t& uvi){ void LTR390::read(uint32_t& uvs, uint32_t& uvi) {
if(!m_initialized) return; if(!m_initialized) return;
uvs = uv(); uvs = uv();
uvi = (uvs/ (3*0.25))*3; uvi = (uvs/ 2300)*2;
} }
/****************************************************************/ /****************************************************************/
LTR390::ChipModel LTR390::chipModel(){ LTR390::ChipModel LTR390::chipModel() {
return m_chip_model; return m_chip_model;
} }
/****************************************************************/ /****************************************************************/
bool LTR390::WriteRegister(uint8_t addr, uint8_t data){ bool LTR390::WriteRegister(uint8_t addr, uint8_t data) {
i2c->beginTransmission(LTR390_ADDRESS); i2c->beginTransmission(LTR390_ADDRESS);
i2c->write(addr); i2c->write(addr);
i2c->write(data); i2c->write(data);
i2c->endTransmission(); i2c->endTransmission();
return true; return true;
} }
/****************************************************************/ /****************************************************************/
bool LTR390::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length){ bool LTR390::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length) {
uint8_t ord(0); uint8_t ord(0);
i2c->beginTransmission(LTR390_ADDRESS); i2c->beginTransmission(LTR390_ADDRESS);
i2c->write(addr); i2c->write(addr);
i2c->endTransmission(); i2c->endTransmission();
i2c->requestFrom(static_cast<uint8_t>(LTR390_ADDRESS), length); i2c->requestFrom(static_cast<uint8_t>(LTR390_ADDRESS), length);
while(i2c->available()){ while(i2c->available()) {
data[ord++] = i2c->read(); data[ord++] = i2c->read();
} }
return ord == length; return ord == length;
} }
+5 -5
View File
@@ -11,8 +11,8 @@
/// ///
/// Based on the data sheet provided /// Based on the data sheet provided
/// ///
class LTR390{ class LTR390 {
public: public:
typedef enum { typedef enum {
LTR390_ON = 0x2, LTR390_ON = 0x2,
@@ -51,15 +51,15 @@ class LTR390{
LTR390_RATE_2000 = 0x6, LTR390_RATE_2000 = 0x6,
} ltr390_rate_t; } ltr390_rate_t;
enum ChipModel{ enum ChipModel {
ChipModel_UNKNOWN = 0, ChipModel_UNKNOWN = 0,
ChipModel_LTR390_REV0 = 0xB0, ChipModel_LTR390_REV0 = 0xB0,
ChipModel_LTR390_REV1 = 0xB1, ChipModel_LTR390_REV1 = 0xB1,
ChipModel_LTR390_REV2 = 0xB2, ChipModel_LTR390_REV2 = 0xB2,
ChipModel_LTR390_REV3 = 0xB3, ChipModel_LTR390_REV3 = 0xB3,
}; };
LTR390(TwoWire* i2c): m_initialized(false),i2c(i2c){} LTR390(TwoWire* i2c): m_initialized(false),i2c(i2c) {}
ChipModel chipModel(); ChipModel chipModel();
+76 -75
View File
@@ -7,128 +7,129 @@
#define SENSOR_DATA_LENGTH 32 #define SENSOR_DATA_LENGTH 32
/****************************************************************/ /****************************************************************/
bool PMSA003::Initialize(){ bool PMSA003::Initialize() {
bool success(true); bool success(true);
success &= ReadChipID(); success &= ReadChipID();
if(success) success = WriteSettings(); if(success) success = WriteSettings();
m_initialized = success; m_initialized = success;
return m_initialized; return m_initialized;
} }
/****************************************************************/ /****************************************************************/
bool PMSA003::ReadChipID(){ bool PMSA003::ReadChipID() {
uint8_t id = 0; uint8_t id = 0;
ReadRegister(REG_VERSION, &id, 1); ReadRegister(REG_VERSION, &id, 1);
Serial.print("PMSSA DEV: ");Serial.println(id); Serial.print("PMSSA DEV: ");
// switch(id){ Serial.println(id);
// case ChipModel_PMSA003_REV0: // switch(id){
// m_chip_model = ChipModel_PMSA003_REV0; // case ChipModel_PMSA003_REV0:
// break; // m_chip_model = ChipModel_PMSA003_REV0;
// default: // break;
// m_chip_model = ChipModel_UNKNOWN; // default:
// return false; // m_chip_model = ChipModel_UNKNOWN;
// } // return false;
// }
return true; return true;
} }
/****************************************************************/ /****************************************************************/
bool PMSA003::WriteSettings(){ bool PMSA003::WriteSettings() {
return true; //No settings return true; //No settings
} }
/****************************************************************/ /****************************************************************/
bool PMSA003::begin(){ bool PMSA003::begin() {
bool success = Initialize(); bool success = Initialize();
success &= m_initialized; success &= m_initialized;
return success; return success;
} }
/****************************************************************/ /****************************************************************/
bool PMSA003::reset(){ bool PMSA003::reset() {
return true; //Cannot be reset return true; //Cannot be reset
} }
/****************************************************************/ /****************************************************************/
bool PMSA003::ReadData(uint8_t data[SENSOR_DATA_LENGTH]){ bool PMSA003::ReadData(uint8_t data[SENSOR_DATA_LENGTH]) {
ReadRegister(REG_Char1,data,SENSOR_DATA_LENGTH); ReadRegister(REG_Char1,data,SENSOR_DATA_LENGTH);
if (data[0] != 0x42 || data[1] != 0x4d) return false; if (data[0] != 0x42 || data[1] != 0x4d) return false;
uint16_t sum = 0; uint16_t sum = 0;
for (uint8_t i = 0; i < 30; i++) sum += data[i]; for (uint8_t i = 0; i < 30; i++) sum += data[i];
uint16_t checksum = data[30]<<8 | data[31]; uint16_t checksum = data[30]<<8 | data[31];
if (sum != checksum) return false; if (sum != checksum) return false;
return true; return true;
} }
/****************************************************************/ /****************************************************************/
void PMSA003::read(PM25_AQI_Data& data){ void PMSA003::read(PM25_AQI_Data& data) {
if(!m_initialized) return; if(!m_initialized) return;
uint8_t rd[SENSOR_DATA_LENGTH]; uint8_t rd[SENSOR_DATA_LENGTH];
if(!ReadData(rd)) return; if(!ReadData(rd)) return;
uint16_t md[16] = {0}; uint16_t md[16] = {0};
for (uint8_t i = 0; i < 15; i++) { for (uint8_t i = 0; i < 15; i++) {
md[i] = rd[i * 2] << 8; md[i] = rd[i * 2] << 8;
md[i] |= rd[i * 2 + 1]; md[i] |= rd[i * 2 + 1];
} }
data.pm10_standard = md[2]; data.pm10_standard = md[2];
data.pm25_standard = md[3]; data.pm25_standard = md[3];
data.pm100_standard = md[4]; data.pm100_standard = md[4];
data.pm10_env = md[5]; data.pm10_env = md[5];
data.pm25_env = md[6]; data.pm25_env = md[6];
data.pm100_env = md[7]; data.pm100_env = md[7];
data.particles_03um = md[8]; data.particles_03um = md[8];
data.particles_05um = md[9]; data.particles_05um = md[9];
data.particles_10um = md[10]; data.particles_10um = md[10];
data.particles_25um = md[11]; data.particles_25um = md[11];
data.particles_50um = md[12]; data.particles_50um = md[12];
data.particles_100um = md[13]; data.particles_100um = md[13];
} }
/****************************************************************/ /****************************************************************/
PMSA003::ChipModel PMSA003::chipModel(){ PMSA003::ChipModel PMSA003::chipModel() {
return m_chip_model; return m_chip_model;
} }
/****************************************************************/ /****************************************************************/
bool PMSA003::WriteRegister(uint16_t addr, uint8_t data){ bool PMSA003::WriteRegister(uint16_t addr, uint8_t data) {
i2c->beginTransmission(PMSA003_ADDRESS); i2c->beginTransmission(PMSA003_ADDRESS);
i2c->write(highByte(addr)); i2c->write(highByte(addr));
i2c->write(lowByte(addr)); i2c->write(lowByte(addr));
i2c->write(data); i2c->write(data);
i2c->endTransmission(); i2c->endTransmission();
return true; return true;
} }
/****************************************************************/ /****************************************************************/
bool PMSA003::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length){ bool PMSA003::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length) {
uint8_t ord(0); uint8_t ord(0);
i2c->beginTransmission(PMSA003_ADDRESS); i2c->beginTransmission(PMSA003_ADDRESS);
i2c->write(addr); i2c->write(addr);
i2c->endTransmission(); i2c->endTransmission();
i2c->requestFrom(static_cast<uint8_t>(PMSA003_ADDRESS), length); i2c->requestFrom(static_cast<uint8_t>(PMSA003_ADDRESS), length);
while(i2c->available()){ while(i2c->available()) {
data[ord++] = i2c->read(); data[ord++] = i2c->read();
} }
return ord == length; return ord == length;
} }
+17 -17
View File
@@ -9,18 +9,18 @@
typedef struct PMSAQIdata { typedef struct PMSAQIdata {
uint16_t pm10_standard, ///< Standard PM1.0 uint16_t pm10_standard, ///< Standard PM1.0
pm25_standard, ///< Standard PM2.5 pm25_standard, ///< Standard PM2.5
pm100_standard; ///< Standard PM10.0 pm100_standard; ///< Standard PM10.0
uint16_t pm10_env, ///< Environmental PM1.0 uint16_t pm10_env, ///< Environmental PM1.0
pm25_env, ///< Environmental PM2.5 pm25_env, ///< Environmental PM2.5
pm100_env; ///< Environmental PM10.0 pm100_env; ///< Environmental PM10.0
uint16_t particles_03um, ///< 0.3um Particle Count uint16_t particles_03um, ///< 0.3um Particle Count
particles_05um, ///< 0.5um Particle Count particles_05um, ///< 0.5um Particle Count
particles_10um, ///< 1.0um Particle Count particles_10um, ///< 1.0um Particle Count
particles_25um, ///< 2.5um Particle Count particles_25um, ///< 2.5um Particle Count
particles_50um, ///< 5.0um Particle Count particles_50um, ///< 5.0um Particle Count
particles_100um; ///< 10.0um Particle Count particles_100um; ///< 10.0um Particle Count
} PM25_AQI_Data; } PM25_AQI_Data;
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
@@ -28,16 +28,16 @@ typedef struct PMSAQIdata {
/// ///
/// Based on the data sheet provided /// Based on the data sheet provided
/// ///
class PMSA003{ class PMSA003 {
public: public:
enum ChipModel{ enum ChipModel {
ChipModel_UNKNOWN = 0, ChipModel_UNKNOWN = 0,
ChipModel_PMSA003_REV0 = 0x10 ChipModel_PMSA003_REV0 = 0x10
}; };
PMSA003(TwoWire* i2c): m_initialized(false),i2c(i2c){} PMSA003(TwoWire* i2c): m_initialized(false),i2c(i2c) {}
ChipModel chipModel(); ChipModel chipModel();
+76 -76
View File
@@ -1,40 +1,40 @@
#include "sgp40.h" #include "sgp40.h"
#include <Arduino.h>
#define SENSOR_DATA_LENGTH 3 #define SENSOR_DATA_LENGTH 3
/****************************************************************/ /****************************************************************/
bool SGP40::Initialize(){ bool SGP40::Initialize() {
bool success(true); bool success(true);
success &= ReadChipID(); success &= ReadChipID();
VocAlgorithm_init(&vocAlgorithmParameters); VocAlgorithm_init(&vocAlgorithmParameters);
if(success) success = WriteSettings(); if(success) success = WriteSettings();
m_initialized = success;
m_initialized = success; return m_initialized;
return m_initialized;
} }
/****************************************************************/ /****************************************************************/
bool SGP40::ReadChipID(){ bool SGP40::ReadChipID() {
uint8_t id = 0; uint8_t id = 0;
//ReadRegister(ID_ADDR, &id, 1); //ReadRegister(ID_ADDR, &id, 1);
switch(id){ switch(id) {
default: default:
m_chip_model = ChipModel_UNKNOWN; m_chip_model = ChipModel_UNKNOWN;
return false; //return false;
} }
return true; return true;
} }
/****************************************************************/ /****************************************************************/
bool SGP40::WriteSettings(){ bool SGP40::WriteSettings() {
uint8_t data[3]; uint8_t data[3];
uint8_t ord(0); uint8_t ord(0);
@@ -47,7 +47,7 @@ bool SGP40::WriteSettings(){
i2c->requestFrom(static_cast<uint8_t>(SGP40_ADDRESS), uint8_t(3)); i2c->requestFrom(static_cast<uint8_t>(SGP40_ADDRESS), uint8_t(3));
while(i2c->available()){ while(i2c->available()) {
data[ord++] = i2c->read(); data[ord++] = i2c->read();
} }
if(ord != 3) return false; if(ord != 3) return false;
@@ -58,21 +58,21 @@ bool SGP40::WriteSettings(){
/****************************************************************/ /****************************************************************/
bool SGP40::begin(){ bool SGP40::begin() {
bool success = Initialize(); bool success = Initialize();
success &= m_initialized; success &= m_initialized;
return success; return success;
} }
/****************************************************************/ /****************************************************************/
bool SGP40::reset(){ bool SGP40::reset() {
WriteRegister(RESET_ADDR, 0x02); WriteRegister(RESET_ADDR, 0x02);
delay(10); //max. startup time according to datasheet delay(10); //max. startup time according to datasheet
return(begin()); return(begin());
} }
/****************************************************************/ /****************************************************************/
bool SGP40::ReadData(uint8_t data[SENSOR_DATA_LENGTH], float RH, float T){ bool SGP40::ReadData(uint8_t data[SENSOR_DATA_LENGTH], float RH, float T) {
bool success; bool success;
uint8_t ord(0); uint8_t ord(0);
@@ -100,7 +100,7 @@ bool SGP40::ReadData(uint8_t data[SENSOR_DATA_LENGTH], float RH, float T){
i2c->requestFrom(SGP40_ADDRESS, SENSOR_DATA_LENGTH); i2c->requestFrom(SGP40_ADDRESS, SENSOR_DATA_LENGTH);
while(i2c->available()){ while(i2c->available()) {
data[ord++] = i2c->read(); data[ord++] = i2c->read();
} }
@@ -109,73 +109,73 @@ bool SGP40::ReadData(uint8_t data[SENSOR_DATA_LENGTH], float RH, float T){
/****************************************************************/ /****************************************************************/
int32_t SGP40::voc(float RH, float T){ int32_t SGP40::voc(float RH, float T) {
if(!m_initialized) return 0; if(!m_initialized) return 0;
uint8_t data[SENSOR_DATA_LENGTH]; uint8_t data[SENSOR_DATA_LENGTH];
ReadData(data, RH, T);
uint16_t results = (data[0]<<8) | data[1];
int32_t voci = 0;
VocAlgorithm_process(&vocAlgorithmParameters, results, &voci);
return voci; ReadData(data, RH, T);
uint16_t results = (data[0]<<8) | data[1];
int32_t voci = 0;
VocAlgorithm_process(&vocAlgorithmParameters, results, &voci);
return voci;
} }
void SGP40::read(int32_t& voc, float RH, float T){ void SGP40::read(int32_t& voc, float RH, float T) {
if(!m_initialized) return; if(!m_initialized) return;
uint8_t data[SENSOR_DATA_LENGTH]; uint8_t data[SENSOR_DATA_LENGTH];
ReadData(data, RH, T); ReadData(data, RH, T);
uint16_t results = (data[0]<<8) | data[1]; uint16_t results = (data[0]<<8) | data[1];
VocAlgorithm_process(&vocAlgorithmParameters, results, &voc); VocAlgorithm_process(&vocAlgorithmParameters, results, &voc);
return;
} }
/****************************************************************/ /****************************************************************/
SGP40::ChipModel SGP40::chipModel(){ SGP40::ChipModel SGP40::chipModel() {
return m_chip_model; return m_chip_model;
} }
/****************************************************************/ /****************************************************************/
bool SGP40::WriteRegister(uint16_t addr, uint8_t data){ bool SGP40::WriteRegister(uint16_t addr, uint8_t data) {
i2c->beginTransmission(SGP40_ADDRESS); i2c->beginTransmission(SGP40_ADDRESS);
i2c->write(highByte(addr)); i2c->write(highByte(addr));
i2c->write(lowByte(addr)); i2c->write(lowByte(addr));
i2c->write(data); i2c->write(data);
i2c->endTransmission(); i2c->endTransmission();
return true; return true;
} }
/****************************************************************/ /****************************************************************/
bool SGP40::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length){ bool SGP40::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length) {
uint8_t ord(0); uint8_t ord(0);
i2c->beginTransmission(SGP40_ADDRESS); i2c->beginTransmission(SGP40_ADDRESS);
i2c->write(addr); i2c->write(addr);
i2c->endTransmission(); i2c->endTransmission();
i2c->requestFrom(static_cast<uint8_t>(SGP40_ADDRESS), length); i2c->requestFrom(static_cast<uint8_t>(SGP40_ADDRESS), length);
while(i2c->available()){ while(i2c->available()) {
data[ord++] = i2c->read(); data[ord++] = i2c->read();
} }
return ord == length; return ord == length;
} }
uint8_t SGP40::CRC8(uint16_t data){ uint8_t SGP40::CRC8(uint16_t data) {
uint8_t crc = 0xFF; uint8_t crc = 0xFF;
crc ^= (data >> 8); crc ^= (data >> 8);
for (uint8_t i = 0 ; i < 8 ; i++){ for (uint8_t i = 0 ; i < 8 ; i++) {
if ((crc & 0x80) != 0) crc = (uint8_t)((crc << 1) ^ 0x31); if ((crc & 0x80) != 0) crc = (uint8_t)((crc << 1) ^ 0x31);
else crc <<= 1; else crc <<= 1;
} }
crc ^= (uint8_t)data; crc ^= (uint8_t)data;
for (uint8_t i = 0 ; i < 8 ; i++){ for (uint8_t i = 0 ; i < 8 ; i++) {
if ((crc & 0x80) != 0) crc = (uint8_t)((crc << 1) ^ 0x31); if ((crc & 0x80) != 0) crc = (uint8_t)((crc << 1) ^ 0x31);
else crc <<= 1; else crc <<= 1;
} }
return crc; return crc;
} }
+5 -6
View File
@@ -1,7 +1,6 @@
#ifndef TG_SGP40_H #ifndef TG_SGP40_H
#define TG_SGP40_H #define TG_SGP40_H
#include <Arduino.h>
#include <Wire.h> #include <Wire.h>
#include "../voc.h" #include "../voc.h"
@@ -13,15 +12,15 @@
/// ///
/// Based on the data sheet provided /// Based on the data sheet provided
/// ///
class SGP40{ class SGP40 {
public: public:
enum ChipModel{ enum ChipModel {
ChipModel_UNKNOWN = 0 ChipModel_UNKNOWN = 0
}; };
SGP40(TwoWire* i2c): m_initialized(false),i2c(i2c){} SGP40(TwoWire* i2c): m_initialized(false),i2c(i2c) {}
ChipModel chipModel(); ChipModel chipModel();
+134 -137
View File
@@ -1,16 +1,17 @@
#include "tsl25911.h" #include "tsl25911.h"
#include <Arduino.h>
#define SENSOR_DATA_LENGTH 4 #define SENSOR_DATA_LENGTH 4
#define ENABLE_POWEROFF (0x00) ///< Flag for ENABLE register to disable #define ENABLE_POWEROFF (0x00) ///< Flag for ENABLE register to disable
#define ENABLE_POWERON (0x01) ///< Flag for ENABLE register to enable #define ENABLE_POWERON (0x01) ///< Flag for ENABLE register to enable
#define ENABLE_AEN (0x02) ///< ALS Enable. This field activates ALS function. Writing a one #define ENABLE_AEN (0x02) ///< ALS Enable. This field activates ALS function. Writing a one
///< activates the ALS. Writing a zero disables the ALS. ///< activates the ALS. Writing a zero disables the ALS.
#define ENABLE_AIEN (0x10) ///< ALS Interrupt Enable. When asserted permits ALS interrupts to be #define ENABLE_AIEN (0x10) ///< ALS Interrupt Enable. When asserted permits ALS interrupts to be
///< generated, subject to the persist filter. ///< generated, subject to the persist filter.
#define ENABLE_NPIEN (0x80) ///< No Persist Interrupt Enable. When asserted NP Threshold conditions #define ENABLE_NPIEN (0x80) ///< No Persist Interrupt Enable. When asserted NP Threshold conditions
///< will generate an interrupt, bypassing the persist filter ///< will generate an interrupt, bypassing the persist filter
#define LUX_DF (408.0F) ///< Lux cooefficient #define LUX_DF (408.0F) ///< Lux cooefficient
#define LUX_COEFB (1.64F) ///< CH0 coefficient #define LUX_COEFB (1.64F) ///< CH0 coefficient
@@ -20,69 +21,66 @@
/****************************************************************/ /****************************************************************/
bool TSL25911::Initialize(){ bool TSL25911::Initialize() {
bool success(true); bool success(true);
success &= ReadChipID(); success &= ReadChipID();
if(success) WriteSettings(); if(success) WriteSettings();
m_initialized = success; m_initialized = success;
return m_initialized; return m_initialized;
} }
/****************************************************************/ /****************************************************************/
bool TSL25911::ReadChipID(){ bool TSL25911::ReadChipID() {
uint8_t id; uint8_t id;
ReadRegister(ID_ADDR, &id, 1); ReadRegister(ID_ADDR, &id, 1);
switch(id){ switch(id) {
case ChipModel_TSL25911_REV0: case ChipModel_TSL25911_REV0:
m_chip_model = ChipModel_TSL25911_REV0; m_chip_model = ChipModel_TSL25911_REV0;
default: break;
m_chip_model = ChipModel_UNKNOWN; default:
return false; m_chip_model = ChipModel_UNKNOWN;
} return false;
return true; }
return true;
} }
/****************************************************************/ /****************************************************************/
void TSL25911::WriteSettings(){ void TSL25911::WriteSettings() {
WriteRegister(REG_ENABLE, ENABLE_POWERON | ENABLE_AEN); WriteRegister(REG_ENABLE, ENABLE_POWERON | ENABLE_AEN);
WriteRegister(REG_CTRL, integration | gain); WriteRegister(REG_CTRL, integration | gain);
WriteRegister(REG_ENABLE,ENABLE_POWEROFF); WriteRegister(REG_ENABLE,ENABLE_POWEROFF);
} }
/****************************************************************/ /****************************************************************/
bool TSL25911::begin(){ bool TSL25911::begin() {
bool success = Initialize(); bool success = Initialize();
success &= m_initialized; success &= m_initialized;
return success; return success;
} }
/****************************************************************/ /****************************************************************/
bool TSL25911::reset(){ bool TSL25911::reset() {
//Write RST REG ? //Write RST REG ?
delay(10); //max. startup time according to datasheet delay(10); //max. startup time according to datasheet
return(begin()); return(begin());
} }
/****************************************************************/ /****************************************************************/
bool TSL25911::ReadData(uint32_t data[SENSOR_DATA_LENGTH]){ bool TSL25911::ReadData(uint32_t* dataf) {
bool success; uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(dataf));
success &= WriteRegister(REG_ENABLE, ENABLE_POWERON | ENABLE_AEN); bool success = WriteRegister(REG_ENABLE, ENABLE_POWERON | ENABLE_AEN);
delay((uint32_t)atime());
for (uint8_t d = 0; d <= integration; d++) // Wait x ms for ADC to complete success &= ReadRegister(CHAN0_LOW,&data[0],2);
delay(120); success &= ReadRegister(CHAN1_LOW,&data[2],2);
success &= ReadRegister(CHAN0_LOW,static_cast<uint8_t*>(static_cast<void*>(&data[0])),2);
success &= ReadRegister(CHAN1_LOW,static_cast<uint8_t*>(static_cast<void*>(&data[2])),2);
success &= WriteRegister(REG_ENABLE,ENABLE_POWEROFF); success &= WriteRegister(REG_ENABLE,ENABLE_POWEROFF);
@@ -94,136 +92,135 @@ bool TSL25911::ReadData(uint32_t data[SENSOR_DATA_LENGTH]){
float ComputeLux(uint16_t ch0, uint16_t ch1, float atime, float again) { float ComputeLux(uint16_t ch0, uint16_t ch1, float atime, float again) {
float cpl, lux1, lux2, lux; float cpl, lux1, lux2, lux;
if ((ch0 == 0xFFFF) | (ch1 == 0xFFFF)) return -1; if ((ch0 == 0xFFFF) | (ch1 == 0xFFFF)) return -1;
cpl = (atime * again) / LUX_DF; cpl = (atime * again) / LUX_DF;
lux = (((float)ch0 - (float)ch1)) * (1.0F - ((float)ch1 / (float)ch0)) / cpl; lux = (((float)ch0 - (float)ch1)) * (1.0F - ((float)ch1 / (float)ch0)) / cpl;
return lux; return lux;
} }
uint16_t TSL25911::lumV(){ uint16_t TSL25911::lumV() {
if(!m_initialized) return 0; if(!m_initialized) return 0;
uint32_t data; uint32_t data;
if(ReadData(&data)) if(ReadData(&data))
return ((data & 0xFFFF) - (data >> 16)); return ((data & 0xFFFF) - (data >> 16));
return 0; return 0;
} }
uint16_t TSL25911::lumIR(){ uint16_t TSL25911::lumIR() {
if(!m_initialized) return 0; if(!m_initialized) return 0;
uint32_t data; uint32_t data;
if(ReadData(&data)) if(ReadData(&data))
return (data >> 16); return (data >> 16);
return 0; return 0;
} }
uint16_t TSL25911::lumF(){ uint16_t TSL25911::lumF() {
if(!m_initialized) return 0; if(!m_initialized) return 0;
uint32_t data; uint32_t data;
if(ReadData(&data)) if(ReadData(&data))
return (data & 0xFFFF); return (data & 0xFFFF);
return 0; return 0;
} }
float TSL25911::lumLux(){ float TSL25911::lumLux() {
if(!m_initialized) return 0; if(!m_initialized) return 0;
uint32_t data; uint32_t data;
if(ReadData(&data)){ if(ReadData(&data)) {
return ComputeLux(data&0xFFFF, data>>16,again(),atime()); return ComputeLux(data&0xFFFF, data>>16,again(),atime());
} }
return 0; return 0;
} }
void TSL25911::read(uint16_t& v, uint16_t& ir, uint16_t& f, float& lux){ void TSL25911::read(uint16_t& v, uint16_t& ir, uint16_t& f, float& lux) {
if(!m_initialized) return; if(!m_initialized) return;
uint32_t data; uint32_t data;
if(ReadData(&data)){ if(!ReadData(&data)) return;
v = ((data & 0xFFFF) - (data >> 16)); v = ((data & 0xFFFF) - (data >> 16));
ir = (data >> 16); ir = (data >> 16);
f = (data & 0xFFFF); f = (data & 0xFFFF);
lux = ComputeLux(data&0xFFFF,data>>16,again(),atime()); lux = ComputeLux(data&0xFFFF,data>>16,again(),atime());
}
} }
/****************************************************************/ /****************************************************************/
TSL25911::ChipModel TSL25911::chipModel(){ TSL25911::ChipModel TSL25911::chipModel() {
return m_chip_model; return m_chip_model;
} }
/****************************************************************/ /****************************************************************/
bool TSL25911::WriteRegister(uint8_t addr, uint8_t data){ bool TSL25911::WriteRegister(uint8_t addr, uint8_t data) {
i2c->beginTransmission(TSL25911_ADDRESS); i2c->beginTransmission(TSL25911_ADDRESS);
i2c->write(addr); i2c->write(addr);
i2c->write(data); i2c->write(data);
i2c->endTransmission(); i2c->endTransmission();
return true; return true;
} }
/****************************************************************/ /****************************************************************/
bool TSL25911::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length){ bool TSL25911::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length) {
uint8_t ord(0); uint8_t ord(0);
i2c->beginTransmission(TSL25911_ADDRESS); i2c->beginTransmission(TSL25911_ADDRESS);
i2c->write(addr); i2c->write(addr);
i2c->endTransmission(); i2c->endTransmission();
i2c->requestFrom(static_cast<uint8_t>(TSL25911_ADDRESS), length); i2c->requestFrom(static_cast<uint8_t>(TSL25911_ADDRESS), length);
while(i2c->available()){ while(i2c->available()) {
data[ord++] = i2c->read(); data[ord++] = i2c->read();
} }
return ord == length; return ord == length;
} }
float TSL25911::again(){ float TSL25911::again() {
switch (gain) { switch (gain) {
case TSL2591_GAIN_LOW: case TSL2591_GAIN_LOW:
return 1.0F; return 1.0F;
break; break;
case TSL2591_GAIN_MED: case TSL2591_GAIN_MED:
return 25.0F; return 25.0F;
break; break;
case TSL2591_GAIN_HIGH: case TSL2591_GAIN_HIGH:
return 428.0F; return 428.0F;
break; break;
case TSL2591_GAIN_MAX: case TSL2591_GAIN_MAX:
return 9876.0F; return 9876.0F;
break; break;
default: default:
return 1.0F; return 1.0F;
break; break;
} }
} }
float TSL25911::atime(){ float TSL25911::atime() {
switch (integration) { switch (integration) {
case TSL2591_INTEGRATIONTIME_100MS: case TSL2591_INTEGRATIONTIME_100MS:
return 100.0F; return 100.0F;
break; break;
case TSL2591_INTEGRATIONTIME_200MS: case TSL2591_INTEGRATIONTIME_200MS:
return 200.0F; return 200.0F;
break; break;
case TSL2591_INTEGRATIONTIME_300MS: case TSL2591_INTEGRATIONTIME_300MS:
return 300.0F; return 300.0F;
break; break;
case TSL2591_INTEGRATIONTIME_400MS: case TSL2591_INTEGRATIONTIME_400MS:
return 400.0F; return 400.0F;
break; break;
case TSL2591_INTEGRATIONTIME_500MS: case TSL2591_INTEGRATIONTIME_500MS:
return 500.0F; return 500.0F;
break; break;
case TSL2591_INTEGRATIONTIME_600MS: case TSL2591_INTEGRATIONTIME_600MS:
return 600.0F; return 600.0F;
break; break;
default: // 100ms default: // 100ms
return 100.0F; return 100.0F;
break; break;
} }
} }
+5 -5
View File
@@ -12,8 +12,8 @@
/// ///
/// Based on the data sheet provided /// Based on the data sheet provided
/// ///
class TSL25911{ class TSL25911 {
public: public:
typedef enum { typedef enum {
TSL25911_FULL = 0x0, TSL25911_FULL = 0x0,
@@ -58,13 +58,13 @@ class TSL25911{
TSL2591_GAIN_MAX = 0x30, /// max gain (9876x) TSL2591_GAIN_MAX = 0x30, /// max gain (9876x)
} tsl2591Gain_t; } tsl2591Gain_t;
enum ChipModel{ enum ChipModel {
ChipModel_UNKNOWN = 0, ChipModel_UNKNOWN = 0,
ChipModel_TSL25911_REV0 = 0x50 ChipModel_TSL25911_REV0 = 0x50
}; };
TSL25911(TwoWire* i2c): m_initialized(false), gain(TSL2591_GAIN_MED), integration(TSL2591_INTEGRATIONTIME_500MS),i2c(i2c){} TSL25911(TwoWire* i2c): m_initialized(false), gain(TSL2591_GAIN_MED), integration(TSL2591_INTEGRATIONTIME_500MS),i2c(i2c) {}
TSL25911(TwoWire* i2c, tsl2591Gain_t _gain,tsl2591IntegrationTime_t _integration) : m_initialized(false),gain(_gain),integration(_integration),i2c(i2c) {} TSL25911(TwoWire* i2c, tsl2591Gain_t _gain,tsl2591IntegrationTime_t _integration) : m_initialized(false),gain(_gain),integration(_integration),i2c(i2c) {}
ChipModel chipModel(); ChipModel chipModel();
+66 -66
View File
@@ -31,83 +31,83 @@ This header must be included in any derived code or copies of the code.
#define hi_coeff9 -0.00000199 #define hi_coeff9 -0.00000199
/****************************************************************/ /****************************************************************/
float EnvironmentCalculations::Altitude(float pressure,float referencePressure,float outdoorTemp){ float EnvironmentCalculations::Altitude(float pressure,float referencePressure,float outdoorTemp) {
// Equation inverse to EquivalentSeaLevelPressure calculation. // Equation inverse to EquivalentSeaLevelPressure calculation.
float altitude = NAN; float altitude = NAN;
if (!isnan(pressure) && !isnan(referencePressure) && !isnan(outdoorTemp)){ if (!isnan(pressure) && !isnan(referencePressure) && !isnan(outdoorTemp)) {
altitude = pow(referencePressure / pressure, 0.190234) - 1; altitude = pow(referencePressure / pressure, 0.190234) - 1;
altitude *= ((outdoorTemp + 273.15) / 0.0065); altitude *= ((outdoorTemp + 273.15) / 0.0065);
} }
return altitude; return altitude;
} }
/****************************************************************/ /****************************************************************/
float EnvironmentCalculations::AbsoluteHumidity(float temperature, float humidity){ float EnvironmentCalculations::AbsoluteHumidity(float temperature, float humidity) {
//taken from https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/ //taken from https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/
//precision is about 0.1°C in range -30 to 35°C //precision is about 0.1°C in range -30 to 35°C
//August-Roche-Magnus 6.1094 exp(17.625 x T)/(T + 243.04) //August-Roche-Magnus 6.1094 exp(17.625 x T)/(T + 243.04)
//Buck (1981) 6.1121 exp(17.502 x T)/(T + 240.97) //Buck (1981) 6.1121 exp(17.502 x T)/(T + 240.97)
//reference https://www.eas.ualberta.ca/jdwilson/EAS372_13/Vomel_CIRES_satvpformulae.html //reference https://www.eas.ualberta.ca/jdwilson/EAS372_13/Vomel_CIRES_satvpformulae.html
float temp = NAN; float temp = NAN;
const float mw = 18.01534; // molar mass of water g/mol const float mw = 18.01534; // molar mass of water g/mol
const float r = 8.31447215; // Universal gas constant J/mol/K const float r = 8.31447215; // Universal gas constant J/mol/K
if (isnan(temperature) || isnan(humidity) ){ if (isnan(temperature) || isnan(humidity) ) {
return NAN; return NAN;
} }
temp = pow(2.718281828, (17.67 * temperature) / (temperature + 243.5)); temp = pow(2.718281828, (17.67 * temperature) / (temperature + 243.5));
//return (6.112 * temp * humidity * 2.1674) / (273.15 + temperature); //simplified version //return (6.112 * temp * humidity * 2.1674) / (273.15 + temperature); //simplified version
return (6.112 * temp * humidity * mw) / ((273.15 + temperature) * r); //long version return (6.112 * temp * humidity * mw) / ((273.15 + temperature) * r); //long version
} }
/****************************************************************/ /****************************************************************/
//FYI: https://ehp.niehs.nih.gov/1206273/ in detail this flow graph: https://ehp.niehs.nih.gov/wp-content/uploads/2013/10/ehp.1206273.g003.png //FYI: https://ehp.niehs.nih.gov/1206273/ in detail this flow graph: https://ehp.niehs.nih.gov/wp-content/uploads/2013/10/ehp.1206273.g003.png
float EnvironmentCalculations::HeatIndex(float temperature,float humidity){ float EnvironmentCalculations::HeatIndex(float temperature,float humidity) {
float heatIndex(NAN); float heatIndex(NAN);
if ( isnan(temperature) || isnan(humidity) ) { if ( isnan(temperature) || isnan(humidity) ) {
return heatIndex; return heatIndex;
}
temperature = (temperature * (9.0 / 5.0) + 32.0); /*conversion to [°F]*/
// Using both Rothfusz and Steadman's equations
// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
if (temperature <= 40) {
heatIndex = temperature; //first red block
}else{
heatIndex = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (humidity * 0.094)); //calculate A -- from the official site, not the flow graph
if (heatIndex >= 79) {
/*
* calculate B
* the following calculation is optimized. Simply spoken, reduzed cpu-operations to minimize used ram and runtime.
* Check the correctness with the following link:
* http://www.wolframalpha.com/input/?source=nav&i=b%3D+x1+%2B+x2*T+%2B+x3*H+%2B+x4*T*H+%2B+x5*T*T+%2B+x6*H*H+%2B+x7*T*T*H+%2B+x8*T*H*H+%2B+x9*T*T*H*H
*/
heatIndex = hi_coeff1
+ (hi_coeff2 + hi_coeff4 * humidity + temperature * (hi_coeff5 + hi_coeff7 * humidity)) * temperature
+ (hi_coeff3 + humidity * (hi_coeff6 + temperature * (hi_coeff8 + hi_coeff9 * temperature))) * humidity;
//third red block
if ((humidity < 13) && (temperature >= 80.0) && (temperature <= 112.0)) {
heatIndex -= ((13.0 - humidity) * 0.25) * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);
}else if ((humidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0)){
heatIndex += (0.02 * (humidity - 85.0) * (87.0 - temperature));
}
} }
}
return (heatIndex - 32.0) * (5.0 / 9.0); /*conversion back to [°C]*/ temperature = (temperature * (9.0 / 5.0) + 32.0); /*conversion to [°F]*/
// Using both Rothfusz and Steadman's equations
// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
if (temperature <= 40) {
heatIndex = temperature; //first red block
} else {
heatIndex = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (humidity * 0.094)); //calculate A -- from the official site, not the flow graph
if (heatIndex >= 79) {
/*
* calculate B
* the following calculation is optimized. Simply spoken, reduzed cpu-operations to minimize used ram and runtime.
* Check the correctness with the following link:
* http://www.wolframalpha.com/input/?source=nav&i=b%3D+x1+%2B+x2*T+%2B+x3*H+%2B+x4*T*H+%2B+x5*T*T+%2B+x6*H*H+%2B+x7*T*T*H+%2B+x8*T*H*H+%2B+x9*T*T*H*H
*/
heatIndex = hi_coeff1
+ (hi_coeff2 + hi_coeff4 * humidity + temperature * (hi_coeff5 + hi_coeff7 * humidity)) * temperature
+ (hi_coeff3 + humidity * (hi_coeff6 + temperature * (hi_coeff8 + hi_coeff9 * temperature))) * humidity;
//third red block
if ((humidity < 13) && (temperature >= 80.0) && (temperature <= 112.0)) {
heatIndex -= ((13.0 - humidity) * 0.25) * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);
} else if ((humidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0)) {
heatIndex += (0.02 * (humidity - 85.0) * (87.0 - temperature));
}
}
}
return (heatIndex - 32.0) * (5.0 / 9.0); /*conversion back to [°C]*/
} }
/****************************************************************/ /****************************************************************/
float EnvironmentCalculations::EquivalentSeaLevelPressure(float altitude,float temp,float pres){ float EnvironmentCalculations::EquivalentSeaLevelPressure(float altitude,float temp,float pres) {
float seaPress = NAN; float seaPress = NAN;
if(!isnan(altitude) && !isnan(temp) && !isnan(pres)){ if(!isnan(altitude) && !isnan(temp) && !isnan(pres)) {
seaPress = (pres / pow(1 - ((0.0065 *altitude) / (temp + (0.0065 *altitude) + 273.15)), 5.257)); seaPress = (pres / pow(1 - ((0.0065 *altitude) / (temp + (0.0065 *altitude) + 273.15)), 5.257));
} }
return seaPress; return seaPress;
@@ -115,15 +115,15 @@ float EnvironmentCalculations::EquivalentSeaLevelPressure(float altitude,float t
/****************************************************************/ /****************************************************************/
float EnvironmentCalculations::DewPoint(float temp,float hum){ float EnvironmentCalculations::DewPoint(float temp,float hum) {
// Equations courtesy of Brian McNoldy from http://andrew.rsmas.miami.edu; // Equations courtesy of Brian McNoldy from http://andrew.rsmas.miami.edu;
float dewPoint = NAN; float dewPoint = NAN;
if(!isnan(temp) && !isnan(hum)){ if(!isnan(temp) && !isnan(hum)) {
dewPoint = 243.04 * (log(hum/100.0) + ((17.625 * temp)/(243.04 + temp))) dewPoint = 243.04 * (log(hum/100.0) + ((17.625 * temp)/(243.04 + temp)))
/(17.625 - log(hum/100.0) - ((17.625 * temp)/(243.04 + temp))); /(17.625 - log(hum/100.0) - ((17.625 * temp)/(243.04 + temp)));
} }
return dewPoint; return dewPoint;
} }
+45 -45
View File
@@ -2,59 +2,59 @@
#ifndef TG_ENVIRONMENT_CALCULATIONS_H #ifndef TG_ENVIRONMENT_CALCULATIONS_H
#define TG_ENVIRONMENT_CALCULATIONS_H #define TG_ENVIRONMENT_CALCULATIONS_H
namespace EnvironmentCalculations{ namespace EnvironmentCalculations {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
/// Calculate the altitude based on the pressure and temperature /// Calculate the altitude based on the pressure and temperature
/// in temptUnit. /// in temptUnit.
/// @param pressure at the station in any units. /// @param pressure at the station in any units.
/// @param altUnit meters or feet. default=AltitudeUnit_Meters /// @param altUnit meters or feet. default=AltitudeUnit_Meters
/// @param referencePressure (usually pressure on MSL) /// @param referencePressure (usually pressure on MSL)
/// in the same units as pressure. default=1013.25hPa (ISA) /// in the same units as pressure. default=1013.25hPa (ISA)
/// @param outdoorTemp temperature at the station in tempUnit /// @param outdoorTemp temperature at the station in tempUnit
/// default=15°C (ISA) /// default=15°C (ISA)
/// @return Calculated Altitude in meters. /// @return Calculated Altitude in meters.
float Altitude( float Altitude(
float pressure, float pressure,
float referencePressure = 1013.25, // [hPa] ....ISA value float referencePressure = 1013.25, // [hPa] ....ISA value
float outdoorTemp = 15 // [°C] .... ISA value float outdoorTemp = 15 // [°C] .... ISA value
); );
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
/// Calculate the heatindex based on the humidity and temperature /// Calculate the heatindex based on the humidity and temperature
/// in tempUnit. /// in tempUnit.
/// The formula based on the Heat Index Equation of the US National Weather Service /// The formula based on the Heat Index Equation of the US National Weather Service
/// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml /// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
/// @param temperature in tempUnit /// @param temperature in tempUnit
/// @param humidity in percentage /// @param humidity in percentage
/// @return Calculated heatindex as float in TempUnit /// @return Calculated heatindex as float in TempUnit
float HeatIndex(float temperature,float humidity); float HeatIndex(float temperature,float humidity);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
/// Calculate the absolute humidity based on the relative humidity and temperature /// Calculate the absolute humidity based on the relative humidity and temperature
/// in tempUnit. /// in tempUnit.
/// the formula does work for values between -30°C and 35°C with 0.1°C precision /// the formula does work for values between -30°C and 35°C with 0.1°C precision
/// @param temperature in tempUnit /// @param temperature in tempUnit
/// @param humidity in percentage /// @param humidity in percentage
/// @return Calculated absolute humidity in grams/m³ /// @return Calculated absolute humidity in grams/m³
float AbsoluteHumidity(float temperature, float humidity); float AbsoluteHumidity(float temperature, float humidity);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
/// Convert current pressure to equivalent sea-level pressure. /// Convert current pressure to equivalent sea-level pressure.
/// @param altitude in meters. /// @param altitude in meters.
/// @param temp in tempUnit. /// @param temp in tempUnit.
/// @param pressure at the station in any units. /// @param pressure at the station in any units.
/// @return Equivalent pressure at sea level. The input pressure /// @return Equivalent pressure at sea level. The input pressure
/// unit will determine the output /// unit will determine the output
/// pressure unit. /// pressure unit.
float EquivalentSeaLevelPressure(float altitude,float temp,float pres); float EquivalentSeaLevelPressure(float altitude,float temp,float pres);
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
/// Calculate the dew point based on the temperature in tempUnit /// Calculate the dew point based on the temperature in tempUnit
/// and humidity. /// and humidity.
/// @param temp in tempUnit. /// @param temp in tempUnit.
/// @param hum in %. /// @param hum in %.
float DewPoint(float temp,float hum); float DewPoint(float temp,float hum);
} }
+23 -13
View File
@@ -4,7 +4,7 @@
#include "environment.h" #include "environment.h"
Sensor::Sensor(TwoWire* i2c){ Sensor::Sensor(TwoWire* i2c) {
bme = new BME280(i2c); bme = new BME280(i2c);
ltr = new LTR390(i2c); ltr = new LTR390(i2c);
tsl = new TSL25911(i2c); tsl = new TSL25911(i2c);
@@ -12,30 +12,40 @@ Sensor::Sensor(TwoWire* i2c){
pms = new PMSA003(i2c); pms = new PMSA003(i2c);
} }
void Sensor::TSL_init(void){tsl->begin();} void Sensor::TSL_init(void) {
void Sensor::BME_init(void){bme->begin();} tsl->begin();
void Sensor::ICM_init(void){}//Nothing to do afaik }
void Sensor::LTR_init(void){ltr->begin();} void Sensor::BME_init(void) {
void Sensor::SGP_init(void){sgp->begin();} bme->begin();
void Sensor::PMS_init(void){pms->begin();} }
void Sensor::ICM_init(void) {} //Nothing to do afaik
void Sensor::LTR_init(void) {
ltr->begin();
}
void Sensor::SGP_init(void) {
sgp->begin();
}
void Sensor::PMS_init(void) {
pms->begin();
}
void Sensor::BME_measure(){ void Sensor::BME_measure() {
bme->read(pres, temp, hum); bme->read(pres, temp, hum);
heatidx = EnvironmentCalculations::HeatIndex(temp,hum); heatidx = EnvironmentCalculations::HeatIndex(temp,hum);
} }
void Sensor::LTR_measure(){ void Sensor::LTR_measure() {
ltr->read(uv, uvi); ltr->read(uv, uvi);
} }
void Sensor::TSL_measure(void){ void Sensor::TSL_measure(void) {
tsl->read(light_vis, light_ir, light_full, light_lux); tsl->read(light_vis, light_ir, light_full, light_lux);
} }
void Sensor::ICM_measure(void){ void Sensor::ICM_measure(void) {
//Do realy care about this ???? //Do realy care about this ????
} }
void Sensor::SGP_measure(void){ void Sensor::SGP_measure(void) {
sgp->read(voci, temp, hum); sgp->read(voci, temp, hum);
} }
void Sensor::PMS_measure(void){ void Sensor::PMS_measure(void) {
pms->read(pmd); pms->read(pmd);
} }
+19 -10
View File
@@ -15,8 +15,8 @@
class Sensor class Sensor
{ {
// user-accessible "public" interface // user-accessible "public" interface
public: public:
Sensor(TwoWire* i2c); Sensor(TwoWire* i2c);
float temp = 0; float temp = 0;
@@ -50,16 +50,25 @@ class Sensor
void SGP_measure(void); void SGP_measure(void);
void PMS_measure(void); void PMS_measure(void);
void measure(){ void init() {
TSL_measure(); BME_init();
BME_measure(); LTR_init();
ICM_measure(); TSL_init();
LTR_measure(); SGP_init();
SGP_measure(); PMS_init();
PMS_measure(); ICM_init();
} }
private: void measure() {
BME_measure();
LTR_measure();
TSL_measure();
SGP_measure();
PMS_measure();
ICM_measure();
}
private:
BME280* bme = NULL; BME280* bme = NULL;
LTR390* ltr = NULL; LTR390* ltr = NULL;
TSL25911* tsl = NULL; TSL25911* tsl = NULL;
+65 -63
View File
@@ -251,9 +251,11 @@ static fix16_t fix16_exp(fix16_t x) {
// exp(x) for x = +/- {1, 1/8, 1/64, 1/512} // exp(x) for x = +/- {1, 1/8, 1/64, 1/512}
#define NUM_EXP_VALUES 4 #define NUM_EXP_VALUES 4
static const fix16_t exp_pos_values[NUM_EXP_VALUES] = { static const fix16_t exp_pos_values[NUM_EXP_VALUES] = {
F16(2.7182818), F16(1.1331485), F16(1.0157477), F16(1.0019550)}; F16(2.7182818), F16(1.1331485), F16(1.0157477), F16(1.0019550)
};
static const fix16_t exp_neg_values[NUM_EXP_VALUES] = { static const fix16_t exp_neg_values[NUM_EXP_VALUES] = {
F16(0.3678794), F16(0.8824969), F16(0.9844964), F16(0.9980488)}; F16(0.3678794), F16(0.8824969), F16(0.9844964), F16(0.9980488)
};
const fix16_t* exp_values; const fix16_t* exp_values;
fix16_t res, arg; fix16_t res, arg;
@@ -293,8 +295,8 @@ static void VocAlgorithm__mean_variance_estimator__set_parameters(
fix16_t tau_mean_variance_hours, fix16_t gating_max_duration_minutes); fix16_t tau_mean_variance_hours, fix16_t gating_max_duration_minutes);
static void static void
VocAlgorithm__mean_variance_estimator__set_states(VocAlgorithmParams* params, VocAlgorithm__mean_variance_estimator__set_states(VocAlgorithmParams* params,
fix16_t mean, fix16_t std, fix16_t mean, fix16_t std,
fix16_t uptime_gamma); fix16_t uptime_gamma);
static fix16_t static fix16_t
VocAlgorithm__mean_variance_estimator__get_std(VocAlgorithmParams* params); VocAlgorithm__mean_variance_estimator__get_std(VocAlgorithmParams* params);
static fix16_t static fix16_t
@@ -311,16 +313,16 @@ static fix16_t VocAlgorithm__mean_variance_estimator___sigmoid__process(
VocAlgorithmParams* params, fix16_t sample); VocAlgorithmParams* params, fix16_t sample);
static void VocAlgorithm__mox_model__init(VocAlgorithmParams* params); static void VocAlgorithm__mox_model__init(VocAlgorithmParams* params);
static void VocAlgorithm__mox_model__set_parameters(VocAlgorithmParams* params, static void VocAlgorithm__mox_model__set_parameters(VocAlgorithmParams* params,
fix16_t SRAW_STD, fix16_t SRAW_STD,
fix16_t SRAW_MEAN); fix16_t SRAW_MEAN);
static fix16_t VocAlgorithm__mox_model__process(VocAlgorithmParams* params, static fix16_t VocAlgorithm__mox_model__process(VocAlgorithmParams* params,
fix16_t sraw); fix16_t sraw);
static void VocAlgorithm__sigmoid_scaled__init(VocAlgorithmParams* params); static void VocAlgorithm__sigmoid_scaled__init(VocAlgorithmParams* params);
static void static void
VocAlgorithm__sigmoid_scaled__set_parameters(VocAlgorithmParams* params, VocAlgorithm__sigmoid_scaled__set_parameters(VocAlgorithmParams* params,
fix16_t offset); fix16_t offset);
static fix16_t VocAlgorithm__sigmoid_scaled__process(VocAlgorithmParams* params, static fix16_t VocAlgorithm__sigmoid_scaled__process(VocAlgorithmParams* params,
fix16_t sample); fix16_t sample);
static void VocAlgorithm__adaptive_lowpass__init(VocAlgorithmParams* params); static void VocAlgorithm__adaptive_lowpass__init(VocAlgorithmParams* params);
static void static void
VocAlgorithm__adaptive_lowpass__set_parameters(VocAlgorithmParams* params); VocAlgorithm__adaptive_lowpass__set_parameters(VocAlgorithmParams* params);
@@ -354,7 +356,7 @@ static void VocAlgorithm__init_instances(VocAlgorithmParams* params) {
VocAlgorithm__mean_variance_estimator__get_mean(params)); VocAlgorithm__mean_variance_estimator__get_mean(params));
VocAlgorithm__sigmoid_scaled__init(params); VocAlgorithm__sigmoid_scaled__init(params);
VocAlgorithm__sigmoid_scaled__set_parameters(params, VocAlgorithm__sigmoid_scaled__set_parameters(params,
params->mVoc_Index_Offset); params->mVoc_Index_Offset);
VocAlgorithm__adaptive_lowpass__init(params); VocAlgorithm__adaptive_lowpass__init(params);
VocAlgorithm__adaptive_lowpass__set_parameters(params); VocAlgorithm__adaptive_lowpass__set_parameters(params);
} }
@@ -429,7 +431,7 @@ static void
VocAlgorithm__mean_variance_estimator__init(VocAlgorithmParams* params) { VocAlgorithm__mean_variance_estimator__init(VocAlgorithmParams* params) {
VocAlgorithm__mean_variance_estimator__set_parameters(params, F16(0.), VocAlgorithm__mean_variance_estimator__set_parameters(params, F16(0.),
F16(0.), F16(0.)); F16(0.), F16(0.));
VocAlgorithm__mean_variance_estimator___init_instances(params); VocAlgorithm__mean_variance_estimator___init_instances(params);
} }
@@ -459,9 +461,9 @@ static void VocAlgorithm__mean_variance_estimator__set_parameters(
VocAlgorithm_SAMPLING_INTERVAL) / VocAlgorithm_SAMPLING_INTERVAL) /
(VocAlgorithm_TAU_INITIAL_MEAN + VocAlgorithm_SAMPLING_INTERVAL))); (VocAlgorithm_TAU_INITIAL_MEAN + VocAlgorithm_SAMPLING_INTERVAL)));
params->m_Mean_Variance_Estimator___Gamma_Initial_Variance = F16( params->m_Mean_Variance_Estimator___Gamma_Initial_Variance = F16(
((VocAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING * ((VocAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING *
VocAlgorithm_SAMPLING_INTERVAL) / VocAlgorithm_SAMPLING_INTERVAL) /
(VocAlgorithm_TAU_INITIAL_VARIANCE + VocAlgorithm_SAMPLING_INTERVAL))); (VocAlgorithm_TAU_INITIAL_VARIANCE + VocAlgorithm_SAMPLING_INTERVAL)));
params->m_Mean_Variance_Estimator__Gamma_Mean = F16(0.); params->m_Mean_Variance_Estimator__Gamma_Mean = F16(0.);
params->m_Mean_Variance_Estimator__Gamma_Variance = F16(0.); params->m_Mean_Variance_Estimator__Gamma_Variance = F16(0.);
params->m_Mean_Variance_Estimator___Uptime_Gamma = F16(0.); params->m_Mean_Variance_Estimator___Uptime_Gamma = F16(0.);
@@ -471,8 +473,8 @@ static void VocAlgorithm__mean_variance_estimator__set_parameters(
static void static void
VocAlgorithm__mean_variance_estimator__set_states(VocAlgorithmParams* params, VocAlgorithm__mean_variance_estimator__set_states(VocAlgorithmParams* params,
fix16_t mean, fix16_t std, fix16_t mean, fix16_t std,
fix16_t uptime_gamma) { fix16_t uptime_gamma) {
params->m_Mean_Variance_Estimator___Mean = mean; params->m_Mean_Variance_Estimator___Mean = mean;
params->m_Mean_Variance_Estimator___Std = std; params->m_Mean_Variance_Estimator___Std = std;
@@ -532,10 +534,10 @@ static void VocAlgorithm__mean_variance_estimator___calculate_gamma(
gating_threshold_mean = gating_threshold_mean =
(F16(VocAlgorithm_GATING_THRESHOLD) + (F16(VocAlgorithm_GATING_THRESHOLD) +
(fix16_mul( (fix16_mul(
F16((VocAlgorithm_GATING_THRESHOLD_INITIAL - F16((VocAlgorithm_GATING_THRESHOLD_INITIAL -
VocAlgorithm_GATING_THRESHOLD)), VocAlgorithm_GATING_THRESHOLD)),
VocAlgorithm__mean_variance_estimator___sigmoid__process( VocAlgorithm__mean_variance_estimator___sigmoid__process(
params, params->m_Mean_Variance_Estimator___Uptime_Gating)))); params, params->m_Mean_Variance_Estimator___Uptime_Gating))));
VocAlgorithm__mean_variance_estimator___sigmoid__set_parameters( VocAlgorithm__mean_variance_estimator___sigmoid__set_parameters(
params, F16(1.), gating_threshold_mean, params, F16(1.), gating_threshold_mean,
F16(VocAlgorithm_GATING_THRESHOLD_TRANSITION)); F16(VocAlgorithm_GATING_THRESHOLD_TRANSITION));
@@ -553,16 +555,16 @@ static void VocAlgorithm__mean_variance_estimator___calculate_gamma(
gamma_variance = gamma_variance =
(params->m_Mean_Variance_Estimator___Gamma + (params->m_Mean_Variance_Estimator___Gamma +
(fix16_mul( (fix16_mul(
(params->m_Mean_Variance_Estimator___Gamma_Initial_Variance - (params->m_Mean_Variance_Estimator___Gamma_Initial_Variance -
params->m_Mean_Variance_Estimator___Gamma), params->m_Mean_Variance_Estimator___Gamma),
(sigmoid_gamma_variance - sigmoid_gamma_mean)))); (sigmoid_gamma_variance - sigmoid_gamma_mean))));
gating_threshold_variance = gating_threshold_variance =
(F16(VocAlgorithm_GATING_THRESHOLD) + (F16(VocAlgorithm_GATING_THRESHOLD) +
(fix16_mul( (fix16_mul(
F16((VocAlgorithm_GATING_THRESHOLD_INITIAL - F16((VocAlgorithm_GATING_THRESHOLD_INITIAL -
VocAlgorithm_GATING_THRESHOLD)), VocAlgorithm_GATING_THRESHOLD)),
VocAlgorithm__mean_variance_estimator___sigmoid__process( VocAlgorithm__mean_variance_estimator___sigmoid__process(
params, params->m_Mean_Variance_Estimator___Uptime_Gating)))); params, params->m_Mean_Variance_Estimator___Uptime_Gating))));
VocAlgorithm__mean_variance_estimator___sigmoid__set_parameters( VocAlgorithm__mean_variance_estimator___sigmoid__set_parameters(
params, F16(1.), gating_threshold_variance, params, F16(1.), gating_threshold_variance,
F16(VocAlgorithm_GATING_THRESHOLD_TRANSITION)); F16(VocAlgorithm_GATING_THRESHOLD_TRANSITION));
@@ -578,11 +580,11 @@ static void VocAlgorithm__mean_variance_estimator___calculate_gamma(
F16((1. + VocAlgorithm_GATING_MAX_RATIO)))) - F16((1. + VocAlgorithm_GATING_MAX_RATIO)))) -
F16(VocAlgorithm_GATING_MAX_RATIO))))); F16(VocAlgorithm_GATING_MAX_RATIO)))));
if ((params->m_Mean_Variance_Estimator___Gating_Duration_Minutes < if ((params->m_Mean_Variance_Estimator___Gating_Duration_Minutes <
F16(0.))) { F16(0.))) {
params->m_Mean_Variance_Estimator___Gating_Duration_Minutes = F16(0.); params->m_Mean_Variance_Estimator___Gating_Duration_Minutes = F16(0.);
} }
if ((params->m_Mean_Variance_Estimator___Gating_Duration_Minutes > if ((params->m_Mean_Variance_Estimator___Gating_Duration_Minutes >
params->m_Mean_Variance_Estimator__Gating_Max_Duration_Minutes)) { params->m_Mean_Variance_Estimator__Gating_Max_Duration_Minutes)) {
params->m_Mean_Variance_Estimator___Uptime_Gating = F16(0.); params->m_Mean_Variance_Estimator___Uptime_Gating = F16(0.);
} }
} }
@@ -600,7 +602,7 @@ static void VocAlgorithm__mean_variance_estimator__process(
params->m_Mean_Variance_Estimator___Mean = F16(0.); params->m_Mean_Variance_Estimator___Mean = F16(0.);
} else { } else {
if (((params->m_Mean_Variance_Estimator___Mean >= F16(100.)) || if (((params->m_Mean_Variance_Estimator___Mean >= F16(100.)) ||
(params->m_Mean_Variance_Estimator___Mean <= F16(-100.)))) { (params->m_Mean_Variance_Estimator___Mean <= F16(-100.)))) {
params->m_Mean_Variance_Estimator___Sraw_Offset = params->m_Mean_Variance_Estimator___Sraw_Offset =
(params->m_Mean_Variance_Estimator___Sraw_Offset + (params->m_Mean_Variance_Estimator___Sraw_Offset +
params->m_Mean_Variance_Estimator___Mean); params->m_Mean_Variance_Estimator___Mean);
@@ -610,8 +612,8 @@ static void VocAlgorithm__mean_variance_estimator__process(
VocAlgorithm__mean_variance_estimator___calculate_gamma( VocAlgorithm__mean_variance_estimator___calculate_gamma(
params, voc_index_from_prior); params, voc_index_from_prior);
delta_sgp = (fix16_div( delta_sgp = (fix16_div(
(sraw - params->m_Mean_Variance_Estimator___Mean), (sraw - params->m_Mean_Variance_Estimator___Mean),
F16(VocAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING))); F16(VocAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING)));
if ((delta_sgp < F16(0.))) { if ((delta_sgp < F16(0.))) {
c = (params->m_Mean_Variance_Estimator___Std - delta_sgp); c = (params->m_Mean_Variance_Estimator___Std - delta_sgp);
} else { } else {
@@ -622,25 +624,25 @@ static void VocAlgorithm__mean_variance_estimator__process(
additional_scaling = F16(4.); additional_scaling = F16(4.);
} }
params->m_Mean_Variance_Estimator___Std = (fix16_mul( params->m_Mean_Variance_Estimator___Std = (fix16_mul(
fix16_sqrt((fix16_mul( fix16_sqrt((fix16_mul(
additional_scaling, additional_scaling,
(F16(VocAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING) - (F16(VocAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING) -
params->m_Mean_Variance_Estimator__Gamma_Variance)))), params->m_Mean_Variance_Estimator__Gamma_Variance)))),
fix16_sqrt(( fix16_sqrt((
(fix16_mul( (fix16_mul(
params->m_Mean_Variance_Estimator___Std, params->m_Mean_Variance_Estimator___Std,
(fix16_div( (fix16_div(
params->m_Mean_Variance_Estimator___Std, params->m_Mean_Variance_Estimator___Std,
(fix16_mul( (fix16_mul(
F16(VocAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING), F16(VocAlgorithm_MEAN_VARIANCE_ESTIMATOR__GAMMA_SCALING),
additional_scaling)))))) + additional_scaling)))))) +
(fix16_mul( (fix16_mul(
(fix16_div( (fix16_div(
(fix16_mul( (fix16_mul(
params->m_Mean_Variance_Estimator__Gamma_Variance, params->m_Mean_Variance_Estimator__Gamma_Variance,
delta_sgp)), delta_sgp)),
additional_scaling)), additional_scaling)),
delta_sgp)))))); delta_sgp))))));
params->m_Mean_Variance_Estimator___Mean = params->m_Mean_Variance_Estimator___Mean =
(params->m_Mean_Variance_Estimator___Mean + (params->m_Mean_Variance_Estimator___Mean +
(fix16_mul(params->m_Mean_Variance_Estimator__Gamma_Mean, (fix16_mul(params->m_Mean_Variance_Estimator__Gamma_Mean,
@@ -686,15 +688,15 @@ static void VocAlgorithm__mox_model__init(VocAlgorithmParams* params) {
} }
static void VocAlgorithm__mox_model__set_parameters(VocAlgorithmParams* params, static void VocAlgorithm__mox_model__set_parameters(VocAlgorithmParams* params,
fix16_t SRAW_STD, fix16_t SRAW_STD,
fix16_t SRAW_MEAN) { fix16_t SRAW_MEAN) {
params->m_Mox_Model__Sraw_Std = SRAW_STD; params->m_Mox_Model__Sraw_Std = SRAW_STD;
params->m_Mox_Model__Sraw_Mean = SRAW_MEAN; params->m_Mox_Model__Sraw_Mean = SRAW_MEAN;
} }
static fix16_t VocAlgorithm__mox_model__process(VocAlgorithmParams* params, static fix16_t VocAlgorithm__mox_model__process(VocAlgorithmParams* params,
fix16_t sraw) { fix16_t sraw) {
return (fix16_mul((fix16_div((sraw - params->m_Mox_Model__Sraw_Mean), return (fix16_mul((fix16_div((sraw - params->m_Mox_Model__Sraw_Mean),
(-(params->m_Mox_Model__Sraw_Std + (-(params->m_Mox_Model__Sraw_Std +
@@ -709,13 +711,13 @@ static void VocAlgorithm__sigmoid_scaled__init(VocAlgorithmParams* params) {
static void static void
VocAlgorithm__sigmoid_scaled__set_parameters(VocAlgorithmParams* params, VocAlgorithm__sigmoid_scaled__set_parameters(VocAlgorithmParams* params,
fix16_t offset) { fix16_t offset) {
params->m_Sigmoid_Scaled__Offset = offset; params->m_Sigmoid_Scaled__Offset = offset;
} }
static fix16_t VocAlgorithm__sigmoid_scaled__process(VocAlgorithmParams* params, static fix16_t VocAlgorithm__sigmoid_scaled__process(VocAlgorithmParams* params,
fix16_t sample) { fix16_t sample) {
fix16_t x; fix16_t x;
fix16_t shift; fix16_t shift;
@@ -729,18 +731,18 @@ static fix16_t VocAlgorithm__sigmoid_scaled__process(VocAlgorithmParams* params,
} else { } else {
if ((sample >= F16(0.))) { if ((sample >= F16(0.))) {
shift = (fix16_div( shift = (fix16_div(
(F16(VocAlgorithm_SIGMOID_L) - (F16(VocAlgorithm_SIGMOID_L) -
(fix16_mul(F16(5.), params->m_Sigmoid_Scaled__Offset))), (fix16_mul(F16(5.), params->m_Sigmoid_Scaled__Offset))),
F16(4.))); F16(4.)));
return ((fix16_div((F16(VocAlgorithm_SIGMOID_L) + shift), return ((fix16_div((F16(VocAlgorithm_SIGMOID_L) + shift),
(F16(1.) + fix16_exp(x)))) - (F16(1.) + fix16_exp(x)))) -
shift); shift);
} else { } else {
return (fix16_mul( return (fix16_mul(
(fix16_div(params->m_Sigmoid_Scaled__Offset, (fix16_div(params->m_Sigmoid_Scaled__Offset,
F16(VocAlgorithm_VOC_INDEX_OFFSET_DEFAULT))), F16(VocAlgorithm_VOC_INDEX_OFFSET_DEFAULT))),
(fix16_div(F16(VocAlgorithm_SIGMOID_L), (fix16_div(F16(VocAlgorithm_SIGMOID_L),
(F16(1.) + fix16_exp(x)))))); (F16(1.) + fix16_exp(x))))));
} }
} }
} }
+38 -38
View File
@@ -10,54 +10,54 @@
typedef void (*timedfun_ptr)(); typedef void (*timedfun_ptr)();
class TimedFun { class TimedFun {
public: public:
TimedFun(){}; TimedFun() {};
void registerFun(timedfun_ptr p, uint64_t s){ void registerFun(timedfun_ptr p, uint64_t s) {
funmap.push_back(std::pair<timedfun_ptr,uint64_t>(p,s)); funmap.push_back(std::pair<timedfun_ptr,uint64_t>(p,s));
}; };
void registerFunCond(timedfun_ptr p, uint64_t s){ void registerFunCond(timedfun_ptr p, uint64_t s) {
funmap.push_back(std::pair<timedfun_ptr,uint64_t>(p,s)); funmap.push_back(std::pair<timedfun_ptr,uint64_t>(p,s));
}; };
void minuteTick(){ void tick() {
++counter; ++counter;
} }
void minuteTick(int64_t m){ void tick(int64_t m) {
counter += m; counter += m;
} }
void setTick(int64_t m){ void setTick(int64_t m) {
counter = m; counter = m;
old_counter = m; old_counter = m;
} }
void update(){ void update() {
uint64_t ccounter = old_counter; uint64_t ccounter = old_counter;
old_counter = counter; old_counter = counter;
for (const auto &e : funmap){ for (const auto &e : funmap) {
if( ((counter % e.second == 0) && (counter != ccounter)) || if( ((counter % e.second == 0) && (counter != ccounter)) ||
((counter-ccounter) >= e.second) || ((counter%e.second) < (ccounter%e.second))){ ((counter-ccounter) >= e.second) || ((counter%e.second) < (ccounter%e.second))) {
e.first();
}
}
old_counter = counter;
};
void updateForce(){
Serial.println("TF: Force updating all");
for (const auto &e : funmap){
e.first(); e.first();
} }
Serial.println("TF: OK");
} }
old_counter = counter;
};
private: void updateForce() {
uint64_t counter = 0; Serial.println("TF: Force updating all");
uint64_t old_counter = 0; for (const auto &e : funmap) {
std::vector<std::pair<timedfun_ptr,uint64_t>> funmap; e.first();
}
Serial.println("TF: OK");
}
private:
uint64_t counter = 0;
uint64_t old_counter = 0;
std::vector<std::pair<timedfun_ptr,uint64_t>> funmap;
}; };
+74 -72
View File
@@ -3,114 +3,116 @@
volatile uint8_t gtIRQ = 0; volatile uint8_t gtIRQ = 0;
void IRAM_ATTR _gt_irq_handler() { void IRAM_ATTR _gt_irq_handler() {
noInterrupts(); noInterrupts();
gtIRQ = 1; gtIRQ = 1;
interrupts(); interrupts();
} }
GT1151::GT1151(TwoWire* i2c){ wire = i2c;} GT1151::GT1151(TwoWire* i2c) {
wire = i2c;
}
void GT1151::setHandler(void (*handler)(int8_t, GTPoint*)) { void GT1151::setHandler(void (*handler)(int8_t, GTPoint*)) {
touchHandler = handler; touchHandler = handler;
} }
void GT1151::armIRQ() { void GT1151::armIRQ() {
attachInterrupt(GT1151_INT_PIN, _gt_irq_handler, RISING); attachInterrupt(GT1151_INT_PIN, _gt_irq_handler, RISING);
} }
void GT1151::onIRQ() { void GT1151::onIRQ() {
GTPoint points[CT_MAX_TOUCH]; GTPoint points[CT_MAX_TOUCH];
int16_t contacts = readInput((GTPoint *) &points); int16_t contacts = readInput((GTPoint *) &points);
dev.holding = contacts > 0 && dev.pressing; dev.holding = contacts > 0 && dev.pressing;
dev.pressing = contacts > 0; dev.pressing = contacts > 0;
if(dev.holding){ if(dev.holding) {
dev.dx = points[0].x - dev.points[0].x; dev.dx = points[0].x - dev.points[0].x;
dev.dy = points[0].y - dev.points[0].y; dev.dy = points[0].y - dev.points[0].y;
}else if(dev.pressing){ } else if(dev.pressing) {
memcpy(dev.points,points,sizeof(GTPoint)*CT_MAX_TOUCH); memcpy(dev.points,points,sizeof(GTPoint)*CT_MAX_TOUCH);
} }
if (contacts < 0) return; if (contacts < 0) return;
if (contacts > 0) touchHandler(contacts, (GTPoint *)dev.points); if (contacts > 0) touchHandler(contacts, (GTPoint *)dev.points);
WriteRegister(GT1151_COORD_ADDR, 0x00); WriteRegister(GT1151_COORD_ADDR, 0x00);
} }
int16_t GT1151::readInput(GTPoint* points) { int16_t GT1151::readInput(GTPoint* points) {
uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(points)); uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(points));
int touch_num; int touch_num;
uint8_t regState; uint8_t regState;
int error = !ReadRegister(GT1151_COORD_ADDR, &regState, 1); int error = !ReadRegister(GT1151_COORD_ADDR, &regState, 1);
if ((regState & 0x80)==0) return -1; if ((regState & 0x80)==0) return -1;
touch_num = regState & 0x0f; touch_num = regState & 0x0f;
if(touch_num > 5) return -1; if(touch_num > 5) return -1;
if (touch_num <= 0) return touch_num; if (touch_num <= 0) return touch_num;
error = !ReadRegister(GT1151_COORD_ADDR, data, sizeof(GTPoint) * touch_num); error = !ReadRegister(GT1151_COORD_ADDR, data, sizeof(GTPoint) * touch_num);
if (error) return -1; if (error) return -1;
return touch_num; return touch_num;
} }
void GT1151::Reset(void){ void GT1151::Reset(void) {
pinMode(GT1151_RESET_PIN, OUTPUT); pinMode(GT1151_RESET_PIN, OUTPUT);
pinMode(GT1151_INT_PIN, INPUT); pinMode(GT1151_INT_PIN, INPUT);
digitalWrite(GT1151_RESET_PIN, HIGH); digitalWrite(GT1151_RESET_PIN, HIGH);
delay(100); delay(100);
digitalWrite(GT1151_RESET_PIN, LOW); digitalWrite(GT1151_RESET_PIN, LOW);
delay(100); delay(100);
digitalWrite(GT1151_RESET_PIN, HIGH); digitalWrite(GT1151_RESET_PIN, HIGH);
delay(100); delay(100);
} }
void GT1151::ReadVersion(void){ void GT1151::ReadVersion(void) {
uint8_t buf[4] = {}; uint8_t buf[4] = {};
ReadRegister(GT1151_REG_ID, buf, 4); ReadRegister(GT1151_REG_ID, buf, 4);
} }
void GT1151::begin(void){ void GT1151::begin(void) {
delay(500); delay(500);
Reset(); Reset();
ReadVersion(); ReadVersion();
armIRQ(); armIRQ();
} }
void GT1151::update() { void GT1151::update() {
noInterrupts(); noInterrupts();
uint8_t irq = gtIRQ; uint8_t irq = gtIRQ;
gtIRQ = 0; gtIRQ = 0;
interrupts(); interrupts();
// Serial.printf("IRQ: %d\n",irq); // Serial.printf("IRQ: %d\n",irq);
if (irq) onIRQ(); if (irq) onIRQ();
else dev.pressing = false; else dev.pressing = false;
} }
bool GT1151::WriteRegister(uint16_t addr, uint8_t data){ bool GT1151::WriteRegister(uint16_t addr, uint8_t data) {
wire->beginTransmission(GT1151_ADDRESS); wire->beginTransmission(GT1151_ADDRESS);
wire->write(highByte(addr)); wire->write(highByte(addr));
wire->write(lowByte(addr)); wire->write(lowByte(addr));
wire->write(data); wire->write(data);
wire->endTransmission(); wire->endTransmission();
return true; return true;
} }
bool GT1151::ReadRegister(uint16_t addr,uint8_t data[],uint8_t length){ bool GT1151::ReadRegister(uint16_t addr,uint8_t data[],uint8_t length) {
uint8_t ord(0); uint8_t ord(0);
wire->beginTransmission(GT1151_ADDRESS); wire->beginTransmission(GT1151_ADDRESS);
wire->write(highByte(addr)); wire->write(highByte(addr));
wire->write(lowByte(addr)); wire->write(lowByte(addr));
wire->endTransmission(); wire->endTransmission();
wire->requestFrom(static_cast<uint8_t>(GT1151_ADDRESS), length); wire->requestFrom(static_cast<uint8_t>(GT1151_ADDRESS), length);
while(wire->available()){ while(wire->available()) {
data[ord++] = wire->read(); data[ord++] = wire->read();
} }
return ord == length; return ord == length;
} }
+21 -21
View File
@@ -33,40 +33,40 @@ struct GTPoint {
uint16_t a; uint16_t a;
}; };
typedef struct{ typedef struct {
bool holding; bool holding;
bool pressing; bool pressing;
GTPoint points[CT_MAX_TOUCH]; GTPoint points[CT_MAX_TOUCH];
int16_t dx,dy; int16_t dx,dy;
}GT1151_Dev; } GT1151_Dev;
class GT1151{ class GT1151 {
public: public:
GT1151_Dev dev; GT1151_Dev dev;
GT1151(TwoWire* i2c); GT1151(TwoWire* i2c);
void update(void); void update(void);
void begin(void); void begin(void);
void Reset(void); void Reset(void);
void Gesture(void); void Gesture(void);
void setHandler(void (*handler)(int8_t, GTPoint*)); void setHandler(void (*handler)(int8_t, GTPoint*));
private: private:
void (*touchHandler)(int8_t, GTPoint*); void (*touchHandler)(int8_t, GTPoint*);
TwoWire* wire; TwoWire* wire;
void armIRQ(void); void armIRQ(void);
void onIRQ(void); void onIRQ(void);
int16_t readInput(GTPoint* points); int16_t readInput(GTPoint* points);
void ReadVersion(void); void ReadVersion(void);
uint8_t Scan(void); uint8_t Scan(void);
bool WriteRegister(uint16_t addr, uint8_t data); bool WriteRegister(uint16_t addr, uint8_t data);
bool ReadRegister(uint16_t addr,uint8_t data[],uint8_t length); bool ReadRegister(uint16_t addr,uint8_t data[],uint8_t length);
}; };
#endif #endif