]> git.tnoah.ca Git - lora-radio.git/commitdiff
Added channel load and airtime stats to display
authorMark Qvist <mark@unsigned.io>
Tue, 12 Sep 2023 19:51:51 +0000 (21:51 +0200)
committerMark Qvist <mark@unsigned.io>
Tue, 12 Sep 2023 19:51:51 +0000 (21:51 +0200)
Config.h
Display.h
Graphics.h
RNode_Firmware.ino
Utilities.h

index 3f3b8ba7f2168216b4a585d69d25fc367939f95e..dc653c7e151afeddddbfbaddb3d82f6e7ad73b18 100644 (file)
--- a/Config.h
+++ b/Config.h
@@ -19,7 +19,7 @@
        #define CONFIG_H
 
        #define MAJ_VERS  0x01
-       #define MIN_VERS  0x3F
+       #define MIN_VERS  0x40
 
        #define PLATFORM_AVR   0x90
   #define PLATFORM_ESP32 0x80
                #define AIRTIME_BINS ((AIRTIME_LONGTERM*1000)/AIRTIME_BINLEN_MS)
                bool util_samples[DCD_SAMPLES];
                uint16_t airtime_bins[AIRTIME_BINS];
+               float longterm_bins[AIRTIME_BINS];
                int dcd_sample = 0;
                float local_channel_util = 0.0;
                float total_channel_util = 0.0;
+               float longterm_channel_util = 0.0;
                float airtime = 0.0;
                float longterm_airtime = 0.0;
                float us_per_byte = 0.0;
index 767367503e50a4032875776f9d5ae7f561f5112b..96dcb923868829dd193faa5bec3fdff0a1eeb8db 100644 (file)
--- a/Display.h
+++ b/Display.h
@@ -17,6 +17,7 @@
 #include <Wire.h>
 #include <Adafruit_GFX.h>
 #include <Adafruit_SSD1306.h>
+#include "Fonts/Org_01.h"
 #define DISP_W 128
 #define DISP_H 64
 #if BOARD_MODEL == BOARD_RNODE_NG_20 || BOARD_MODEL == BOARD_LORA32_V2_0
@@ -36,6 +37,8 @@
   #define DISP_ADDR 0x3C
 #endif
 
+#define SMALL_FONT &Org_01
+
 Adafruit_SSD1306 display(DISP_W, DISP_H, &Wire, DISP_RST);
 
 #define DISP_MODE_UNKNOWN   0x00
@@ -359,12 +362,46 @@ void draw_disp_area() {
     if (firmware_update_mode) disp_area.drawBitmap(0, p_by, bm_fw_update, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
   } else {
     if (!disp_ext_fb or bt_ssp_pin != 0) {
-      if (device_signatures_ok()) {
-        disp_area.drawBitmap(0, 0, bm_def_lc, disp_area.width(), 37, SSD1306_WHITE, SSD1306_BLACK);      
+      if (radio_online && display_diagnostics) {
+        disp_area.fillRect(0,8,disp_area.width(),37, SSD1306_BLACK);
+        disp_area.setFont(SMALL_FONT);
+        disp_area.setTextColor(SSD1306_WHITE);
+        disp_area.setTextWrap(false);
+
+        disp_area.setCursor(1, 14);
+        disp_area.print("On");
+        disp_area.setCursor(1+12, 14);
+        disp_area.print("@");
+        disp_area.setCursor(1+12+1+6, 14);
+        disp_area.printf("%.1fKbps", (float)lora_bitrate/1000.0);
+
+        disp_area.setCursor(2, 23);
+        disp_area.print("Channel Load");
+        
+        disp_area.setCursor(11, 33);
+        if (total_channel_util < 0.099) {
+          disp_area.printf("%.1f%%", total_channel_util*100.0);
+        } else {
+          disp_area.printf("%.0f%%", total_channel_util*100.0);
+        }
+        disp_area.drawBitmap(2, 26, bm_hg_low, 5, 9, SSD1306_WHITE, SSD1306_BLACK);
+
+        disp_area.setCursor(32+11, 33);
+        if (longterm_channel_util < 0.099) {
+          disp_area.printf("%.1f%%", longterm_channel_util*100.0);
+        } else {
+          disp_area.printf("%.0f%%", longterm_channel_util*100.0);
+        }
+        disp_area.drawBitmap(32+2, 26, bm_hg_high, 5, 9, SSD1306_WHITE, SSD1306_BLACK);
+
       } else {
-        disp_area.drawBitmap(0, 0, bm_def, disp_area.width(), 37, SSD1306_WHITE, SSD1306_BLACK);      
+        if (device_signatures_ok()) {
+          disp_area.drawBitmap(0, 0, bm_def_lc, disp_area.width(), 37, SSD1306_WHITE, SSD1306_BLACK);      
+        } else {
+          disp_area.drawBitmap(0, 0, bm_def, disp_area.width(), 37, SSD1306_WHITE, SSD1306_BLACK);      
+        }
       }
-      
+
       if (!hw_ready || radio_error || !device_firmware_ok()) {
         if (!device_firmware_ok()) {
           disp_area.drawBitmap(0, 37, bm_fw_corrupt, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
@@ -393,30 +430,49 @@ void draw_disp_area() {
           if (not community_fw and disp_page == 0) disp_page = 1;
         }
 
-        if (disp_page == 0) {
-          if (true || device_signatures_ok()) {
-            if (radio_online) {
-              disp_area.drawBitmap(0, 37, bm_online, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
+        if (radio_online) {
+          if (display_diagnostics) {
+            disp_area.fillRect(0,37,disp_area.width(),27, SSD1306_WHITE);
+            disp_area.setFont(SMALL_FONT);
+            disp_area.setTextColor(SSD1306_BLACK);
+            disp_area.setTextWrap(false);
+            
+            disp_area.setCursor(1+20+10, 37+3+7-3+1+1);
+            disp_area.print("Airtime");
+            
+            disp_area.setCursor(11, 37+13+10-4+1);
+            if (total_channel_util < 0.099) {
+              disp_area.printf("%.1f%%", airtime*100.0);
             } else {
-              disp_area.drawBitmap(0, 37, bm_checks, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
+              disp_area.printf("%.0f%%", airtime*100.0);
             }
+            disp_area.drawBitmap(2, 37+6+10-4+1, bm_hg_low, 5, 9, SSD1306_BLACK, SSD1306_WHITE);
+
+            disp_area.setCursor(32+11, 37+13+10-4+1);
+            if (longterm_channel_util < 0.099) {
+              disp_area.printf("%.1f%%", longterm_airtime*100.0);
+            } else {
+              disp_area.printf("%.0f%%", longterm_airtime*100.0);
+            }
+            disp_area.drawBitmap(32+2, 37+6+10-4+1, bm_hg_high, 5, 9, SSD1306_BLACK, SSD1306_WHITE);
+
           } else {
-            disp_area.drawBitmap(0, 37, bm_nfr, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
-          }
-        } else if (disp_page == 1) {
-          if (radio_online) {
             disp_area.drawBitmap(0, 37, bm_online, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
-          } else{
+          }
+        } else {
+          if (disp_page == 0) {
+            if (device_signatures_ok()) {
+              disp_area.drawBitmap(0, 37, bm_checks, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
+            } else {
+              disp_area.drawBitmap(0, 37, bm_nfr, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
+            }
+          } else if (disp_page == 1) {
             if (!console_active) {
               disp_area.drawBitmap(0, 37, bm_hwok, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
             } else {
               disp_area.drawBitmap(0, 37, bm_console_active, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
             }
-          }
-        } else if (disp_page == 2) {
-          if (radio_online) {
-            disp_area.drawBitmap(0, 37, bm_online, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
-          } else{
+          } else if (disp_page == 2) {
             disp_area.drawBitmap(0, 37, bm_version, disp_area.width(), 27, SSD1306_WHITE, SSD1306_BLACK);
             char *v_str = (char*)malloc(3+1);
             sprintf(v_str, "%01d%02d", MAJ_VERS, MIN_VERS);
@@ -436,17 +492,6 @@ void draw_disp_area() {
     } else {
       disp_area.drawBitmap(0, 0, fb, disp_area.width(), disp_area.height(), SSD1306_WHITE, SSD1306_BLACK);
     }
-    if (display_diagnostics) {
-      disp_area.setCursor(0, 0);
-      disp_area.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
-      disp_area.setTextSize(1);
-      disp_area.printf("B:%.1fK\r\n", (float)lora_bitrate/1000.0);
-      disp_area.printf("U:%.1f%%\r\n", total_channel_util*100.0);
-      disp_area.printf("L:%.1f%%\r\n", local_channel_util*100.0);
-      disp_area.printf("A:%.2f%%\r\n", airtime*100.0);
-      disp_area.printf("a:%.2f%%\r\n", longterm_airtime*100.0);
-      disp_area.printf("C:%d\r\n", current_airtime_bin());
-    }
   }
 }
 
index e2b032fa254e9a4909af4d7716592319eb4c9276..3f1daf591c116816cf1c572fa52b1d7e0bbb9ed2 100644 (file)
@@ -406,4 +406,12 @@ const unsigned char bm_n_uh [] PROGMEM = {
 const unsigned char bm_plug [] PROGMEM = {
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x7f, 0x80, 0x55, 0xfc, 0x00, 0xaa, 0xfc, 0x00, 0x00, 
    0x7f, 0x80, 0x00, 0x1c, 0x00
+};
+
+const unsigned char bm_hg_low [] PROGMEM = {
+   0xf8, 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0xf8, 0xf8
+};
+
+const unsigned char bm_hg_high [] PROGMEM = {
+   0xf8, 0x88, 0xf8, 0x70, 0x20, 0x70, 0xf8, 0xf8, 0xf8
 };
\ No newline at end of file
index 9788b9a7a0bc99d2cd01dbdf7c1ab567ad7b1d29..39a27aef923e399a77cfd0081d85accb0a58db47 100644 (file)
@@ -89,8 +89,7 @@ void setup() {
   LoRa.setPins(pin_cs, pin_reset, pin_dio);
   
   #if MCU_VARIANT == MCU_ESP32
-    for (uint16_t ai = 0; ai < DCD_SAMPLES; ai++) { util_samples[ai] = false; }
-    for (uint16_t ai = 0; ai < AIRTIME_BINS; ai++) { airtime_bins[ai] = 0; }
+    init_channel_stats();
 
     // Check installed transceiver chip and
     // probe boot parameters.
@@ -402,14 +401,19 @@ void flushQueue(void) {
 void add_airtime(uint16_t written) {
   #if MCU_VARIANT == MCU_ESP32
     float ms_cost = ((float)written * us_per_byte)/1000.0;
-    airtime_bins[current_airtime_bin()] += ms_cost;
+    uint16_t cb = current_airtime_bin();
+    uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; }
+    airtime_bins[cb] += ms_cost;
+    airtime_bins[nb] = 0;
   #endif
 }
 
 void update_airtime() {
   #if MCU_VARIANT == MCU_ESP32
     uint16_t cb = current_airtime_bin();
-    uint16_t pb = cb-1; if (cb < 0) { cb = AIRTIME_BINS-1; }
+    uint16_t pb = cb-1; if (pb < 0) { pb = AIRTIME_BINS-1; }
+    uint16_t nb = cb+1; if (nb == AIRTIME_BINS) { nb = 0; }
+    airtime_bins[nb] = 0;
     airtime = (float)(airtime_bins[cb]+airtime_bins[pb])/(2.0*AIRTIME_BINLEN_MS);
 
     uint32_t longterm_airtime_sum = 0;
@@ -417,6 +421,12 @@ void update_airtime() {
       longterm_airtime_sum += airtime_bins[bin];
     }
     longterm_airtime = (float)longterm_airtime_sum/(float)AIRTIME_LONGTERM_MS;
+
+    float longterm_channel_util_sum = 0.0;
+    for (uint16_t bin = 0; bin < AIRTIME_BINS; bin++) {
+      longterm_channel_util_sum += longterm_bins[bin];
+    }
+    longterm_channel_util = (float)longterm_channel_util_sum/(float)AIRTIME_BINS;
   #endif
 }
 
@@ -895,6 +905,8 @@ void checkModemStatus() {
         total_channel_util = local_channel_util + airtime;
         if (total_channel_util > 1.0) total_channel_util = 1.0;
 
+        longterm_bins[current_airtime_bin()] = total_channel_util;
+
         update_airtime();
       }
     #endif
index 103738b45e5207331358fecbb1b7dca30bc4686d..78afdd29c52826bc8aae989cd3e93dad96128c7d 100644 (file)
@@ -1181,6 +1181,16 @@ void unlock_rom() {
        eeprom_erase();
 }
 
+void init_channel_stats() {
+       for (uint16_t ai = 0; ai < DCD_SAMPLES; ai++) { util_samples[ai] = false; }
+       for (uint16_t ai = 0; ai < AIRTIME_BINS; ai++) { airtime_bins[ai] = 0; }
+       for (uint16_t ai = 0; ai < AIRTIME_BINS; ai++) { longterm_bins[ai] = 0.0; }
+       local_channel_util = 0.0;
+       total_channel_util = 0.0;
+       airtime = 0.0;
+       longterm_airtime = 0.0;
+}
+
 typedef struct FIFOBuffer
 {
   unsigned char *begin;