Added splash screen and unit zero set menu.

Fri, 01 Nov 2019 13:13:14 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Fri, 01 Nov 2019 13:13:14 +0100
changeset 18
d969e0fe05dc
parent 17
f9eca4a55911
child 19
4fb9ed228a23

Added splash screen and unit zero set menu.

main/co2meter.c file | annotate | diff | comparison | revisions
main/config.h file | annotate | diff | comparison | revisions
main/xutil.h file | annotate | diff | comparison | revisions
--- a/main/co2meter.c	Thu Oct 31 22:22:22 2019 +0100
+++ b/main/co2meter.c	Fri Nov 01 13:13:14 2019 +0100
@@ -93,6 +93,20 @@
 
 
 
+void screen_splash()
+{
+    screen_top("CO2 meter %s", app_desc->version);
+
+    u8g2_SetFont(&u8g2, u8g2_font_t0_22b_tf);
+    u8g2_uint_t w = u8g2_GetUTF8Width(&u8g2, "START");
+    u8g2_DrawUTF8(&u8g2, (128 - w) / 2,50, "START");
+
+    u8g2_SendBuffer(&u8g2);
+    u8g2_SetPowerSave(&u8g2, 0); // wake up display
+}
+
+
+
 void screen_main()
 {
     char	buf[65];
@@ -146,6 +160,19 @@
 
 
 
+void screen_unit_zero(int no, int sub)
+{
+    screen_top("Unit %d zero mV", no + 1);
+    menu_line(       0, 2, 25, "Current   %d", units[no].pressure_zero);
+    menu_line(sub == 0, 2, 37, "New value %d", units[no].pressure_voltage / (adc_state->Batt_voltage / 1000));
+    menu_line(sub == 1, 2, 49, "Return");
+
+    u8g2_SendBuffer(&u8g2);
+    u8g2_SetPowerSave(&u8g2, 0);
+}
+
+
+
 void screen_unit_setup(int no, int sub)
 {
     screen_top("Unit %d setup", no + 1);
@@ -225,6 +252,27 @@
 
 
 
+int rotate_to_sub(rotary_encoder_position_t pos, int min, int max, int cursub)
+{
+   int	sub = cursub;
+
+   if (pos > 0) {
+	if (sub < max)
+	    sub++;
+	else
+	    sub = min;
+	ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo));
+    } else if (pos < 0) {
+	if (sub > min)
+	    sub--;
+	else
+	    sub = max;
+	ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo));
+    }
+    return sub;
+}
+
+
 void app_main()
 {
     struct timeval	now;
@@ -235,10 +283,26 @@
     Main_Loop1 = ML1_INIT;
     Main_Loop2 = -1;
 
+    /*
+     * Setup the OLED display.
+     * See: https://github.com/nkolban/esp32-snippets/blob/master/hardware/displays/U8G2/
+     */
+    u8g2_esp32_hal_t u8g2_esp32_hal = U8G2_ESP32_HAL_DEFAULT;
+    u8g2_esp32_hal.sda = PIN_SDA;
+    u8g2_esp32_hal.scl = PIN_SCL;
+    u8g2_esp32_hal_init(u8g2_esp32_hal);
+
+    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);
+    u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,
+
+    app_desc = esp_ota_get_app_description();
+
     switch (esp_sleep_get_wakeup_cause()) {
         case ESP_SLEEP_WAKEUP_EXT1: {
 	    ESP_LOGI(TAG, "Starting from deep sleep, Rotary switch pressed");
 	    New_Loop2 = ML2_INIT;
+	    screen_splash();
             break;
         }
         case ESP_SLEEP_WAKEUP_TIMER: {
@@ -248,6 +312,7 @@
         case ESP_SLEEP_WAKEUP_UNDEFINED:
         default:
             ESP_LOGI(TAG, "Starting from hard reset");
+	    screen_splash();
     }
 
     const int wakeup_time_sec = 55;
@@ -263,8 +328,6 @@
     // to minimize current consumption.
 //    rtc_gpio_isolate(GPIO_NUM_12);
 
-    app_desc = esp_ota_get_app_description();
-
     /*
      * Initialize NVS
      */
@@ -276,19 +339,6 @@
     ESP_ERROR_CHECK(ret);
 
     /*
-     * Setup the OLED display.
-     * See: https://github.com/nkolban/esp32-snippets/blob/master/hardware/displays/U8G2/
-     */
-    u8g2_esp32_hal_t u8g2_esp32_hal = U8G2_ESP32_HAL_DEFAULT;
-    u8g2_esp32_hal.sda = PIN_SDA;
-    u8g2_esp32_hal.scl = PIN_SCL;
-    u8g2_esp32_hal_init(u8g2_esp32_hal);
-
-    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);
-    u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,
-
-    /*
      * Setup SPIFFS filesystem
      */
     ESP_LOGI(TAG, "Initializing SPIFFS");
@@ -401,6 +451,7 @@
 	ESP_LOGI(TAG, "Entered app loop");
 	rotary_encoder_event_t event = { 0 };
 	int sub = 0;
+	u8g2_SetPowerSave(&u8g2, 1);
 
 	/* Measure process or user input via rotary switch */
 	while (1) {
@@ -450,14 +501,13 @@
 				    units[i].pressure_state = adc_state->Pressure[i].error;
 				    units[i].pressure_channel = adc_state->Pressure[i].channel;
 				    units[i].pressure_voltage = adc_state->Pressure[i].voltage;
-				    units[i].pressure_zero = 110;
 				    if (units[i].pressure_state || units[i].pressure_voltage < 80)
 					units[i].alarm |= ALARM_UNIT_PRESSURE;
 				    int P = (units[i].pressure_voltage / (adc_state->Batt_voltage / 1000) - units[i].pressure_zero) * 14; // in bar
 				    if (P < 0)
 				    	P = 0;
 				    units[i].pressure = P;
-printf("%d volt: %d batt: %d scale: %d  bar: %d\n", i, units[i].pressure_voltage, adc_state->Batt_voltage, 
+printf("%d volt: %d batt: %d scale: %d  mbar: %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?
 // Verbruik 10 mA
@@ -570,6 +620,14 @@
 			screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub);
 			break;
 
+		    case ML2_ZERO_UNIT1:
+		    case ML2_ZERO_UNIT2:
+		    case ML2_ZERO_UNIT3:
+			ESP_LOGI(TAG, "Loop user: Zero Unit %d", Main_Loop2 - ML2_ZERO_UNIT1);
+                        sub = 0;
+                        screen_unit_zero(Main_Loop2 - ML2_ZERO_UNIT1, sub);
+                        break;
+
 		    case ML2_INACTIVE:
 			ESP_LOGI(TAG, "Loop user: Inactive");
 			u8g2_SetPowerSave(&u8g2, 1); // powersave display
@@ -614,23 +672,13 @@
 		    	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++;
-						    } else {
-							sub = 0;
-						    }
-						    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--;
-						    } else {
-							sub = 3;
-						    }
-						    screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub);
-						    ESP_ERROR_CHECK(rotary_encoder_reset(&rinfo));
-						}
+			case ML2_SETUP_UNIT3:	sub = rotate_to_sub(event.state.position, 0, 3, sub);
+						screen_unit_setup(Main_Loop2 - ML2_SETUP_UNIT1, sub);
+						break;
+			case ML2_ZERO_UNIT1:
+			case ML2_ZERO_UNIT2:
+			case ML2_ZERO_UNIT3:	sub = rotate_to_sub(event.state.position, 0, 1, sub);
+						screen_unit_zero(Main_Loop2 - ML2_ZERO_UNIT1, sub);
 						break;
 			default:
 		    				ESP_LOGI(TAG, "Event: position %d, direction %s", event.state.position,
@@ -655,43 +703,71 @@
                 }
 	    }
 
-	    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;
-			}
+	    /*
+	     * Handle pressed rotary button.
+	     */
+	    if (PushDuration) {
+		int idx = 0;
+	    	switch (Main_Loop2) {
+		    case ML2_UNIT1:
+		    case ML2_UNIT2:
+		    case ML2_UNIT3:
+			New_Loop2 = ML2_SETUP_UNIT1 + (Main_Loop2 - ML2_UNIT1);
 			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;
+		    case ML2_SETUP_UNIT1:
+		    case ML2_SETUP_UNIT2:
+		    case ML2_SETUP_UNIT3:
+			idx = Main_Loop2 - ML2_SETUP_UNIT1;
+			if (sub == 0) {
+			    if (xSemaphoreTake(xSemaphoreUnits, 25) == pdTRUE) {
+				if (units[idx].mode)
+				    units[idx].mode = 0;
+				else
+				    units[idx].mode = 1;
+				write_units();
+                            	xSemaphoreGive(xSemaphoreUnits);
 			    }
-			    if (sub == 3)
-				New_Loop2 = ML2_UNIT1 + (Main_Loop2 - ML2_SETUP_UNIT1);
-			    printf("sub %d  new %d\n", sub, New_Loop2);
-			    PushDuration = 0;
+			    screen_unit_setup(idx, sub);
+			    if (Main_Loop1 == ML1_DONE)
+				Main_Loop1 = ML1_INIT;
 			}
+			if (sub == 1)
+			    New_Loop2 = ML2_ZERO_UNIT1 + idx;
+			if (sub == 3)
+			    New_Loop2 = ML2_UNIT1 + idx;
+			printf("unit setup sub %d  new %d  idx %d\n", sub, New_Loop2, idx);
 			break;
 
-		default:
+		    case ML2_ZERO_UNIT1:
+		    case ML2_ZERO_UNIT2:
+		    case ML2_ZERO_UNIT3:
+			idx = Main_Loop2 - ML2_ZERO_UNIT1;
+                        if (sub == 0) {
+			    if (xSemaphoreTake(xSemaphoreUnits, 25) == pdTRUE &&
+			      xSemaphoreTake(xSemaphoreADC, 10) == pdTRUE &&
+			      adc_state->Pressure[idx].voltage > 165 &&
+			      adc_state->Pressure[idx].voltage < 660) {
+				units[idx].pressure_zero = adc_state->Pressure[idx].voltage / (adc_state->Batt_voltage / 1000);
+				write_units();
+				xSemaphoreGive(xSemaphoreADC);
+                                xSemaphoreGive(xSemaphoreUnits);
+				screen_unit_zero(idx, sub);
+				if (Main_Loop1 == ML1_DONE)
+                            	    Main_Loop1 = ML1_INIT;
+			    }
+			}
+			if (sub == 1) {
+			    New_Loop2 = ML2_SETUP_UNIT1 + idx;
+			    sub = 1;
+			}
+			printf("unit zero sub %d  new %d  idx %d\n", sub, New_Loop2, idx);
 			break;
+
+		    default:
+			break;
+	    	}
+	    	PushDuration = 0;
 	    }
 
 	    if (Main_Loop1 == ML1_DONE && Main_Loop2 == ML2_DONE)
--- a/main/config.h	Thu Oct 31 22:22:22 2019 +0100
+++ b/main/config.h	Fri Nov 01 13:13:14 2019 +0100
@@ -97,6 +97,9 @@
     ML2_SETUP_UNIT1,		///< Unit 1 setup
     ML2_SETUP_UNIT2,		///< Unit 2 setup
     ML2_SETUP_UNIT3,		///< Unit 3 setup
+    ML2_ZERO_UNIT1,		///< Unit 1 set zero
+    ML2_ZERO_UNIT2,		///< Unit 2 set zero
+    ML2_ZERO_UNIT3,		///< Unit 3 set zero
     ML2_INACTIVE,		///< Inactive reached, cleanup
     ML2_DONE			///< All done
 } ML2;
--- a/main/xutil.h	Thu Oct 31 22:22:22 2019 +0100
+++ b/main/xutil.h	Fri Nov 01 13:13:14 2019 +0100
@@ -1,8 +1,32 @@
+/**
+ * @file xutil.h
+ * @brief In memory string manipulation.
+ */
+
+
 #ifndef XUTIL_H
 #define	XUTIL_H
 
-char *xmalloc(size_t);
-char *xstrcpy(char *);
-char *xstrcat(char *, char *);
+/**
+ * @brief Safe memory allocation. Abort if not enough.
+ * @param size The amount of memory to allocate.
+ * @return A pointer to the allocated memory.
+ */
+char *xmalloc(size_t size);
+
+/**
+ * @brief Copy string in memory.
+ * @param src The source string to copy.
+ * @return A pointer to the string with the copied string.
+ */
+char *xstrcpy(char *src);
+
+/**
+ * @brief Add data to a string in memory.
+ * @param src The original string.
+ * @param add The string to append to src.
+ * @return A pointer to the combined string.
+ */
+char *xstrcat(char *src, char *add);
 
 #endif

mercurial