336 lines
9.6 KiB
Arduino
336 lines
9.6 KiB
Arduino
|
/* Includes ------------------------------------------------------------------*/
|
||
|
#include "env.h"
|
||
|
|
||
|
#include "src/epd/epd_cfg.h"
|
||
|
#include "src/epd/epd_driver.h"
|
||
|
#include "src/epd/epd_paint.h"
|
||
|
|
||
|
#include "src/ntpt/ntp.h"
|
||
|
#include "src/owm/owm.h"
|
||
|
|
||
|
#include "src/sensor/sensor.h"
|
||
|
#include "src/touch/gt1151.h"
|
||
|
|
||
|
#include "src/influxdb/influx.h"
|
||
|
|
||
|
#include <Arduino.h>
|
||
|
#include <Wire.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <WiFi.h>
|
||
|
#include <WiFiMulti.h>
|
||
|
|
||
|
#define PIN_SDA 18
|
||
|
#define PIN_SCL 23
|
||
|
|
||
|
|
||
|
/* Global Variables -----------------------------------------------------------*/
|
||
|
|
||
|
typedef enum {
|
||
|
VIEW_MAIN = 0,
|
||
|
VIEW_WEATHER, VIEW_WEATHER_ALT,
|
||
|
VIEW_TEMP, VIEW_AIR,
|
||
|
VIEW_CUSTOM,
|
||
|
|
||
|
VIEW_COUNT
|
||
|
} views_t;
|
||
|
|
||
|
static const uint8_t view_count = 5;
|
||
|
static uint8_t view_curr;
|
||
|
static const views_t view_tab[view_count] = {
|
||
|
VIEW_MAIN,
|
||
|
VIEW_WEATHER,VIEW_WEATHER_ALT,
|
||
|
VIEW_TEMP,VIEW_AIR
|
||
|
};
|
||
|
|
||
|
static WiFiMulti wifiMulti;
|
||
|
static TwoWire I2C = TwoWire(0);
|
||
|
static strDateTime dateTime = {0};
|
||
|
static Sensor* sensor = new Sensor(&I2C);
|
||
|
static GT1151* touch = new GT1151(&I2C);
|
||
|
static OWM* owm = new OWM(LOCATION, OPENWEATHER_API);
|
||
|
static OWM* owm_alt = new OWM(LOCATION_ALT, OPENWEATHER_API);
|
||
|
|
||
|
static Influx* iflx = new Influx(NULL, owm, owm_alt);//add sensor
|
||
|
|
||
|
static NTPtime NTPch(NTP_URL);
|
||
|
static bool time_update = false,
|
||
|
ntp_update = true,
|
||
|
weather_update = true,
|
||
|
sensor_update = true,
|
||
|
influx_w_update = true, influx_s_update = true,
|
||
|
view_update = true, view_refresh = false;
|
||
|
|
||
|
static bool shutdownt = false;
|
||
|
static int shutdownc = 0;
|
||
|
|
||
|
uint8_t *BlackImage;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* IRQ ------------------------------------------------------------------------*/
|
||
|
hw_timer_t * timer = NULL;
|
||
|
void IRAM_ATTR onSecondTimer() {
|
||
|
dateTime.second += 1;
|
||
|
if (dateTime.second == 60) {
|
||
|
dateTime.minute += 1;
|
||
|
dateTime.second = 0;
|
||
|
if (dateTime.minute == 60) {
|
||
|
dateTime.hour += 1;
|
||
|
dateTime.minute = 0;
|
||
|
if (dateTime.hour == 24) {
|
||
|
dateTime.hour = 0;
|
||
|
dateTime.minute = 0;
|
||
|
dateTime.second = 0;
|
||
|
}
|
||
|
ntp_update = true;
|
||
|
}
|
||
|
if(dateTime.minute % 5) weather_update = true;
|
||
|
if(dateTime.minute % 5) sensor_update = true;
|
||
|
|
||
|
if(dateTime.minute % 5) influx_w_update = true;
|
||
|
if(dateTime.minute % 5) influx_s_update = true;
|
||
|
view_update = true;
|
||
|
time_update = true;
|
||
|
|
||
|
}
|
||
|
if(touch->dev.holding) shutdownc++;
|
||
|
else shutdownc = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void IRAM_ATTR onTouch(int8_t contacts, GTPoint *points) {
|
||
|
if(touch->dev.holding) return;
|
||
|
Serial.printf("Contacts: %d\n", contacts);
|
||
|
for (uint8_t i = 0; i < contacts; i++) {
|
||
|
Serial.printf("C%d: #%d %d,%d s:%d\n", i, points[i].id, points[i].x, points[i].y, points[i].a);
|
||
|
yield();
|
||
|
}
|
||
|
if(points[0].x < 125) view_curr = (++view_curr % view_count);
|
||
|
else view_curr = (--view_curr % view_count);
|
||
|
view_update = true;
|
||
|
}
|
||
|
//x = 250 to 0
|
||
|
//y = ????
|
||
|
|
||
|
/* Setup Functions -----------------------------------------------------------*/
|
||
|
void setup_EPD(){
|
||
|
//START EPD
|
||
|
DEV_Module_Init();
|
||
|
EPD_2IN13_V2_Init(EPD_2IN13_V2_FULL);
|
||
|
EPD_2IN13_V2_Clear();
|
||
|
delay(100);
|
||
|
|
||
|
//EPD STORAGE
|
||
|
uint16_t Imagesize = ((EPD_2IN13_V2_WIDTH % 8 == 0) ? (EPD_2IN13_V2_WIDTH / 8 ) : (EPD_2IN13_V2_WIDTH / 8 + 1)) * EPD_2IN13_V2_HEIGHT;
|
||
|
if ((BlackImage = (uint8_t *)malloc(Imagesize)) == NULL) exit(1);
|
||
|
Paint_NewImage(BlackImage, EPD_2IN13_V2_WIDTH, EPD_2IN13_V2_HEIGHT, 270, WHITE);
|
||
|
Paint_SelectImage(BlackImage);
|
||
|
Paint_SetMirroring(MIRROR_HORIZONTAL);
|
||
|
Paint_Clear(WHITE);
|
||
|
|
||
|
Paint_DrawIcon(89,54, ICON_LOGO, &FontIcon, BLACK, WHITE);
|
||
|
Paint_DrawString_EN(29, 5, "Helcel", &Font45, WHITE, BLACK);
|
||
|
Paint_SelectImage(BlackImage);
|
||
|
EPD_2IN13_V2_Display(BlackImage);
|
||
|
delay(100);
|
||
|
}
|
||
|
|
||
|
void setup_EPD_END(){
|
||
|
Paint_Clear(WHITE);
|
||
|
EPD_2IN13_V2_Init(EPD_2IN13_V2_FULL);
|
||
|
EPD_2IN13_V2_DisplayPartBaseImage(BlackImage);
|
||
|
EPD_2IN13_V2_Init(EPD_2IN13_V2_PART);
|
||
|
Paint_SelectImage(BlackImage);
|
||
|
}
|
||
|
|
||
|
void setup_TOUCH() {
|
||
|
touch->setHandler(onTouch);
|
||
|
touch->begin();
|
||
|
}
|
||
|
|
||
|
void setup_WIFI(){
|
||
|
uint8_t tries = 3;
|
||
|
WIFI_REGISTER_AP(wifiMulti);
|
||
|
while (wifiMulti.run() == WL_CONNECTED && tries-- >0) delay(500);
|
||
|
}
|
||
|
|
||
|
void setup_TIMER(){
|
||
|
timer = timerBegin(0, 80, true);
|
||
|
timerAttachInterrupt(timer, &onSecondTimer, true);
|
||
|
timerAlarmWrite(timer, 1000000, true);
|
||
|
timerAlarmEnable(timer);
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Setup Functions --------------------------------------------------------------*/
|
||
|
void setup(){
|
||
|
Serial.begin(115200);
|
||
|
|
||
|
I2C.begin(PIN_SDA, PIN_SCL, 100000);
|
||
|
I2C.setPins(PIN_SDA,PIN_SCL);
|
||
|
setup_EPD();
|
||
|
setup_TOUCH();
|
||
|
setup_WIFI();
|
||
|
setup_TIMER();
|
||
|
|
||
|
iflx->check();
|
||
|
|
||
|
setup_EPD_END();
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Update Functions-------------------------------------------------------------*/
|
||
|
void updateNTP(){
|
||
|
if (!ntp_update) return;
|
||
|
if (wifiMulti.run() != WL_CONNECTED) return;
|
||
|
strDateTime nDateTime = NTPch.getNTPtime(1.0, 1);
|
||
|
if(nDateTime.valid){
|
||
|
dateTime = nDateTime;
|
||
|
time_update = true;
|
||
|
ntp_update = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void updateWeather(){
|
||
|
if (!weather_update) return;
|
||
|
if (wifiMulti.run() != WL_CONNECTED) return;
|
||
|
|
||
|
if(owm!= NULL && !owm->update()) return;
|
||
|
if(owm_alt!= NULL && !owm_alt->update()) return;
|
||
|
weather_update = false;
|
||
|
}
|
||
|
|
||
|
void updateTime(){
|
||
|
if (!time_update) return;
|
||
|
Paint_ClearWindows(170, EPD_2IN13_V2_WIDTH - Font24.Height, 170 + Font24.Width * 4.5, EPD_2IN13_V2_WIDTH, WHITE);
|
||
|
if (!dateTime.valid) return;
|
||
|
Paint_DrawTime(170, 98, &dateTime, &Font24, WHITE, BLACK);
|
||
|
EPD_2IN13_V2_DisplayPart(BlackImage);
|
||
|
time_update = false;
|
||
|
}
|
||
|
|
||
|
void updateSensor(){
|
||
|
if (!sensor_update) return;
|
||
|
sensor->measure();
|
||
|
sensor_update = false;
|
||
|
}
|
||
|
|
||
|
ICON_tpe getWeatherIcon(int id){
|
||
|
if(id>=200 && id<300){ //Thunder
|
||
|
return ICON_CLOUD_THUNDER;
|
||
|
}else if(id>=300 && id<400){//Drizzle
|
||
|
return ICON_CLOUD_RAIN;
|
||
|
}else if(id>=500 && id<600){//Rain
|
||
|
return ICON_CLOUD_RAIN;
|
||
|
}else if(id>=600 && id<700){//Snow
|
||
|
return ICON_CLOUD_SNOW;
|
||
|
}else if(id>=700 && id<800){//Warning
|
||
|
return ICON_WARN;
|
||
|
}else if(id>=800 && id<900){//Clear & Cloudy
|
||
|
if(id==800) return ICON_SUN;
|
||
|
else if(id==801) return ICON_CLOUD_SUN;
|
||
|
else return ICON_CLOUD;
|
||
|
}else{
|
||
|
return ICON_WARN;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void refreshDisplay(){
|
||
|
Paint_Clear(WHITE);
|
||
|
EPD_2IN13_V2_Init(EPD_2IN13_V2_FULL);
|
||
|
EPD_2IN13_V2_DisplayPartBaseImage(BlackImage);
|
||
|
EPD_2IN13_V2_Init(EPD_2IN13_V2_PART);
|
||
|
Paint_SelectImage(BlackImage);
|
||
|
}
|
||
|
|
||
|
void updateDisplay(){
|
||
|
// forceRefresh();
|
||
|
if (!view_update) return;
|
||
|
if (view_refresh) refreshDisplay();
|
||
|
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);
|
||
|
switch(view_tab[view_curr]){
|
||
|
case VIEW_MAIN:
|
||
|
Paint_DrawIcon(0,0, ICON_LOGO,&FontIcon, BLACK, WHITE);
|
||
|
Paint_DrawString_EN(60,0,"MAIN", &Font24, WHITE, BLACK);
|
||
|
Paint_DrawIntUnit(0,30, 69,"", &Font24, BLACK, WHITE);
|
||
|
break;
|
||
|
case VIEW_WEATHER_ALT:
|
||
|
case VIEW_WEATHER:
|
||
|
{
|
||
|
OWM* cowm = (view_tab[view_curr]==VIEW_WEATHER)?owm:owm_alt;
|
||
|
if(!cowm->valid_weather) break;
|
||
|
JsonObject weather_0 = cowm->weather["weather"][0];
|
||
|
JsonObject weather_main = cowm->weather["main"];
|
||
|
JsonObject weather_wind = cowm->weather["wind"];
|
||
|
JsonObject weather_sys = cowm->weather["sys"];
|
||
|
if(!weather_0 || !weather_main || !weather_sys || !weather_wind) break;
|
||
|
Paint_DrawIcon(0,8, getWeatherIcon(weather_0["id"]), &FontIcon, BLACK, WHITE);
|
||
|
Paint_DrawString_EN(2,EPD_2IN13_V2_WIDTH - 4 - Font16.Height,weather_0["description"], &Font16, WHITE, BLACK);
|
||
|
Paint_DrawFltUnit(76,0,weather_main["temp"], "C", &Font24, BLACK, WHITE);
|
||
|
Paint_DrawFltUnit(186,6,weather_main["feels_like"], "C", &Font12, BLACK, WHITE);
|
||
|
Paint_DrawIntUnit(76,24,weather_main["pressure"], "hPa", &Font24, BLACK, WHITE);
|
||
|
Paint_DrawIntUnit(76,48,weather_main["humidity"], "%", &Font24, BLACK, WHITE);
|
||
|
Paint_DrawFltUnit(76,72,weather_wind["speed"], "m/s", &Font24, BLACK, WHITE);
|
||
|
strDateTime sunrisedt = NTPtime::ConvertUnixTimestamp(NTPtime::adjustTimeZone(weather_sys["sunrise"], 1.0, 1));
|
||
|
strDateTime sunsetdt = NTPtime::ConvertUnixTimestamp(NTPtime::adjustTimeZone(weather_sys["sunset"], 1.0, 1));
|
||
|
Paint_DrawTime(20, 6, &sunrisedt, &Font12, WHITE, BLACK);
|
||
|
Paint_DrawTime(20, 76, &sunsetdt, &Font12, WHITE, BLACK);
|
||
|
}
|
||
|
break;
|
||
|
case VIEW_TEMP:
|
||
|
Paint_DrawIcon(0,Font24.Height, ICON_TEMPERATURE,&FontIcon, BLACK, WHITE);
|
||
|
Paint_DrawString_EN(2,0,"Temp", &Font24, WHITE, BLACK);
|
||
|
Paint_DrawFltUnit(76,0,sensor->heatidx, "C", &Font24, BLACK, WHITE);
|
||
|
Paint_DrawFltUnit(76,36,sensor->temp, "C", &Font24, BLACK, WHITE);
|
||
|
Paint_DrawFltUnit(160,36,sensor->hum, "%", &Font24, BLACK, WHITE);
|
||
|
Paint_DrawFltUnit(76,64,sensor->pres, "hPa", &Font24, BLACK, WHITE);
|
||
|
break;
|
||
|
case VIEW_AIR:
|
||
|
Paint_DrawIcon(0,Font24.Height, ICON_POLUTION,&FontIcon, BLACK, WHITE);
|
||
|
Paint_DrawString_EN(2,0,"Air", &Font24, WHITE, BLACK);
|
||
|
Paint_DrawIntUnit(150,10, 69,"", &Font24, BLACK, WHITE);
|
||
|
break;
|
||
|
case VIEW_CUSTOM:
|
||
|
Paint_DrawString_EN(60,0,"CUSTOM", &Font24, WHITE, BLACK);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
EPD_2IN13_V2_DisplayPart(BlackImage);
|
||
|
view_update = false;
|
||
|
}
|
||
|
|
||
|
void updateInflux(){
|
||
|
if(wifiMulti.run() != WL_CONNECTED) return;
|
||
|
iflx->record(influx_w_update, influx_s_update);
|
||
|
influx_w_update = false;
|
||
|
influx_s_update = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* The main loop -------------------------------------------------------------*/
|
||
|
void loop(){
|
||
|
if(shutdownc >= 10){
|
||
|
refreshDisplay();
|
||
|
EPD_2IN13_V2_Sleep();
|
||
|
esp_deep_sleep_start();
|
||
|
}
|
||
|
|
||
|
updateNTP();
|
||
|
updateWeather();
|
||
|
updateSensor();
|
||
|
updateInflux();
|
||
|
|
||
|
touch->update();
|
||
|
updateDisplay();
|
||
|
updateTime();
|
||
|
delay(50);
|
||
|
if(!touch->dev.holding) shutdownc = 0;
|
||
|
|
||
|
|
||
|
}
|