[M] Fix Sensors

This commit is contained in:
choelzl 2022-05-28 15:06:59 +02:00
parent f05b6492b0
commit 58ba94a455
Signed by: sora
GPG Key ID: A362EA0491E2EEA0
39 changed files with 14135 additions and 14103 deletions

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);
} }
} }

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){
if(id>=200 && id<300){ //Thunder ICON_tpe getWeatherIcon(int id) {
return ICON_CLOUD_THUNDER; if(id>=200 && id<300) { //Thunder
}else if(id>=300 && id<400){//Drizzle return ICON_CLOUD_THUNDER;
return ICON_CLOUD_RAIN; } else if(id>=300 && id<400) { //Drizzle
}else if(id>=500 && id<600){//Rain return ICON_CLOUD_RAIN;
return ICON_CLOUD_RAIN; } else if(id>=500 && id<600) { //Rain
}else if(id>=600 && id<700){//Snow return ICON_CLOUD_RAIN;
return ICON_CLOUD_SNOW; } else if(id>=600 && id<700) { //Snow
}else if(id>=700 && id<800){//Warning return ICON_CLOUD_SNOW;
return ICON_WARN; } else if(id>=700 && id<800) { //Warning
}else if(id>=800 && id<900){//Clear & Cloudy return ICON_WARN;
if(id==800) return ICON_SUN; } else if(id>=800 && id<900) { //Clear & Cloudy
else if(id==801) return ICON_CLOUD_SUN; if(id==800) return ICON_SUN;
else return ICON_CLOUD; else if(id==801) return ICON_CLOUD_SUN;
}else{ else return ICON_CLOUD;
return ICON_WARN; } else {
} return ICON_WARN;
}
} }
void WeatherDisplay::drawDisplay() { void WeatherDisplay::drawDisplay() {
@ -107,7 +113,7 @@ void WeatherDisplay::drawDisplay() {
Paint_DrawTime(20, 76, &sunsetdt, &Font12, WHITE, BLACK); Paint_DrawTime(20, 76, &sunsetdt, &Font12, WHITE, BLACK);
} }
void TempDisplay::drawDisplay() { void TempDisplay::drawDisplay() {
Paint_DrawIcon(0,8, ICON_TEMPERATURE,&FontIcon, BLACK, WHITE); Paint_DrawIcon(0,8, ICON_TEMPERATURE,&FontIcon, BLACK, WHITE);
Paint_DrawFltUnit(76,0,sensor->temp, "C", &Font24, BLACK, WHITE); Paint_DrawFltUnit(76,0,sensor->temp, "C", &Font24, BLACK, WHITE);
Paint_DrawFltUnit(186,6,sensor->heatidx, "C", &Font12, BLACK, WHITE); Paint_DrawFltUnit(186,6,sensor->heatidx, "C", &Font12, BLACK, WHITE);
@ -117,7 +123,7 @@ void TempDisplay::drawDisplay() {
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);
} }
void AirDisplay::drawDisplay() { void AirDisplay::drawDisplay() {
Paint_DrawIcon(0,8, ICON_POLUTION,&FontIcon, BLACK, WHITE); Paint_DrawIcon(0,8, ICON_POLUTION,&FontIcon, BLACK, WHITE);
Paint_DrawIntUnit(76,0,sensor->voci, "voci", &Font24, BLACK, WHITE); Paint_DrawIntUnit(76,0,sensor->voci, "voci", &Font24, BLACK, WHITE);
@ -137,12 +143,12 @@ 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);
} }
void LightDisplay::drawDisplay() { void LightDisplay::drawDisplay() {
Paint_DrawIcon(0,8, ICON_BULB,&FontIcon, BLACK, WHITE); //TODO BULB Paint_DrawIcon(0,8, ICON_BULB,&FontIcon, BLACK, WHITE); //TODO BULB
Paint_DrawFltUnit(76,0,sensor->light_lux, "lux", &Font24, BLACK, WHITE); Paint_DrawFltUnit(76,0,sensor->light_lux, "lux", &Font24, BLACK, WHITE);
@ -154,10 +160,10 @@ void LightDisplay::drawDisplay() {
} }
void MainDisplay::drawDisplay() { void MainDisplay::drawDisplay() {
DrawMain(true); DrawMain(true);
} }
void CustomDisplay::drawDisplay() { void CustomDisplay::drawDisplay() {
Paint_DrawString_EN(60,0,"CUSTOM", &Font24, WHITE, BLACK); Paint_DrawString_EN(60,0,"CUSTOM", &Font24, WHITE, BLACK);
} }

View File

@ -8,7 +8,7 @@
#include "../ntp/ntp.h" #include "../ntp/ntp.h"
#include "../owm/owm.h" #include "../owm/owm.h"
#include "../sensor/sensor.h" #include "../sensor/sensor.h"
#include <Arduino.h> #include <Arduino.h>
@ -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);
@ -33,51 +33,51 @@ class Display {
static void nextView(); static void nextView();
static void prevView(); static void prevView();
}; };
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

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

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,29 +17,29 @@ 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);
data <<= 1; data <<= 1;
digitalWrite(EPD_SCK_PIN, GPIO_PIN_SET); digitalWrite(EPD_SCK_PIN, GPIO_PIN_SET);
digitalWrite(EPD_SCK_PIN, GPIO_PIN_RESET); digitalWrite(EPD_SCK_PIN, GPIO_PIN_RESET);
} }
digitalWrite(EPD_CS_PIN, GPIO_PIN_SET); digitalWrite(EPD_CS_PIN, GPIO_PIN_SET);

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);

View File

@ -15,7 +15,7 @@
* V3.2(2020-07-23): * V3.2(2020-07-23):
* 1. Change: Paint_SetScale(uint8_t scale) * 1. Change: Paint_SetScale(uint8_t scale)
* Add scale 7 for 5.65f e-Parper * Add scale 7 for 5.65f e-Parper
* 2. Change: Paint_SetPixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color) * 2. Change: Paint_SetPixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color)
* Add the branch for scale 7 * Add the branch for scale 7
* 3. Change: Paint_Clear(uint16_t Color) * 3. Change: Paint_Clear(uint16_t Color)
* Add the branch for scale 7 * Add the branch for scale 7
@ -26,7 +26,7 @@
* 2. Add void Paint_SetScale(uint8_t scale); * 2. Add void Paint_SetScale(uint8_t scale);
* *
* V3.0(2019-04-18): * V3.0(2019-04-18):
* 1.Change: * 1.Change:
* Paint_DrawPoint(..., DOT_STYLE DOT_STYLE) * Paint_DrawPoint(..., DOT_STYLE DOT_STYLE)
* => Paint_DrawPoint(..., DOT_STYLE Dot_Style) * => Paint_DrawPoint(..., DOT_STYLE Dot_Style)
* Paint_DrawLine(..., LINE_STYLE Line_Style, DOT_PIXEL Dot_Pixel) * Paint_DrawLine(..., LINE_STYLE Line_Style, DOT_PIXEL Dot_Pixel)
@ -43,16 +43,16 @@
* 2.add: Paint_SelectImage() * 2.add: Paint_SelectImage()
* Select the picture to be drawn * Select the picture to be drawn
* 3.add: Paint_SetRotate() * 3.add: Paint_SetRotate()
* Set the direction of the cache * Set the direction of the cache
* 4.add: Paint_RotateImage() * 4.add: Paint_RotateImage()
* Can flip the picture, Support 0-360 degrees, * Can flip the picture, Support 0-360 degrees,
* but only 90.180.270 rotation is better * but only 90.180.270 rotation is better
* 4.add: Paint_SetMirroring() * 4.add: Paint_SetMirroring()
* Can Mirroring the picture, horizontal, vertical, origin * Can Mirroring the picture, horizontal, vertical, origin
* 5.add: Paint_DrawString_CN() * 5.add: Paint_DrawString_CN()
* Can display Chinese(GB1312) * Can display Chinese(GB1312)
* *
* ----------------------------------------------------------------------------- * -----------------------------------------------------------------------------
* V1.0(2018-07-17): * V1.0(2018-07-17):
* Create library * Create library
* *
@ -94,20 +94,20 @@ 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;
Paint.WidthMemory = Width; Paint.WidthMemory = Width;
Paint.HeightMemory = Height; Paint.HeightMemory = Height;
Paint.Color = Color; Paint.Color = Color;
Paint.Scale = 2; Paint.Scale = 2;
Paint.WidthByte = (Width % 8 == 0)? (Width / 8 ): (Width / 8 + 1); Paint.WidthByte = (Width % 8 == 0)? (Width / 8 ): (Width / 8 + 1);
Paint.HeightByte = Height; Paint.HeightByte = Height;
Paint.Rotate = Rotate; Paint.Rotate = Rotate;
Paint.Mirror = MIRROR_NONE; Paint.Mirror = MIRROR_NONE;
if(Rotate == ROTATE_0 || Rotate == ROTATE_180) { if(Rotate == ROTATE_0 || Rotate == ROTATE_180) {
Paint.Width = Width; Paint.Width = Width;
Paint.Height = Height; Paint.Height = Height;
@ -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,27 +145,27 @@ 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, \
MIRROR_VERTICAL or MIRROR_ORIGIN\r\n"); MIRROR_VERTICAL or MIRROR_ORIGIN\r\n");
} }
} }
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,16 +177,16 @@ 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;
} }
uint16_t X, Y; uint16_t X, Y;
switch(Paint.Rotate) { switch(Paint.Rotate) {
case 0: case 0:
X = Xpoint; X = Xpoint;
Y = Ypoint; Y = Ypoint;
break; break;
case 90: case 90:
X = Paint.WidthMemory - Ypoint - 1; X = Paint.WidthMemory - Ypoint - 1;
@ -203,7 +203,7 @@ void Paint_SetPixel(uint16_t Xpoint, uint16_t Ypoint, uint16_t Color){
default: default:
return; return;
} }
switch(Paint.Mirror) { switch(Paint.Mirror) {
case MIRROR_NONE: case MIRROR_NONE:
break; break;
@ -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) {
@ -558,7 +558,7 @@ void Paint_DrawChar(uint16_t Xpoint, uint16_t Ypoint, const char Acsii_Char,
for (Page = 0; Page < Font->Height; Page ++ ) { for (Page = 0; Page < Font->Height; Page ++ ) {
for (Column = 0; Column < Font->Width; Column ++ ) { for (Column = 0; Column < Font->Width; Column ++ ) {
if (FONT_BACKGROUND == Color_Background) { if (FONT_BACKGROUND == Color_Background) {
if (*ptr & (0x80 >> (Column % 8))) if (*ptr & (0x80 >> (Column % 8)))
Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground); Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground);
} else { } else {
@ -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) {
@ -589,7 +589,7 @@ void Paint_DrawIcon(uint16_t Xpoint, uint16_t Ypoint, const ICON_tpe icon,
for (Page = 0; Page < Font->Height; Page ++ ) { for (Page = 0; Page < Font->Height; Page ++ ) {
for (Column = 0; Column < Font->Width; Column ++ ) { for (Column = 0; Column < Font->Width; Column ++ ) {
if (FONT_BACKGROUND == Color_Background) { if (FONT_BACKGROUND == Color_Background) {
if (*ptr & (0x80 >> (Column % 8))) if (*ptr & (0x80 >> (Column % 8)))
Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground); Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground);
} else { } else {
@ -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;
@ -670,7 +670,7 @@ void Paint_DrawIntUnit(uint16_t Xpoint, uint16_t Ypoint, int32_t Number,const ch
while (Str_Array[Str_Bit] != '\0') { while (Str_Array[Str_Bit] != '\0') {
++Str_Bit; ++Str_Bit;
} }
while (pString[Unit_Bit] != '\0') { while (pString[Unit_Bit] != '\0') {
Str_Array[Str_Bit] = pString[Unit_Bit]; Str_Array[Str_Bit] = pString[Unit_Bit];
++Unit_Bit; ++Unit_Bit;
@ -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;
@ -693,7 +693,7 @@ void Paint_DrawFltUnit(uint16_t Xpoint, uint16_t Ypoint, float Number,const char
while (Str_Array[Str_Bit] != '\0') { while (Str_Array[Str_Bit] != '\0') {
++Str_Bit; ++Str_Bit;
} }
while (pString[Unit_Bit] != '\0') { while (pString[Unit_Bit] != '\0') {
Str_Array[Str_Bit] = pString[Unit_Bit]; Str_Array[Str_Bit] = pString[Unit_Bit];
++Unit_Bit; ++Unit_Bit;
@ -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);
} }

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@
#define __FONTS_H #define __FONTS_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
@ -48,11 +48,11 @@
//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;
extern sFONT Font45; extern sFONT Font45;
@ -66,27 +66,27 @@ 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;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* __FONTS_H */ #endif /* __FONTS_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -41,143 +41,143 @@ oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq\n\
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\n\ mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\n\
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n\ emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n\
-----END CERTIFICATE-----\n\ -----END CERTIFICATE-----\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

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;
}; };

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;

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;
@ -46,7 +46,7 @@ private:
String key; String key;
String httpGETRequest(const char* serverName) { String httpGETRequest(const char* serverName) {
HTTPClient http; HTTPClient http;
http.begin(serverName,root_ca); http.begin(serverName,root_ca);
int httpResponseCode = http.GET(); int httpResponseCode = http.GET();
String payload = "{}"; String payload = "{}";
@ -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\

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;
} }

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();

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;
} }

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();

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;
uint16_t sum = 0; if (data[0] != 0x42 || data[1] != 0x4d) return false;
for (uint8_t i = 0; i < 30; i++) sum += data[i];
uint16_t checksum = data[30]<<8 | data[31];
if (sum != checksum) return false;
return true; uint16_t sum = 0;
for (uint8_t i = 0; i < 30; i++) sum += data[i];
uint16_t checksum = data[30]<<8 | data[31];
if (sum != checksum) return false;
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;
} }

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();
@ -58,7 +58,7 @@ private:
static const uint8_t REG_Char1 = 0x00; // 0x42 static const uint8_t REG_Char1 = 0x00; // 0x42
static const uint8_t REG_Char2 = 0x01; // 0x4d static const uint8_t REG_Char2 = 0x01; // 0x4d
static const uint8_t REG_FrameH = 0x02; // Frame length = 2x13 + 2 static const uint8_t REG_FrameH = 0x02; // Frame length = 2x13 + 2
static const uint8_t REG_FrameL = 0x03; // -- static const uint8_t REG_FrameL = 0x03; // --
static const uint8_t REG_d1h = 0x04; // PM1.0 ug/m3 (standard) static const uint8_t REG_d1h = 0x04; // PM1.0 ug/m3 (standard)
static const uint8_t REG_d1l = 0x05; static const uint8_t REG_d1l = 0x05;
@ -72,17 +72,17 @@ private:
static const uint8_t REG_d5l = 0x0D; static const uint8_t REG_d5l = 0x0D;
static const uint8_t REG_d6h = 0x0E; // PM10 ug/m3 (atmospheric env) static const uint8_t REG_d6h = 0x0E; // PM10 ug/m3 (atmospheric env)
static const uint8_t REG_d6l = 0x0F; static const uint8_t REG_d6l = 0x0F;
static const uint8_t REG_d7h = 0x10; // >0.3um/0.1L static const uint8_t REG_d7h = 0x10; // >0.3um/0.1L
static const uint8_t REG_d7l = 0x11; static const uint8_t REG_d7l = 0x11;
static const uint8_t REG_d8h = 0x12; // >0.5um/0.1L static const uint8_t REG_d8h = 0x12; // >0.5um/0.1L
static const uint8_t REG_d8l = 0x13; static const uint8_t REG_d8l = 0x13;
static const uint8_t REG_d9h = 0x14; // >1.0um/0.1L static const uint8_t REG_d9h = 0x14; // >1.0um/0.1L
static const uint8_t REG_d9l = 0x15; static const uint8_t REG_d9l = 0x15;
static const uint8_t REG_d10h = 0x16; // >2.5um/0.1L static const uint8_t REG_d10h = 0x16; // >2.5um/0.1L
static const uint8_t REG_d10l = 0x17; static const uint8_t REG_d10l = 0x17;
static const uint8_t REG_d11h = 0x18; // >5.0um/0.1L static const uint8_t REG_d11h = 0x18; // >5.0um/0.1L
static const uint8_t REG_d11l = 0x19; static const uint8_t REG_d11l = 0x19;
static const uint8_t REG_d12h = 0x1A; // >10.0um/0.1L static const uint8_t REG_d12h = 0x1A; // >10.0um/0.1L
static const uint8_t REG_d12l = 0x1B; static const uint8_t REG_d12l = 0x1B;
static const uint8_t REG_VERSION = 0x1C; // Verion static const uint8_t REG_VERSION = 0x1C; // Verion

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);
@ -81,7 +81,7 @@ bool SGP40::ReadData(uint8_t data[SENSOR_DATA_LENGTH], float RH, float T){
uint16_t RH_ticks = (uint16_t)(RH * 65535 / 100); // Convert RH from %RH to ticks uint16_t RH_ticks = (uint16_t)(RH * 65535 / 100); // Convert RH from %RH to ticks
uint16_t T_ticks = (uint16_t)((T + 45) * 65535 / 175); // Convert T from DegC to ticks uint16_t T_ticks = (uint16_t)((T + 45) * 65535 / 175); // Convert T from DegC to ticks
i2c->beginTransmission(SGP40_ADDRESS); i2c->beginTransmission(SGP40_ADDRESS);
i2c->write(highByte(REG_MEASURE_RAW)); i2c->write(highByte(REG_MEASURE_RAW));
i2c->write(lowByte(REG_MEASURE_RAW)); i2c->write(lowByte(REG_MEASURE_RAW));
@ -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]; ReadData(data, RH, T);
int32_t voci = 0; uint16_t results = (data[0]<<8) | data[1];
VocAlgorithm_process(&vocAlgorithmParameters, results, &voci); int32_t voci = 0;
VocAlgorithm_process(&vocAlgorithmParameters, results, &voci);
return 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;
} }

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();
@ -46,7 +45,7 @@ private:
static const uint16_t REG_MEASURE_TEST = 0x280E; static const uint16_t REG_MEASURE_TEST = 0x280E;
static const uint16_t REG_HEATER_OFF = 0x3615; static const uint16_t REG_HEATER_OFF = 0x3615;
static const uint16_t RESET_ADDR = 0x0006; static const uint16_t RESET_ADDR = 0x0006;
static const uint16_t test_pass = 0xD400; static const uint16_t test_pass = 0xD400;
static const uint16_t test_fail = 0x4B00; static const uint16_t test_fail = 0x4B00;

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,70 +21,67 @@
/****************************************************************/ /****************************************************************/
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());
success &= ReadRegister(CHAN0_LOW,&data[0],2);
success &= ReadRegister(CHAN1_LOW,&data[2],2);
for (uint8_t d = 0; d <= integration; d++) // Wait x ms for ADC to complete
delay(120);
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);
return success; return success;
@ -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;
} }
} }

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();

View File

@ -12,7 +12,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015. Written: Dec 30 2015.
Last Updated: Dec 23 2017. Last Updated: Dec 23 2017.
This header must be included in any derived code or copies of the code. This header must be included in any derived code or copies of the code.
*/ */
#include "environment.h" #include "environment.h"
@ -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;
} }

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);
} }

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);
} }

View File

@ -15,15 +15,15 @@
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;
float pres = 0; float pres = 0;
float hum = 0; float hum = 0;
float heatidx = 0; float heatidx = 0;
float light = 0; float light = 0;
uint32_t uv = 0; uint32_t uv = 0;
uint32_t uvi = 0; uint32_t uvi = 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;

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))))));
} }
} }
} }

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;
}; };

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;
if(touch_num > 5) return -1;
if (touch_num <= 0) return touch_num;
error = !ReadRegister(GT1151_COORD_ADDR, data, sizeof(GTPoint) * touch_num); touch_num = regState & 0x0f;
if (error) return -1; if(touch_num > 5) return -1;
return touch_num; if (touch_num <= 0) return touch_num;
error = !ReadRegister(GT1151_COORD_ADDR, data, sizeof(GTPoint) * touch_num);
if (error) return -1;
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;
} }

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