config TEMP_PIN
int "If using temperature, on which GPIO?"
default 4
+ depends on TEMP_ENABLED
help
Gets passed and used later for includes
config EEPY_DEVICE
Working on this
config LIGHT_SLEEP_ENABLED
bool "Actually go into light sleep between polls?"
+ depends on EEPY_DEVICE
default n
help
Not very well tested yet
help
Gets passed and used later for includes
-config CO2_ENABLED
+config CO2_PWM_ENABLED
+ bool "Fetch and report CO2 from PWM?"
+ default n
+
+config CO2_PWM_PIN
+ int "PWM RX pin for CO2"
+ depends on CO2_PWM_ENABLED
+ default 0
+
+config CO2_UART_ENABLED
bool "Fetch and report CO2 from UART?"
default n
help
config CO2_TX_PIN
int "UART TX pin for CO2"
default 22
+ depends on CO2_UART_ENABLED
help
Gets passed and used later for includes
config CO2_RX_PIN
int "UART RX pin for CO2"
default 25
+ depends on CO2_UART_ENABLED
help
Gets passed and used later for includes
-
-
-
config WIFI_ENABLED
bool "Are we using wifi association and MQTT"
default n
Gets passed and used later for includes
config MOTION_FIRST_PIN
int "If using motion, on which GPIO?"
+ depends on MOTION_FIRST_ENABLED
default 22
help
Gets passed and used later for includes
Gets passed and used later for includes
config MOTION_SECOND_PIN
int "If using motion, on which GPIO?"
+ depends on MOTION_SECOND_ENABLED
default 22
help
Gets passed and used later for includes
config PWM_TOPIC
string "Topic to listen on for PWM data"
default "esp32/pwm/default"
+ depends on PWM_ENABLED
config PWM_TARGET_PERCENT
int "Target percentage for PWM"
+ depends on PWM_ENABLED
default 50
config PWM_R1_GPIO
int "Red 1 GPIO LED, -1 for disabled"
+ depends on PWM_ENABLED
default -1
config PWM_G1_GPIO
int "Green 1 GPIO LED, -1 for disabled"
+ depends on PWM_ENABLED
default -1
config PWM_B1_GPIO
int "Blue 1 GPIO LED, -1 for disabled"
+ depends on PWM_ENABLED
default -1
config PWM_R2_GPIO
int "Red 2 GPIO LED, -1 for disabled"
+ depends on PWM_ENABLED
default -1
config PWM_G2_GPIO
int "Green 2 GPIO LED, -1 for disabled"
+ depends on PWM_ENABLED
default -1
config PWM_B2_GPIO
int "Blue 2 GPIO LED, -1 for disabled"
+ depends on PWM_ENABLED
default -1
uint16_t pm25;
float aqi;
#endif
-#ifdef CONFIG_CO2_ENABLED
+#if defined(CONFIG_CO2_UART_ENABLED) || defined(CONFIG_CO2_PWM_ENABLED)
int16_t co2_ppm;
#endif
#ifdef CONFIG_TEMP_ENABLED
} report_data_t;
// end report data
-
static temperature_sensor_handle_t temp_handle;
static QueueHandle_t event_queue;
static QueueHandle_t send_queue;
}
#endif
-#ifdef CONFIG_CO2_ENABLED
+#ifdef CONFIG_CO2_UART_ENABLED
// hardcoded given the co2 device we expect to find
void init_uart_co2(void) {
const uart_config_t uart_config = {
// we read the correct number of bytes in response, now need to parse and return
return co2_parse_sensor_data(co2_data);
}
+#endif // CONFIG_CO2_UART_ENABLED
-#endif
+#ifdef CONFIG_CO2_PWM_ENABLED
+static void co2_pwm_task(void* discard){
+ TickType_t xLastWakeTime;
+ const TickType_t xFrequency = pdMS_TO_TICKS(10); //1/portTICK_PERIOD_MS;
+
+ // Initialise the xLastWakeTime variable with the current time.
+ xLastWakeTime = xTaskGetTickCount();
+ int counter = 0;
+ int total_high = 0;
+ int total_low = 0;
+ int total_ppm = 0;
+ int level = 0;
+
+ //zero-initialize the config structure.
+ gpio_config_t io_conf = {};
+
+ // GPIO interrupt on either rising or falling edge
+ io_conf.intr_type = GPIO_INTR_DISABLE;
+ // bit mask of the pins, set to nothing at the start
+ io_conf.pin_bit_mask = 0;
+ io_conf.pin_bit_mask |= (1ULL << CONFIG_CO2_PWM_PIN );
+
+ //set as input mode
+ io_conf.mode = GPIO_MODE_INPUT;
+ // enable pull-down mode
+ io_conf.pull_down_en = 1;
+ io_conf.pull_up_en = 0;
+ // hysteresis separates the thresholds for high/low so we don't have a lot of toggling in between
+ io_conf.hys_ctrl_mode = GPIO_HYS_SOFT_ENABLE;
+ gpio_config(&io_conf);
+
+
+ // this will loop every 10 seconds and slur out a little less than 10 1004ms periods
+ // but that's okay, since we expect CO2 to mostly stay the same and anyway this will be an average of the cycle
+ // the _important_ bit is just to be consistent on delay, so using vTaskDelayUntil helps there
+ //
+ // see MH-Z19B datasheet for more details
+ for( ;; ){
+ // each period is 1004ms, so we'll just count up to that to keep the formula the same
+ if (counter > 1003){
+ // formula from the datasheet
+ total_ppm = (5000*(total_high-2))/(total_high+total_low-4);
+ // doesn't really matter when we start the counting loop, so just block until we have the semaphore
+ // (should only be unavailable if another task is updating, or more likely we're generating the report)
+ xSemaphoreTake(report_data.mutex, portMAX_DELAY);
+ report_data.co2_ppm = total_ppm;
+ xSemaphoreGive(report_data.mutex);
+
+ total_high = 0;
+ total_low = 0;
+ counter = 0;
+ }
+
+ // get the
+ level = gpio_get_level(CONFIG_CO2_PWM_PIN);
+
+ if (level == 1){
+ total_high += 1;
+ } else {
+ total_low += 1;
+ }
+
+ // Wait for the next cycle.
+ vTaskDelayUntil( &xLastWakeTime, xFrequency );
+ counter+=1;
+
+ // Perform action here.
+ }
+}
+
+#endif // CONFIG_CO2_PWM_ENABLED
// this task sends identifying information over mqtt, sleeps an hour, then repeats
cJSON_AddNumberToObject(root, "pm25", ((float)report_data.pm25/100));
cJSON_AddNumberToObject(root, "aqi", report_data.aqi);
#endif
-#ifdef CONFIG_CO2_ENABLED
+#if defined(CONFIG_CO2_UART_ENABLED) || defined(CONFIG_CO2_PWM_ENABLED)
+
// -1 is what we use for errors, 0 seems to be the device just isn't yet init
if (report_data.co2_ppm != -1 && report_data.co2_ppm != 0){
cJSON_AddNumberToObject(root, "co2", report_data.co2_ppm);
static void monitoring_task(void* discard)
{
-short temp_avg = 0;
#ifdef CONFIG_TEMP_ENABLED
+ short temp_avg = 0;
init_temp();
#endif
#ifdef CONFIG_AQI_ENABLED
- uint16_t set_pm10;
- uint16_t set_pm25;
float cur_aqi_pm25 = 0.0;
float cur_aqi_pm10 = 0.0;
int length = 0;
#endif
#endif // end AQI UART section
-#ifdef CONFIG_CO2_ENABLED
+#ifdef CONFIG_CO2_UART_ENABLED
int16_t co2_ppm = co2_read_sensor();
if (co2_ppm != -1 ){
xSemaphoreTake(report_data.mutex, portMAX_DELAY);
report_data.co2_ppm = co2_ppm;
xSemaphoreGive(report_data.mutex);
}
-
#endif // end CO2 UART section
- temp_avg = 0;
#ifdef CONFIG_TEMP_ENABLED
// Temperature fetch/calculation/report
temp_avg = new_temp_average(get_temp());
init_uart_aqi();
init_pmbuffer();
#endif
-#ifdef CONFIG_CO2_ENABLED
+#ifdef CONFIG_CO2_UART_ENABLED
init_uart_co2();
#endif
+#ifdef CONFIG_CO2_PWM_ENABLED
+ xTaskCreate(co2_pwm_task, "co2_pwm_task", 4096, NULL, 2, NULL);
+#endif
#ifdef CONFIG_TEMP_ENABLED
init_tempbuffer();
#endif