PCB lives now in its own git repo https://git.la10cy.net/DeltaLima/CanGrow-12V-PCB
411 lines
9.6 KiB
C
411 lines
9.6 KiB
C
/*
|
|
*
|
|
* include/CanGrow.h - main header file
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
|
|
/* If you need detailed debug output, uncomment the following lines.
|
|
* DEBUG is less noisy messages
|
|
* DEBUG2 are noisy messages
|
|
* DEBUG3 are super noisy messages */
|
|
//#define DEBUG
|
|
//#define DEBUG2
|
|
//#define DEBUG3
|
|
|
|
/* ensure the code will also compile when CANGROW_VER and CANGROW_BUILD
|
|
* are not defined by the compiler arguments
|
|
* like -DCANGROW_VER="0.x-dev" or -DCANGROW_BUILD="commitid-core-timestamp"
|
|
*/
|
|
|
|
|
|
/*
|
|
*
|
|
*
|
|
* Constants
|
|
*
|
|
*
|
|
*/
|
|
|
|
#ifndef CANGROW_VER
|
|
#define CANGROW_VER "0.2-dev2"
|
|
#endif
|
|
#ifndef CANGROW_BUILD
|
|
#define CANGROW_BUILD "0420"
|
|
#endif
|
|
#ifndef CANGROW_BUILDTIME
|
|
#define CANGROW_BUILDTIME "1711922400" // 1.4.2024
|
|
#endif
|
|
|
|
#define CANGROW_DEFAULT_WIFI_SSID "CanGrow-unconfigured"
|
|
#define CANGROW_DEFAULT_WIFI_PASSWORD "letitgrow!"
|
|
|
|
#define CANGROW_CFG "/config.json"
|
|
#define TIME2FS "/time"
|
|
|
|
/* define Max limits for outputs and sensors */
|
|
const byte Max_Outputs = 16;
|
|
const byte Max_Sensors = 16;
|
|
/* How much values can a sensor contain at max */
|
|
const byte Max_Sensors_Read = 6;
|
|
/* how much GPIOs a Sensor can use */
|
|
const byte Max_Sensors_GPIO = 2;
|
|
|
|
|
|
/* actual structure initialization for GPIO_Index is done within the header files
|
|
* for ESP32 and ESP8266
|
|
*
|
|
* GPIO_Index.note explenation:
|
|
* 1 - BOOTFAILS_LOW: BootFails when LOW
|
|
* 2 - BOOTFAILS_HIGH: BootFails when HIGH
|
|
* 3 - FLASHMODE_LOW: FlashMode needs LOW to enter
|
|
* 4 - INPUT_ONLY: Input Only
|
|
* 5 - NO_PWM: No PWM output
|
|
* 6 - PWM_BOOT: PWM at boot time
|
|
* 7 - INT_ADC Pin for internal ADC (only ESP32, ESP8266 only has one Pin, A0)
|
|
*/
|
|
const byte BOOTFAILS_LOW = 1;
|
|
const byte BOOTFAILS_HIGH = 2;
|
|
const byte FLASHMODE_LOW = 3;
|
|
const byte INPUT_ONLY = 4;
|
|
const byte NO_PWM = 5;
|
|
const byte HIGH_BOOT = 6;
|
|
const byte INT_ADC = 7;
|
|
const byte INT_DAC = 8;
|
|
|
|
|
|
//const char signMessage[] PROGMEM = {"I AM PREDATOR, UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"};
|
|
|
|
|
|
const char BOOTFAILS_LOW_descr[] PROGMEM = {"BF_LOW"};
|
|
const char BOOTFAILS_HIGH_descr[] PROGMEM = {"BF_HIGH"};
|
|
const char FLASMODE_LOW_descr[] PROGMEM = {"FM_LOW"};
|
|
const char INPUT_ONLY_descr[] PROGMEM = {"IN_ONLY"};
|
|
const char NO_PWM_descr[] PROGMEM = {"NO_PWM"};
|
|
const char HIGH_BOOT_descr[] PROGMEM = {"B_HIGH"};
|
|
const char INT_ADC_descr[] PROGMEM = {"INT_ADC"};
|
|
const char INT_DAC_descr[] PROGMEM = {"INT_DAC"};
|
|
|
|
const char * GPIO_Index_note_descr[] = {
|
|
NULL, // 0 - no note
|
|
BOOTFAILS_LOW_descr, // 1
|
|
BOOTFAILS_HIGH_descr, // 2
|
|
FLASMODE_LOW_descr, // 3
|
|
INPUT_ONLY_descr, // 4
|
|
NO_PWM_descr, // 5
|
|
HIGH_BOOT_descr, // 6
|
|
INT_ADC_descr, // 7
|
|
INT_DAC_descr, // 8
|
|
};
|
|
|
|
|
|
/*
|
|
* RTCs available
|
|
*/
|
|
|
|
// 0 is unconfigured
|
|
const byte RTCs_total = 4;
|
|
|
|
const byte RTCs_DS1307 = 1;
|
|
const byte RTCs_DS3231 = 2;
|
|
const byte RTCs_PCF8523 = 3;
|
|
const byte RTCs_PCF8563 = 4;
|
|
|
|
const char RTCs_DS1307_descr[] PROGMEM = {"DS1307"};
|
|
const char RTCs_DS3231_descr[] PROGMEM = {"DS3231"};
|
|
const char RTCs_PCF8523_descr[] PROGMEM = {"PCF8523"};
|
|
const char RTCs_PCF8563_descr[] PROGMEM = {"PCF8563"};
|
|
|
|
const char * RTCs_descr[] = {
|
|
NULL, // unconfigured
|
|
RTCs_DS1307_descr,
|
|
RTCs_DS3231_descr,
|
|
RTCs_PCF8523_descr,
|
|
RTCs_PCF8563_descr,
|
|
};
|
|
|
|
|
|
/*
|
|
* Time scales
|
|
*/
|
|
|
|
// 0 is unconfigured
|
|
const byte TIMESCALE_total = 7;
|
|
|
|
const byte TIMESCALE_SECOND = 0;
|
|
const byte TIMESCALE_MINUTE = 1;
|
|
const byte TIMESCALE_HOUR = 2;
|
|
const byte TIMESCALE_DAY = 3;
|
|
const byte TIMESCALE_WEEK = 4;
|
|
const byte TIMESCALE_MONTH = 5;
|
|
const byte TIMESCALE_YEAR = 6;
|
|
|
|
|
|
const char TIMESCALE_SECOND_descr[] PROGMEM = {"Second"};
|
|
const char TIMESCALE_MINUTE_descr[] PROGMEM = {"Minute"};
|
|
const char TIMESCALE_HOUR_descr[] PROGMEM = {"Hour"};
|
|
const char TIMESCALE_DAY_descr[] PROGMEM = {"Day"};
|
|
const char TIMESCALE_WEEK_descr[] PROGMEM = {"Week"};
|
|
const char TIMESCALE_MONTH_descr[] PROGMEM = {"Month"};
|
|
const char TIMESCALE_YEAR_descr[] PROGMEM = {"Year"};
|
|
|
|
const char * Timescale_descr[] = {
|
|
TIMESCALE_SECOND_descr,
|
|
TIMESCALE_MINUTE_descr,
|
|
TIMESCALE_HOUR_descr,
|
|
TIMESCALE_DAY_descr,
|
|
TIMESCALE_WEEK_descr,
|
|
TIMESCALE_MONTH_descr,
|
|
TIMESCALE_YEAR_descr,
|
|
};
|
|
|
|
|
|
|
|
/* GPIO Index struct
|
|
* filled with CanGrow_ESP8266.h and CanGrow_ESP32.h
|
|
*/
|
|
|
|
struct GPIO_Index {
|
|
const byte gpio;
|
|
const byte note;
|
|
};
|
|
|
|
|
|
/*
|
|
*
|
|
* Config
|
|
*
|
|
* Note: when adding/removing/changing a saved Config variable
|
|
* you have to touch the config struct, LoadConfig() and SaveConfig() at least too!
|
|
*/
|
|
|
|
/*
|
|
* Config WiFi
|
|
*/
|
|
struct Config_WiFi {
|
|
char ssid[32];
|
|
char password[64];
|
|
bool dhcp;
|
|
byte ip[4] = {192,168,4,20};
|
|
byte netmask[4] = {255,255,255,0};
|
|
byte gateway[4] = {0,0,0,0};
|
|
byte dns[4] = {0,0,0,0};
|
|
};
|
|
|
|
|
|
/*
|
|
* Config System
|
|
*/
|
|
|
|
struct Config_System_Output {
|
|
|
|
/*
|
|
* Config System Output
|
|
*
|
|
* - type: output type like GPIO, I2C, URL
|
|
* 1 - GPIO
|
|
* 2 - I2C
|
|
* 3 - Web
|
|
* - device: what this output is connected to
|
|
* 1 - Light
|
|
* 2 - Fan
|
|
* 3 - Pump
|
|
* 4 - Humudifier
|
|
* 5 - Dehumidifier
|
|
* 6 - Heating
|
|
* - name: name of output
|
|
* - enabled: enable output
|
|
* - gpio: which gpio is used
|
|
* - invert: invert output
|
|
* - gpio_pwm: enable pwm for output
|
|
* - i2c:
|
|
* - webcall_host: ip to smart plug (tasmota e.g.)
|
|
* - webcall_path_on: GET request path to turn ON
|
|
* - webcall_path_off: GET request path to turn OFF
|
|
|
|
*
|
|
*/
|
|
byte type[Max_Outputs];
|
|
byte device[Max_Outputs];
|
|
char name[Max_Outputs][32];
|
|
bool enabled[Max_Outputs];
|
|
byte gpio[Max_Outputs];
|
|
bool gpio_pwm[Max_Outputs];
|
|
bool invert[Max_Outputs];
|
|
byte i2c_type[Max_Outputs];
|
|
byte i2c_addr[Max_Outputs];
|
|
byte i2c_port[Max_Outputs];
|
|
char webcall_host[Max_Outputs][32];
|
|
char webcall_path_on[Max_Outputs][32];
|
|
char webcall_path_off[Max_Outputs][32];
|
|
char webcall_user[Max_Outputs][32];
|
|
char webcall_password[Max_Outputs][32];
|
|
};
|
|
|
|
struct Config_System_Sensor {
|
|
/*
|
|
* Config System Sensor
|
|
* - type: Index ID of SensorIndex, which Sensor to use (ADC, BME280, Chirp, ...)
|
|
* - name: nice name
|
|
* - gpio[]: gpio to use for RPM reading, builtin ADC, OneWire, TwoWire
|
|
*/
|
|
|
|
byte type[Max_Sensors];
|
|
char name[Max_Sensors][32];
|
|
byte i2c_addr[Max_Sensors];
|
|
byte gpio[Max_Sensors][Max_Sensors_GPIO];
|
|
float offset[Max_Sensors][Max_Sensors_Read];
|
|
unsigned int low[Max_Sensors][Max_Sensors_Read];
|
|
unsigned int high[Max_Sensors][Max_Sensors_Read];
|
|
byte rawConvert[Max_Sensors][Max_Sensors_Read];
|
|
};
|
|
|
|
/* main System struct */
|
|
struct Config_System {
|
|
bool ntp = true;
|
|
byte rtc;
|
|
bool time2fs;
|
|
short ntpOffset;
|
|
unsigned short maintenanceDuration;
|
|
char esp32cam[16];
|
|
char httpUser[32];
|
|
char httpPass[32];
|
|
bool httpLogSerial;
|
|
unsigned short schedulerInterval = 1000;
|
|
unsigned short pwmFreq = 13370;
|
|
Config_System_Output output;
|
|
Config_System_Sensor sensor;
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
* Config Grow
|
|
*/
|
|
|
|
struct Config_Grow_Light {
|
|
bool configured[Max_Outputs];
|
|
byte output[Max_Outputs];
|
|
byte sunriseHourVeg[Max_Outputs];
|
|
byte sunriseMinuteVeg[Max_Outputs];
|
|
byte sunsetHourVeg[Max_Outputs];
|
|
byte sunsetMinuteVeg[Max_Outputs];
|
|
|
|
byte sunriseHourBloom[Max_Outputs];
|
|
byte sunriseMinuteBloom[Max_Outputs];
|
|
byte sunsetHourBloom[Max_Outputs];
|
|
byte sunsetMinuteBloom[Max_Outputs];
|
|
|
|
byte power[Max_Outputs];
|
|
bool fade[Max_Outputs];
|
|
byte fadeDuration[Max_Outputs];
|
|
};
|
|
|
|
struct Config_Grow_Air {
|
|
bool configured[Max_Outputs];
|
|
byte output[Max_Outputs];
|
|
byte power[Max_Sensors];
|
|
byte controlSensor[Max_Outputs];
|
|
byte controlRead[Max_Outputs];
|
|
byte controlMode[Max_Outputs];
|
|
float min[Max_Outputs];
|
|
float max[Max_Outputs];
|
|
};
|
|
|
|
struct Config_Grow_Water {
|
|
bool configured[Max_Outputs];
|
|
byte output[Max_Outputs];
|
|
byte controlSensor[Max_Outputs];
|
|
byte controlRead[Max_Outputs];
|
|
byte controlMode[Max_Outputs];
|
|
byte onTime[Max_Sensors];
|
|
byte min[Max_Sensors];
|
|
byte max[Max_Sensors];
|
|
byte interval[Max_Sensors];
|
|
byte intervalUnit[Max_Sensors];
|
|
};
|
|
|
|
struct Config_Grow_Dashboard {
|
|
bool configured[Max_Sensors][Max_Sensors_Read];
|
|
byte sensor[Max_Sensors][Max_Sensors_Read];
|
|
};
|
|
|
|
struct Config_Grow {
|
|
char name[64] = "CanGrow";
|
|
unsigned long start;
|
|
byte daysVeg = 42;
|
|
byte daysBloom = 69;
|
|
Config_Grow_Light light;
|
|
Config_Grow_Air air;
|
|
Config_Grow_Water water;
|
|
Config_Grow_Dashboard dashboard;
|
|
//unsigned short dayOfGrow;
|
|
//byte daysSeed;
|
|
|
|
//byte lightHoursVeg;
|
|
//byte lightHoursBloom;
|
|
//byte sunriseHour;
|
|
//byte sunriseMinute;
|
|
//bool sunFade;
|
|
//byte sunFadeDuration;
|
|
};
|
|
|
|
|
|
/*
|
|
* main Config struct
|
|
*/
|
|
struct Config {
|
|
char test[16] = "123";
|
|
Config_WiFi wifi;
|
|
Config_System system;
|
|
Config_Grow grow;
|
|
|
|
|
|
};
|
|
|
|
Config config;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
*
|
|
*
|
|
* Global Runtime variables
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
// do we need a restart? (e.g. after wifi settings change)
|
|
bool needRestart = false;
|
|
// this triggers Restart() from the main loop
|
|
bool doRestart = false;
|
|
// previous value of millis within the scheduler loop
|
|
unsigned long schedulerPrevMillis = 0;
|
|
/* in which time status is the system
|
|
* 0 - OK
|
|
* 1 - RTC fallback is used
|
|
* 2 - Time2FS fallback is used
|
|
*/
|
|
byte timeSrcStatus;
|
|
|
|
/* rtcError - false no Error, true had error while init */
|
|
bool rtcError = false;
|
|
// did ntp offset got changed?
|
|
bool updateNtpOffset = false;
|
|
/* sensorStatus[] to keep track if sensor init succeeded or not, true is OK */
|
|
bool sensorStatus[Max_Sensors];
|
|
/* outputStatus[] to keep track if output init succeeded or not, true is OK */
|
|
bool outputStatus[Max_Outputs];
|
|
/* outputState[] gets read by Output_Update() */
|
|
byte outputState[Max_Outputs];
|
|
/* keep track how often a http call failed */
|
|
byte outputWebcallFailed[Max_Outputs];
|
|
|
|
/* remember timestamp when pump was turned on to turn it off after config.grow.water.onTime */
|
|
unsigned long controlWaterLastStarted[Max_Outputs];
|
|
/* remember timestamp when last water cycle was done.*/
|
|
unsigned long controlWaterLast[Max_Outputs];
|