]> git.earman.xyz Git - sensor-watch.git/commitdiff
bring in battery voltage face, add new method and demo for displaying floats
authorjoeycastillo <joeycastillo@utexas.edu>
Mon, 30 Sep 2024 04:24:23 +0000 (00:24 -0400)
committerjoeycastillo <joeycastillo@utexas.edu>
Mon, 30 Sep 2024 04:24:23 +0000 (00:24 -0400)
12 files changed:
Makefile
movement/watch_faces/demo/voltage_face.c [deleted file]
movement/watch_faces/demo/voltage_face.h [deleted file]
movement_config.h
movement_faces.h
watch-faces.mk
watch-faces/demo/float_demo_face.c [new file with mode: 0644]
watch-faces/demo/float_demo_face.h [new file with mode: 0644]
watch-faces/sensor/voltage_face.c [new file with mode: 0644]
watch-faces/sensor/voltage_face.h [new file with mode: 0644]
watch-library/shared/watch/watch_common_display.c
watch-library/shared/watch/watch_slcd.h

index 6a76e69bd67895d09ee143321390265e65df52fe..ab894cec962d2a60e1df637778758bd2fe209b75 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -40,6 +40,8 @@ INCLUDES += \
   -I./watch-library/hardware/watch \
   -I./watch-faces/clock \
   -I./watch-faces/complication \
+  -I./watch-faces/demo \
+  -I./watch-faces/sensor \
   -I./watch-faces/settings \
 
 # Add your source files here.
diff --git a/movement/watch_faces/demo/voltage_face.c b/movement/watch_faces/demo/voltage_face.c
deleted file mode 100644 (file)
index 2d209d2..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2022 Joey Castillo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "voltage_face.h"
-#include "watch.h"
-
-static void _voltage_face_update_display(void) {
-    char buf[14];
-
-    watch_enable_adc();
-    float voltage = (float)watch_get_vcc_voltage() / 1000.0;
-    watch_disable_adc();
-
-    sprintf(buf, "BA  %4.2f V", voltage);
-    // printf("%s\n", buf);
-    watch_display_string(buf, 0);
-}
-
-void voltage_face_setup(uint8_t watch_face_index, void ** context_ptr) {
-    (void) watch_face_index;
-    (void) context_ptr;
-}
-
-void voltage_face_activate(void *context) {
-    (void) context;
-}
-
-bool voltage_face_loop(movement_event_t event, void *context) {
-    (void) context;
-    watch_date_time date_time;
-    switch (event.event_type) {
-        case EVENT_ACTIVATE:
-            _voltage_face_update_display();
-            break;
-        case EVENT_TICK:
-            date_time = watch_rtc_get_date_time();
-            if (date_time.unit.second % 5 == 4) {
-                watch_set_indicator(WATCH_INDICATOR_SIGNAL);
-            } else if (date_time.unit.second % 5 == 0) {
-                _voltage_face_update_display();
-                watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
-            }
-            break;
-        case EVENT_LOW_ENERGY_UPDATE:
-            // clear seconds area and start tick animation if necessary
-            if (!watch_sleep_animation_is_running()) {
-                watch_display_string("  ", 8);
-                watch_start_sleep_animation(1000);
-            }
-            // update once an hour
-            if (date_time.unit.minute == 0) {
-                watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
-                _voltage_face_update_display();
-                watch_display_string("  ", 8);
-            }
-            break;
-        default:
-            movement_default_loop_handler(event);
-            break;
-    }
-
-    return true;
-}
-
-void voltage_face_resign(void *context) {
-    (void) context;
-}
diff --git a/movement/watch_faces/demo/voltage_face.h b/movement/watch_faces/demo/voltage_face.h
deleted file mode 100644 (file)
index 9257671..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2022 Joey Castillo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef VOLTAGE_FACE_H_
-#define VOLTAGE_FACE_H_
-
-/*
- * VOLTAGE face
- *
- * This watch face is very simple and has no controls to speak of. It displays
- * the battery voltage as measured by the SAM L22’s ADC.
- *
- * Note that the Simple Clock watch face includes a low battery warning, so you
- * don’t technically need to this watch face unless you want to track the
- * battery level.
- */
-
-#include "movement.h"
-
-void voltage_face_setup(uint8_t watch_face_index, void ** context_ptr);
-void voltage_face_activate(void *context);
-bool voltage_face_loop(movement_event_t event, void *context);
-void voltage_face_resign(void *context);
-
-#define voltage_face ((const watch_face_t){ \
-    voltage_face_setup, \
-    voltage_face_activate, \
-    voltage_face_loop, \
-    voltage_face_resign, \
-    NULL, \
-})
-
-#endif // VOLTAGE_FACE_H_
index c54149ecdbfc5cb3ef26f46efc988594a3f74d6d..94564d95fe9df10584c1d6471235277e6aef9035 100644 (file)
@@ -34,6 +34,7 @@ const watch_face_t watch_faces[] = {
     advanced_alarm_face,
     countdown_face,
     fast_stopwatch_face,
+    voltage_face,
     preferences_face,
     set_time_face,
 };
index 09d682f37d846acf260a67105aecee6a869e52f0..1d3215d1c8f35807049ba09c7e1d1bc1311cd331 100644 (file)
@@ -31,6 +31,8 @@
 #include "countdown_face.h"
 #include "fast_stopwatch_face.h"
 #include "sunrise_sunset_face.h"
+#include "float_demo_face.h"
+#include "voltage_face.h"
 #include "set_time_face.h"
 #include "preferences_face.h"
 // New includes go above this line.
index 417e30d602c5bac163d9bcd6ede140a3b179cf16..0e38e1cdc242d9e589891247b31259953f2c27cb 100644 (file)
@@ -6,5 +6,7 @@ SRCS += \
   ./watch-faces/complication/countdown_face.c \
   ./watch-faces/complication/fast_stopwatch_face.c \
   ./watch-faces/complication/sunrise_sunset_face.c \
+  ./watch-faces/demo/float_demo_face.c \
+  ./watch-faces/sensor/voltage_face.c \
   ./watch-faces/settings/set_time_face.c \
   ./watch-faces/settings/preferences_face.c \
diff --git a/watch-faces/demo/float_demo_face.c b/watch-faces/demo/float_demo_face.c
new file mode 100644 (file)
index 0000000..fa650d2
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Joey Castillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "float_demo_face.h"
+#include "watch.h"
+
+void float_demo_face_setup(uint8_t watch_face_index, void ** context_ptr) {
+    (void) watch_face_index;
+    if (*context_ptr == NULL) *context_ptr = malloc(sizeof(float));
+}
+
+void float_demo_face_activate(void *context) {
+    float *c = (float *)context;
+    *c = 0;
+    watch_display_text_with_fallback(WATCH_POSITION_TOP, "FLOAT", "FL");
+    movement_request_tick_frequency(32);
+}
+
+bool float_demo_face_loop(movement_event_t event, void *context) {
+    float *c = (float *)context;
+    switch (event.event_type) {
+        case EVENT_TICK:
+            *c = (*c) + 0.11;
+            // fall through
+        case EVENT_ACTIVATE:
+            watch_display_float_with_best_effort(*c, "#F");
+            break;
+        default:
+            movement_default_loop_handler(event);
+            break;
+    }
+
+    return true;
+}
+
+void float_demo_face_resign(void *context) {
+    (void) context;
+}
diff --git a/watch-faces/demo/float_demo_face.h b/watch-faces/demo/float_demo_face.h
new file mode 100644 (file)
index 0000000..96ea8ad
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2024 Joey Castillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef FLOAT_DEMO_FACE_H_
+#define FLOAT_DEMO_FACE_H_
+
+/*
+ * FLOAT DEMO
+ * 
+ * To be deleted, tests float display functionality.
+ */
+
+#include "movement.h"
+
+void float_demo_face_setup(uint8_t watch_face_index, void ** context_ptr);
+void float_demo_face_activate(void *context);
+bool float_demo_face_loop(movement_event_t event, void *context);
+void float_demo_face_resign(void *context);
+
+#define float_demo_face ((const watch_face_t){ \
+    float_demo_face_setup, \
+    float_demo_face_activate, \
+    float_demo_face_loop, \
+    float_demo_face_resign, \
+    NULL, \
+})
+
+#endif // FLOAT_DEMO_FACE_H_
diff --git a/watch-faces/sensor/voltage_face.c b/watch-faces/sensor/voltage_face.c
new file mode 100644 (file)
index 0000000..b532c9d
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Joey Castillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "voltage_face.h"
+#include "watch.h"
+
+static void _voltage_face_update_display(void) {
+    watch_enable_adc();
+    float voltage = (float)watch_get_vcc_voltage() / 1000.0;
+    watch_disable_adc();
+
+    watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "BAT", "BA");
+    watch_display_float_with_best_effort(voltage, " V");
+}
+
+void voltage_face_setup(uint8_t watch_face_index, void ** context_ptr) {
+    (void) watch_face_index;
+    (void) context_ptr;
+}
+
+void voltage_face_activate(void *context) {
+    (void) context;
+}
+
+bool voltage_face_loop(movement_event_t event, void *context) {
+    (void) context;
+    watch_date_time date_time;
+    switch (event.event_type) {
+        case EVENT_ACTIVATE:
+            _voltage_face_update_display();
+            break;
+        case EVENT_TICK:
+            date_time = watch_rtc_get_date_time();
+            if (date_time.unit.second % 5 == 4) {
+                watch_set_indicator(WATCH_INDICATOR_SIGNAL);
+            } else if (date_time.unit.second % 5 == 0) {
+                _voltage_face_update_display();
+                watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
+            }
+            break;
+        case EVENT_LOW_ENERGY_UPDATE:
+            // clear seconds area (on classic LCD) and start tick animation if necessary
+            if (!watch_sleep_animation_is_running()) {
+                watch_display_text_with_fallback(WATCH_POSITION_SECONDS, " V", "  ");
+                watch_start_sleep_animation(1000);
+            }
+            // update once an hour
+            if (date_time.unit.minute == 0) {
+                watch_clear_indicator(WATCH_INDICATOR_SIGNAL);
+                _voltage_face_update_display();
+                watch_display_text_with_fallback(WATCH_POSITION_SECONDS, " V", "  ");
+            }
+            break;
+        default:
+            movement_default_loop_handler(event);
+            break;
+    }
+
+    return true;
+}
+
+void voltage_face_resign(void *context) {
+    (void) context;
+}
diff --git a/watch-faces/sensor/voltage_face.h b/watch-faces/sensor/voltage_face.h
new file mode 100644 (file)
index 0000000..9257671
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2022 Joey Castillo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef VOLTAGE_FACE_H_
+#define VOLTAGE_FACE_H_
+
+/*
+ * VOLTAGE face
+ *
+ * This watch face is very simple and has no controls to speak of. It displays
+ * the battery voltage as measured by the SAM L22’s ADC.
+ *
+ * Note that the Simple Clock watch face includes a low battery warning, so you
+ * don’t technically need to this watch face unless you want to track the
+ * battery level.
+ */
+
+#include "movement.h"
+
+void voltage_face_setup(uint8_t watch_face_index, void ** context_ptr);
+void voltage_face_activate(void *context);
+bool voltage_face_loop(movement_event_t event, void *context);
+void voltage_face_resign(void *context);
+
+#define voltage_face ((const watch_face_t){ \
+    voltage_face_setup, \
+    voltage_face_activate, \
+    voltage_face_loop, \
+    voltage_face_resign, \
+    NULL, \
+})
+
+#endif // VOLTAGE_FACE_H_
index 4e7184f265d22ea1d1ed9ebadc1064d4ad4a4c39..baf0fde8619e290a97a9abdb201220e5db90056a 100644 (file)
@@ -25,6 +25,7 @@
 #include "watch_slcd.h"
 #include "watch_common_display.h"
 #include <string.h>
+#include <stdio.h>
 
 #ifdef USE_CUSTOM_LCD
 static const uint32_t IndicatorSegments[] = {
@@ -267,6 +268,37 @@ void watch_display_text_with_fallback(watch_position_t location, const char *str
 #endif
 }
 
+void watch_display_float_with_best_effort(float value, const char *units) {
+    char buf[8];
+    char buf_fallback[8];
+    const char *blank_units = "  ";
+
+    if (value < 0.0) {
+        watch_clear_decimal_if_available();
+        watch_display_text_with_fallback(WATCH_POSITION_BOTTOM, "Undflo", " Unflo");
+        return;
+    } else if (value > 199.99) {
+        watch_clear_decimal_if_available();
+        watch_display_text(WATCH_POSITION_BOTTOM, "Ovrflo");
+        return;
+    }
+
+    uint16_t value_times_100 = (uint16_t)(value * 100.0);
+    if (value_times_100 > 9999) {
+        snprintf(buf, sizeof(buf), "%5u%s", value_times_100, units ? units : blank_units);
+        snprintf(buf_fallback, sizeof(buf_fallback), "%4.1f%s", value, units ? units : blank_units);
+    } else if (value_times_100 > 999) {
+        snprintf(buf, sizeof(buf), "%4u%s", value_times_100, units ? units : blank_units);
+        snprintf(buf_fallback, sizeof(buf_fallback), "%4.1f%s", value, units ? units : blank_units);
+    } else {
+        snprintf(buf, sizeof(buf), " %03u%s", value_times_100 % 1000u, units ? units : blank_units);
+        snprintf(buf_fallback, sizeof(buf_fallback), "%4.2f%s", value, units ? units : blank_units);
+    }
+
+    watch_display_text_with_fallback(WATCH_POSITION_BOTTOM, buf, buf_fallback);
+    watch_set_decimal_if_available();
+}
+
 void watch_set_colon(void) {
 #ifdef USE_CUSTOM_LCD
     watch_set_pixel(0, 0);
index c3a23ba061b598c027a1d45cf44d22c339b191ed..b369b3b53ccdba8097829043dc6508504cfc93b0 100644 (file)
@@ -160,6 +160,19 @@ void watch_display_text(watch_position_t location, const char *string);
  */
 void watch_display_text_with_fallback(watch_position_t location, const char *string, const char *fallback);
 
+/**
+ * @brief Displays a floating point number as best we can on whatever LCD is available.
+ * @details The custom LCD can energize a decimal point in the same position as the colon. With the leading 1,
+ *          we can display numbers from 0.00 to 199.99 with two digits of precision. The original F-91W LCD has
+ *          no decimal point, so we use a hyphen to indicate the decimal point. For floats from 0.00 to 9.99,
+ *          we can display the number with two digits after the "decimal point" (hyphen). For floats from 10.0
+ *          to 99.9, you'll only get one digit after the hyphen. For floats from 100 to 199.9, we'll still give
+ *          you one digit after the hyphen, but you'll lose the second character of your units.
+ * @param value A floating point number from 0.00 to 199.99 to display on the main clock digits.
+ * @param units A 1-2 character string to display in the seconds position. Second character may be truncated.
+ */
+void watch_display_float_with_best_effort(float value, const char *units);
+
 /** @brief Turns the colon segment on.
   */
 void watch_set_colon(void);