# HG changeset patch # User Michiel Broek # Date 1572474106 -3600 # Node ID e38ffa806e844e41060719525ba27546db81aa47 # Parent 83314e7b1b4aa75c1c085f73a4003ee76a3e5970 Initial code for the rotary switch and some menus. Changed default pushbutton pin from 12 to 14 and swapped the rotary pins. Disabled always create a new units file, it should be safe to keep it now. diff -r 83314e7b1b4a -r e38ffa806e84 main/Kconfig.projbuild --- a/main/Kconfig.projbuild Sat Oct 26 14:05:17 2019 +0200 +++ b/main/Kconfig.projbuild Wed Oct 30 23:21:46 2019 +0100 @@ -64,7 +64,7 @@ config ROT_ENC_SW_GPIO int "Rotary Encoder push switch GPIO number" range 0 39 - default 12 + default 14 help GPIO number (IOxx) from which to sample the Rotary Push function output and to wakeup the ESP from deep sleep. diff -r 83314e7b1b4a -r e38ffa806e84 main/co2meter.c --- a/main/co2meter.c Sat Oct 26 14:05:17 2019 +0200 +++ b/main/co2meter.c Wed Oct 30 23:21:46 2019 +0100 @@ -11,15 +11,14 @@ #define ROT_ENC_A_GPIO (CONFIG_ROT_ENC_A_GPIO) #define ROT_ENC_B_GPIO (CONFIG_ROT_ENC_B_GPIO) #define ROT_ENC_SW_GPIO (CONFIG_ROT_ENC_SW_GPIO) +#define INACTIVITY 480 ///< Time in 250 mSec units. + +#define RESET_AT 0 ///< Set to a positive non-zero number to reset the position if this value is exceeded -#define ENABLE_HALF_STEPS false ///< Set to true to enable tracking of rotary encoder at half step resolution -#define RESET_AT 0 ///< Set to a positive non-zero number to reset the position if this value is exceeded -#define FLIP_DIRECTION false ///< Set to true to reverse the clockwise/counterclockwise sense - - -int Main_Loop1 = MAIN_LOOP1_INIT; ///< Loop 1 init +int Main_Loop1 = ML1_INIT; ///< Loop 1 init int Main_Loop2 = -1; ///< Loop 2 invalid +int New_Loop2 = ML2_DONE; ///< Loop 2 new state bool System_TimeOk = false; ///< System time status time_t now; ///< Current time struct tm timeinfo; ///< Current time structure @@ -29,9 +28,10 @@ static TaskHandle_t xTaskADC = NULL; static TaskHandle_t xTaskWifi = NULL; static TaskHandle_t xTaskMQTT = NULL; -const esp_app_desc_t *app_desc = NULL; -u8g2_t u8g2; ///< A structure which will contain all the data for one display - +const esp_app_desc_t *app_desc = NULL; ///< Application description +u8g2_t u8g2; ///< A structure which will contain all the data for one display +rotary_encoder_info_t rinfo = { 0 }; ///< Rotary encoder record +static int PushDuration = 0; ///< Duration of the pushed button extern unit_t units[3]; ///< Pressure test units extern SemaphoreHandle_t xSemaphoreUnits; ///< Units lock semaphore @@ -39,12 +39,16 @@ extern SemaphoreHandle_t xSemaphoreDS18B20; ///< DS18B20 lock semaphore extern ADC_State *adc_state; ///< ADC state extern SemaphoreHandle_t xSemaphoreADC; ///< ADC lock semaphore -extern int count_pub; +extern int count_pub; ///< Published MQTT messages in transit +static xQueueHandle gpio_evt_queue = NULL; ///< Rotary pushbutton queue +static int usertimer = 0; ///< User inactive timeout -void screen_main(float t, float p1, float p2, float p3) + +void screen_main() { char buf[65]; + int i; u8g2_ClearBuffer(&u8g2); u8g2_DrawHLine(&u8g2, 0, 14, 128); @@ -53,26 +57,99 @@ u8g2_uint_t w = u8g2_GetStrWidth(&u8g2, buf); u8g2_DrawStr(&u8g2, (128 - w) / 2,12, buf); - u8g2_SetFont(&u8g2, u8g2_font_t0_22b_tf); - sprintf(buf, "%.1f °C", t); - w = u8g2_GetUTF8Width(&u8g2, buf); - u8g2_DrawUTF8(&u8g2, (128 - w) / 2,40, buf); - u8g2_SetFont(&u8g2, u8g2_font_t0_18b_tf); + if (xSemaphoreTake(xSemaphoreUnits, 25) == pdTRUE) { + + u8g2_SetFont(&u8g2, u8g2_font_t0_22b_tf); + sprintf(buf, "%.1f °C", units[0].temperature / 1000.0); + w = u8g2_GetUTF8Width(&u8g2, buf); + u8g2_DrawUTF8(&u8g2, (128 - w) / 2,40, buf); + u8g2_SetFont(&u8g2, u8g2_font_t0_18b_tf); + + for (i = 0; i < 3; i++) { + sprintf(buf, "%.1f", units[i].pressure / 1000.0); + w = u8g2_GetUTF8Width(&u8g2, buf); + u8g2_DrawUTF8(&u8g2, ((42 - w) / 2) + i * 43,63, buf); + } + xSemaphoreGive(xSemaphoreUnits); + } + u8g2_SendBuffer(&u8g2); + u8g2_SetPowerSave(&u8g2, 0); // wake up display +} + + + +void screen_unit(int no) +{ + char buf[65]; + + u8g2_ClearBuffer(&u8g2); + u8g2_DrawHLine(&u8g2, 0, 14, 128); + u8g2_SetFont(&u8g2, u8g2_font_t0_15_tr); + sprintf(buf, "Unit %d", no + 1); + u8g2_uint_t w = u8g2_GetStrWidth(&u8g2, buf); + u8g2_DrawStr(&u8g2, (128 - w) / 2,12, buf); + + if (xSemaphoreTake(xSemaphoreUnits, 25) == pdTRUE) { + + u8g2_SetFont(&u8g2, u8g2_font_t0_22b_tf); + sprintf(buf, "%.1f °C", units[no].temperature / 1000.0); + w = u8g2_GetUTF8Width(&u8g2, buf); + u8g2_DrawUTF8(&u8g2, (128 - w) / 2,40, buf); +// u8g2_SetFont(&u8g2, u8g2_font_t0_18b_tf); + + sprintf(buf, "%.2f bar", units[no].pressure / 1000.0); + w = u8g2_GetUTF8Width(&u8g2, buf); + u8g2_DrawUTF8(&u8g2, (128 - w) / 2,63, buf); - sprintf(buf, "%.1f", p1); - w = u8g2_GetUTF8Width(&u8g2, buf); - u8g2_DrawUTF8(&u8g2, ((42 - w) / 2),63, buf); + xSemaphoreGive(xSemaphoreUnits); + } + u8g2_SendBuffer(&u8g2); + u8g2_SetPowerSave(&u8g2, 0); // wake up display +} + + + +void screen_unit_setup(int no, int sub) +{ + char buf[65]; + + u8g2_ClearBuffer(&u8g2); + u8g2_DrawHLine(&u8g2, 0, 14, 128); + u8g2_SetFont(&u8g2, u8g2_font_t0_15_tr); + sprintf(buf, "Unit %d setup", no + 1); + u8g2_uint_t w = u8g2_GetStrWidth(&u8g2, buf); + u8g2_DrawStr(&u8g2, (128 - w) / 2,12, buf); - sprintf(buf, "%.1f", p2); - w = u8g2_GetUTF8Width(&u8g2, buf); - u8g2_DrawUTF8(&u8g2, ((42 - w) / 2) + 43,63, buf); + if (sub == 0) + u8g2_SetFont(&u8g2, u8g2_font_t0_15b_tr); + else + u8g2_SetFont(&u8g2, u8g2_font_t0_15_tr); + sprintf(buf, "Mode %s", units[no].mode ? "ON":"OFF"); + u8g2_DrawStr(&u8g2,2,28, buf); + + if (sub == 1) + u8g2_SetFont(&u8g2, u8g2_font_t0_15b_tr); + else + u8g2_SetFont(&u8g2, u8g2_font_t0_15_tr); + sprintf(buf, "Calibrate"); + u8g2_DrawStr(&u8g2,2,40, buf); - sprintf(buf, "%.1f", p3); - w = u8g2_GetUTF8Width(&u8g2, buf); - u8g2_DrawUTF8(&u8g2, ((42 - w) / 2) + 86,63, buf); + if (sub == 2) + u8g2_SetFont(&u8g2, u8g2_font_t0_15b_tr); + else + u8g2_SetFont(&u8g2, u8g2_font_t0_15_tr); + sprintf(buf, "T.sensor "); + u8g2_DrawStr(&u8g2,2,52, buf); + + if (sub == 3) + u8g2_SetFont(&u8g2, u8g2_font_t0_15b_tr); + else + u8g2_SetFont(&u8g2, u8g2_font_t0_15_tr); + sprintf(buf, "Return"); + u8g2_DrawStr(&u8g2,2,64, buf); u8g2_SendBuffer(&u8g2); - u8g2_SetPowerSave(&u8g2, 0); // wake up display + u8g2_SetPowerSave(&u8g2, 0); } @@ -84,32 +161,78 @@ u8g2_DrawStr(&u8g2,2,24,e2); u8g2_SendBuffer(&u8g2); u8g2_SetPowerSave(&u8g2, 0); +} + + +/* + * Interrupt service routine for the rotary pushbutton. + */ +static void IRAM_ATTR gpio_isr_handler(void* arg) +{ + uint32_t gpio_num = (uint32_t) arg; + xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); } +/* + * GPIO queue task. See if there is a rotary pushbutton event in the queue. + */ +static void gpio_task(void* arg) +{ + uint32_t io_num; + static int64_t pushed = 0; + + for(;;) { + if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { + if (io_num == ROT_ENC_SW_GPIO) { + if (gpio_get_level(io_num) == 0) { + pushed = esp_timer_get_time(); + PushDuration = 0; + } else if (gpio_get_level(io_num) == 1) { + PushDuration = (esp_timer_get_time() - pushed) / 1000; + ESP_LOGI(TAG, "GPIO rotary button intr, val: %d time: %d", gpio_get_level(io_num), PushDuration); + } + } else { + ESP_LOGE(TAG, "GPIO[%d] unknown intr, val: %d", io_num, gpio_get_level(io_num)); + } + usertimer = INACTIVITY; + } + } +} + + + +/* + * Select new menu number on a postitive or negative rotary position. + * Then reset the rotary position. + */ +static void rotate_to_menu(rotary_encoder_position_t pos, int next_menu, int prev_menu) +{ + if (pos > 0) + New_Loop2 = next_menu; + else if (pos < 0) + New_Loop2 = prev_menu; + ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo)); +} + + void app_main() { struct timeval now; gettimeofday(&now, NULL); int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000; - int New_Loop2 = MAIN_LOOP2_INIT; esp_err_t ret; - Main_Loop1 = MAIN_LOOP1_INIT; + Main_Loop1 = ML1_INIT; Main_Loop2 = -1; switch (esp_sleep_get_wakeup_cause()) { case ESP_SLEEP_WAKEUP_EXT1: { - uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status(); - if (wakeup_pin_mask != 0) { - int pin = __builtin_ffsll(wakeup_pin_mask) - 1; - printf("Wake up from GPIO %d\n", pin); - } else { - printf("Wake up from GPIO\n"); - } + ESP_LOGI(TAG, "Starting from deep sleep, Rotary switch pressed"); + New_Loop2 = ML2_INIT; break; } case ESP_SLEEP_WAKEUP_TIMER: { @@ -124,12 +247,10 @@ const int wakeup_time_sec = 55; ESP_LOGI(TAG, "Enabling timer wakeup, %ds", wakeup_time_sec); esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000); + const uint64_t ext_wakeup_pin_1_mask = 1ULL << ROT_ENC_SW_GPIO; -// const int ext_wakeup_pin_1 = ROT_ENC_SW_GPIO; // 25 in example, redefine to rotary name. -// const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1; - -// printf("Enabling EXT1 wakeup on pins GPIO%d\n", ext_wakeup_pin_1); -// esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask, ESP_EXT1_WAKEUP_ANY_HIGH); // TODO: what is the logic of the rotary button. + ESP_LOGI(TAG, "Enabling EXT1 wakeup on pin GPIO%d", ROT_ENC_SW_GPIO); + esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask, ESP_EXT1_WAKEUP_ALL_LOW); // Isolate GPIO12 pin from external circuits. This is needed for modules // which have an external pull-up resistor on GPIO12 (such as ESP32-WROVER) @@ -159,7 +280,6 @@ u8g2_Setup_sh1106_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8g2_esp32_i2c_byte_cb, u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure u8x8_SetI2CAddress(&u8g2.u8x8, 0x78); - ESP_LOGI(TAG, "u8g2_InitDisplay"); u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this, /* @@ -248,18 +368,24 @@ * installed before calling rotary_encoder_register() */ ESP_ERROR_CHECK(gpio_install_isr_service(0)); - rotary_encoder_info_t rinfo = { 0 }; ESP_ERROR_CHECK(rotary_encoder_init(&rinfo, ROT_ENC_A_GPIO, ROT_ENC_B_GPIO)); -// ESP_ERROR_CHECK(rotary_encoder_enable_half_steps(&rinfo, ENABLE_HALF_STEPS)); -#ifdef FLIP_DIRECTION -// ESP_ERROR_CHECK(rotary_encoder_flip_direction(&rinfo)); -#endif + ESP_ERROR_CHECK(rotary_encoder_enable_half_steps(&rinfo, false)); + + gpio_config_t io_conf; + io_conf.intr_type = GPIO_PIN_INTR_ANYEDGE; + io_conf.pin_bit_mask = (1ULL << ROT_ENC_SW_GPIO); + io_conf.mode = GPIO_MODE_INPUT; + gpio_config(&io_conf); + + gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t)); + xTaskCreate(gpio_task, "gpio_task", 2048, NULL, 10, NULL); + + gpio_isr_handler_add(ROT_ENC_SW_GPIO, gpio_isr_handler, (void*) ROT_ENC_SW_GPIO); // Create a queue for events from the rotary encoder driver. // Tasks can read from this queue to receive up to date position information. -// QueueHandle_t event_queue = rotary_encoder_create_queue(); -// ESP_ERROR_CHECK(rotary_encoder_set_queue(&rinfo, event_queue)); - + QueueHandle_t event_queue = rotary_encoder_create_queue(); + ESP_ERROR_CHECK(rotary_encoder_set_queue(&rinfo, event_queue)); /* * Main application loop. @@ -267,35 +393,36 @@ while (1) { ESP_LOGI(TAG, "Entered app loop"); + rotary_encoder_event_t event = { 0 }; + int sub = 0; /* Measure process or user input via rotary switch */ while (1) { switch (Main_Loop1) { - case MAIN_LOOP1_INIT: + case ML1_INIT: ESP_LOGI(TAG, "Loop timer: Init"); - // If configured do MAIN_LOOP1_CONNECT - Main_Loop1 = MAIN_LOOP1_CONNECT; + // If configured do ML1_CONNECT + Main_Loop1 = ML1_CONNECT; requestWiFi_system(true); request_ds18b20(); request_adc(); break; - case MAIN_LOOP1_CONNECT: + case ML1_CONNECT: if (ready_WiFi()) - Main_Loop1 = MAIN_LOOP1_MQTT_CONNECT; + Main_Loop1 = ML1_MQTT_CONNECT; break; - case MAIN_LOOP1_MQTT_CONNECT: + case ML1_MQTT_CONNECT: if (ready_ds18b20() && ready_adc()) { connect_mqtt(true); - Main_Loop1 = MAIN_LOOP1_WAITCON; + Main_Loop1 = ML1_WAITCON; ESP_LOGI(TAG, "Loop timer: Wait MQTT"); /* Get global temperature, use for all units. */ uint32_t temp = 0; int state = 0; char rom_code[17]; - float t = 0, p1, p2, p3; if (xSemaphoreTake(xSemaphoreDS18B20, 10) == pdTRUE) { temp = (ds18b20_state->sensor[0].temperature * 1000); state = (ds18b20_state->sensor[0].error == 0) ? 0:1; @@ -303,13 +430,10 @@ rom_code[16] = '\0'; xSemaphoreGive(xSemaphoreDS18B20); } - t = temp / 1000.0; /* Copy measured data and calculate results */ if (xSemaphoreTake(xSemaphoreUnits, 25) == pdTRUE) { for (int i = 0; i < 3; i++) { - if (i == 0) - units[i].mode = 1; units[i].temperature = temp; units[i].temperature_state = state; units[i].alarm = 0; @@ -327,12 +451,6 @@ if (P < 0) P = 0; units[i].pressure = P; - if (i == 0) - p1 = P / 1000.0; - else if (i == 1) - p2 = P / 1000.0; - else if (i == 2) - p3 = P / 1000.0; printf("%d volt: %d batt: %d scale: %d bar: %d\n", i, units[i].pressure_voltage, adc_state->Batt_voltage, units[i].pressure_voltage / (adc_state->Batt_voltage / 1000) - units[i].pressure_zero, P); // Moet die echt op 5 volt? @@ -343,51 +461,56 @@ } write_units(); xSemaphoreGive(xSemaphoreUnits); - screen_main(t, p1, p2, p3); + switch (Main_Loop2) { + case ML2_USER: screen_main(); break; + case ML2_UNIT1: screen_unit(0); break; + case ML2_UNIT2: screen_unit(1); break; + case ML2_UNIT3: screen_unit(2); break; + } } } break; - case MAIN_LOOP1_WAITCON: + case ML1_WAITCON: if (ready_mqtt()) - Main_Loop1 = MAIN_LOOP1_SEND; + Main_Loop1 = ML1_SEND; break; - case MAIN_LOOP1_SEND: + case ML1_SEND: ESP_LOGI(TAG, "Loop timer: Send MQTT"); publishNode(); publishUnits(); publishLogs(); - Main_Loop1 = MAIN_LOOP1_WAITACK; + Main_Loop1 = ML1_WAITACK; break; - case MAIN_LOOP1_WAITACK: + case ML1_WAITACK: if (count_pub == 0) // Wait until all published messages are sent. - Main_Loop1 = MAIN_LOOP1_MQTT_DISCONNECT; + Main_Loop1 = ML1_MQTT_DISCONNECT; break; - case MAIN_LOOP1_MQTT_DISCONNECT: + case ML1_MQTT_DISCONNECT: ESP_LOGI(TAG, "Loop timer: Disconnect MQTT"); connect_mqtt(false); // Doesn't really disconnect. - Main_Loop1 = MAIN_LOOP1_DISCONNECT; + Main_Loop1 = ML1_DISCONNECT; break; - case MAIN_LOOP1_DISCONNECT: + case ML1_DISCONNECT: if (! ready_mqtt()) { ESP_LOGI(TAG, "Loop timer: WiFi off"); requestWiFi_system(false); - Main_Loop1 = MAIN_LOOP1_WIFI_OFF; + Main_Loop1 = ML1_WIFI_OFF; } break; - case MAIN_LOOP1_WIFI_OFF: + case ML1_WIFI_OFF: if (! ready_WiFi()) { ESP_LOGI(TAG, "Loop timer: Done"); - Main_Loop1 = MAIN_LOOP1_DONE; + Main_Loop1 = ML1_DONE; } break; - case MAIN_LOOP1_DONE: + case ML1_DONE: break; } @@ -399,17 +522,54 @@ Main_Loop2 = New_Loop2; switch (Main_Loop2) { - case MAIN_LOOP2_INIT: + case ML2_INIT: ESP_LOGI(TAG, "Loop user: Init"); // u8g2_SetPowerSave(&u8g2, 0); // wake up display // u8g2_ClearBuffer(&u8g2); -// New_Loop2 = MAIN_LOOP2_INACTIVE; - New_Loop2 = MAIN_LOOP2_DONE; + New_Loop2 = ML2_USER; + usertimer = INACTIVITY; + break; + + case ML2_USER: + ESP_LOGI(TAG, "Loop user: User mainmenu"); + screen_main(); + break; + + case ML2_UNIT1: + case ML2_UNIT2: + case ML2_UNIT3: + ESP_LOGI(TAG, "Loop user: Unit %d", Main_Loop2 - ML2_UNIT1); + screen_unit(Main_Loop2 - ML2_UNIT1); + break; + + case ML2_SET_WIFI: + ESP_LOGI(TAG, "Loop user: Setup WiFi"); break; - case MAIN_LOOP2_INACTIVE: -// u8g2_SetPowerSave(&u8g2, 1); // powersave display - New_Loop2 = MAIN_LOOP2_DONE; + case ML2_SET_NETWORK: + ESP_LOGI(TAG, "Loop user: Setup Network"); + break; + + case ML2_SET_MQTT: + ESP_LOGI(TAG, "Loop user: Setup MQTT"); + break; + + case ML2_UPDATE: + ESP_LOGI(TAG, "Loop user: Update"); + break; + + case ML2_SETUP_UNIT1: + case ML2_SETUP_UNIT2: + case ML2_SETUP_UNIT3: + ESP_LOGI(TAG, "Loop user: Setup Unit %d", Main_Loop2 - ML2_SETUP_UNIT1); + sub = 0; + screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub); + break; + + case ML2_INACTIVE: + ESP_LOGI(TAG, "Loop user: Inactive"); + u8g2_SetPowerSave(&u8g2, 1); // powersave display + New_Loop2 = ML2_DONE; break; default: @@ -418,10 +578,10 @@ } /* - * Action process. + * Main user processing. Handle the rotary encoder and pushbutton. */ - switch (Main_Loop2) { - // If wakeup from GPIO -- state machine 2 + if (Main_Loop2 < ML2_INACTIVE) { + // If wakeup from GPIO -- state machine 2 // Init OLED // If not configured, start configure // If configured select first unit @@ -443,12 +603,97 @@ // Sensors setup menu: DS18B20 addr Press is assign // DS18B20 addr - // Break if all done and inactive. - default: - break; + if (xQueueReceive(event_queue, &event, 250 / portTICK_PERIOD_MS) == pdTRUE) { + usertimer = INACTIVITY; + switch (Main_Loop2) { + case ML2_USER: rotate_to_menu(event.state.position, ML2_UNIT1, ML2_USER); break; + case ML2_UNIT1: rotate_to_menu(event.state.position, ML2_UNIT2, ML2_USER); break; + case ML2_UNIT2: rotate_to_menu(event.state.position, ML2_UNIT3, ML2_UNIT1); break; + case ML2_UNIT3: rotate_to_menu(event.state.position, ML2_SET_WIFI, ML2_UNIT2); break; + case ML2_SET_WIFI: rotate_to_menu(event.state.position, ML2_SET_NETWORK, ML2_UNIT3); break; + case ML2_SET_NETWORK: rotate_to_menu(event.state.position, ML2_SET_MQTT, ML2_SET_WIFI); break; + case ML2_SET_MQTT: rotate_to_menu(event.state.position, ML2_UPDATE, ML2_SET_NETWORK); break; + case ML2_UPDATE: rotate_to_menu(event.state.position, ML2_UPDATE, ML2_SET_MQTT); break; + case ML2_SETUP_UNIT1: + case ML2_SETUP_UNIT2: + case ML2_SETUP_UNIT3: if (event.state.position > 0) { + if (sub < 3) { + sub++; + screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub); + } + ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo)); + } else if (event.state.position < 0) { + if (sub > 0) { + sub--; + screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub); + } + ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo)); + } + break; + default: + ESP_LOGI(TAG, "Event: position %d, direction %s", event.state.position, + event.state.direction ? (event.state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ? "CW":"CCW"):"NOT_SET"); + } + } else { + // Poll current position and direction + rotary_encoder_state_t state = { 0 }; + ESP_ERROR_CHECK(rotary_encoder_get_state(&rinfo, &state)); + +// ESP_LOGI(TAG, "Poll: position %d, direction %s timer %d", state.position, +// state.direction ? (state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ? "CW" : "CCW") : "NOT_SET", usertimer); + if (usertimer) + usertimer--; + else + New_Loop2 = ML2_INACTIVE; + + // Reset the device + // if (RESET_AT && (state.position >= RESET_AT || state.position <= -RESET_AT)) { + // ESP_LOGI(TAG, "Reset"); + // ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo)); + // } + } } - if (Main_Loop1 == MAIN_LOOP1_DONE && Main_Loop2 == MAIN_LOOP2_DONE) + switch (Main_Loop2) { + // Break if all done and inactive. + case ML2_UNIT1: + case ML2_UNIT2: + case ML2_UNIT3: + if (PushDuration) { + New_Loop2 = ML2_SETUP_UNIT1 + (Main_Loop2 - ML2_UNIT1); + PushDuration = 0; + } + break; + + case ML2_SETUP_UNIT1: + case ML2_SETUP_UNIT2: + case ML2_SETUP_UNIT3: + if (PushDuration) { + if (sub == 0) { + if (xSemaphoreTake(xSemaphoreUnits, 25) == pdTRUE) { + if (units[Main_Loop2 - ML2_SETUP_UNIT1].mode) + units[Main_Loop2 - ML2_SETUP_UNIT1].mode = 0; + else + units[Main_Loop2 - ML2_SETUP_UNIT1].mode = 1; + write_units(); + xSemaphoreGive(xSemaphoreUnits); + } + screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub); + if (Main_Loop1 == ML1_DONE) + Main_Loop1 = ML1_INIT; + } + if (sub == 3) + New_Loop2 = ML2_UNIT1 + (Main_Loop2 - ML2_SETUP_UNIT1); + printf("sub %d new %d\n", sub, New_Loop2); + PushDuration = 0; + } + break; + + default: + break; + } + + if (Main_Loop1 == ML1_DONE && Main_Loop2 == ML2_DONE) break; vTaskDelay(10 / portTICK_PERIOD_MS); @@ -465,8 +710,8 @@ gettimeofday(&sleep_enter_time, NULL); esp_deep_sleep_start(); - Main_Loop1 = MAIN_LOOP1_INIT; - New_Loop2 = MAIN_LOOP2_INIT; + Main_Loop1 = ML1_INIT; + New_Loop2 = ML2_INIT; } } diff -r 83314e7b1b4a -r e38ffa806e84 main/config.c --- a/main/config.c Sat Oct 26 14:05:17 2019 +0200 +++ b/main/config.c Wed Oct 30 23:21:46 2019 +0100 @@ -81,7 +81,7 @@ void read_units() { uint8_t *dst; uint8_t mac_addr[8] = {0}; - FILE *f = fopen("/spiffs/etc/units.conft", "r"); + FILE *f = fopen("/spiffs/etc/units.conf", "r"); if (f == NULL) { // No units yet, create them. diff -r 83314e7b1b4a -r e38ffa806e84 main/config.h --- a/main/config.h Sat Oct 26 14:05:17 2019 +0200 +++ b/main/config.h Wed Oct 30 23:21:46 2019 +0100 @@ -66,17 +66,17 @@ */ typedef enum { - MAIN_LOOP1_INIT = 0, ///< Init fase - MAIN_LOOP1_CONNECT, ///< Connect WiFi - MAIN_LOOP1_MQTT_CONNECT, ///< Connect MQTT if WiFi - MAIN_LOOP1_WAITCON, ///< Wait for connection and measurements - MAIN_LOOP1_SEND, ///< Send MQTT node and units messages - MAIN_LOOP1_WAITACK, ///< MQTT messages received - MAIN_LOOP1_MQTT_DISCONNECT, ///< MQTT disconnect - MAIN_LOOP1_DISCONNECT, ///< Disconnect WiFi - MAIN_LOOP1_WIFI_OFF, ///< WiFi power off - MAIN_LOOP1_DONE ///< All done -} MAIN_LOOP1; + ML1_INIT = 0, ///< Init fase + ML1_CONNECT, ///< Connect WiFi + ML1_MQTT_CONNECT, ///< Connect MQTT if WiFi + ML1_WAITCON, ///< Wait for connection and measurements + ML1_SEND, ///< Send MQTT node and units messages + ML1_WAITACK, ///< MQTT messages received + ML1_MQTT_DISCONNECT, ///< MQTT disconnect + ML1_DISCONNECT, ///< Disconnect WiFi + ML1_WIFI_OFF, ///< WiFi power off + ML1_DONE ///< All done +} ML1; @@ -85,18 +85,21 @@ */ typedef enum { - MAIN_LOOP2_INIT = 0, - MAIN_LOOP2_UNIT1, ///< Unit 1 - MAIN_LOOP2_UNIT2, ///< Unit 2 - MAIN_LOOP2_UNIT3, ///< Unit 3 - MAIN_LOOP2_UNIT4, ///< Unit 4 - MAIN_LOOP2_SET_WIFI, ///< WiFi stations setup - MAIN_LOOP2_SET_NETWORK, ///< Network setup - MAIN_LOOP2_SET_MQTT, ///< MQTT setup - MAIN_LOOP2_UPDATE, ///< Update - MAIN_LOOP2_INACTIVE, ///< Inactive reached, cleanup - MAIN_LOOP2_DONE ///< All done -} MAIN_LOOP2; + ML2_INIT = 0, + ML2_USER, ///< User mainmenu + ML2_UNIT1, ///< Unit 1 + ML2_UNIT2, ///< Unit 2 + ML2_UNIT3, ///< Unit 3 + ML2_SET_WIFI, ///< WiFi stations setup + ML2_SET_NETWORK, ///< Network setup + ML2_SET_MQTT, ///< MQTT setup + ML2_UPDATE, ///< Update + ML2_SETUP_UNIT1, ///< Unit 1 setup + ML2_SETUP_UNIT2, ///< Unit 2 setup + ML2_SETUP_UNIT3, ///< Unit 3 setup + ML2_INACTIVE, ///< Inactive reached, cleanup + ML2_DONE ///< All done +} ML2; diff -r 83314e7b1b4a -r e38ffa806e84 main/task_mqtt.c --- a/main/task_mqtt.c Sat Oct 26 14:05:17 2019 +0200 +++ b/main/task_mqtt.c Wed Oct 30 23:21:46 2019 +0100 @@ -91,7 +91,7 @@ */ if (xSemaphoreTake(xSemaphorePcounter, 10) == pdTRUE) { count_pub++; -printf(" up %d\n", count_pub); +//printf(" up %d\n", count_pub); xSemaphoreGive(xSemaphorePcounter); } else { ESP_LOGE(TAG, "Missed lock 1"); @@ -288,7 +288,7 @@ if (xSemaphoreTake(xSemaphorePcounter, 10) == pdTRUE) { if (count_pub) { count_pub--; -printf("down %d\n", count_pub); +//printf("down %d\n", count_pub); } xSemaphoreGive(xSemaphorePcounter); } else { diff -r 83314e7b1b4a -r e38ffa806e84 sdkconfig --- a/sdkconfig Sat Oct 26 14:05:17 2019 +0200 +++ b/sdkconfig Wed Oct 30 23:21:46 2019 +0100 @@ -84,9 +84,9 @@ CONFIG_I2C_MASTER_SDA=21 CONFIG_I2C_MASTER_PORT_NUM=0 CONFIG_I2C_MASTER_FREQUENCY=100000 -CONFIG_ROT_ENC_A_GPIO=27 -CONFIG_ROT_ENC_B_GPIO=26 -CONFIG_ROT_ENC_SW_GPIO=12 +CONFIG_ROT_ENC_A_GPIO=26 +CONFIG_ROT_ENC_B_GPIO=27 +CONFIG_ROT_ENC_SW_GPIO=14 CONFIG_BATT_CHANNEL=4 CONFIG_PRESSURE_1=6 CONFIG_PRESSURE_2=7