|
| 1 | +#include <ZeroKernel.h> |
| 2 | +#include <adapters/PowerSaveLoopAdapter.h> |
| 3 | + |
| 4 | +using zerokernel::Kernel; |
| 5 | + |
| 6 | +namespace { |
| 7 | + |
| 8 | +const unsigned long kSamplePeriodUs = 100000UL; |
| 9 | +const unsigned long kSummaryPeriodMs = 5000UL; |
| 10 | + |
| 11 | +struct BaselineState { |
| 12 | + bool wifiConnected; |
| 13 | + bool connectPending; |
| 14 | + bool mqttConnected; |
| 15 | + bool httpConnectPending; |
| 16 | + bool failNextHttp; |
| 17 | + bool failNextMqtt; |
| 18 | + unsigned long nextExpectedUs; |
| 19 | + unsigned long lagAccumUs; |
| 20 | + unsigned long maxLagUs; |
| 21 | + unsigned long sampleRuns; |
| 22 | + unsigned long fastMisses; |
| 23 | + unsigned long startedAtMs; |
| 24 | + unsigned long lastSummaryAtMs; |
| 25 | + unsigned long httpQueued; |
| 26 | + unsigned long httpSendOk; |
| 27 | + unsigned long httpSendFail; |
| 28 | + unsigned long httpConnectAttempts; |
| 29 | + unsigned long httpMaxQueue; |
| 30 | + unsigned long mqttQueued; |
| 31 | + unsigned long mqttSendOk; |
| 32 | + unsigned long mqttSendFail; |
| 33 | + unsigned long mqttConnectAttempts; |
| 34 | + unsigned long wifiConnectAttempts; |
| 35 | + unsigned long wifiReconnects; |
| 36 | +} g_state = {}; |
| 37 | + |
| 38 | +unsigned long boardMillis() { |
| 39 | + return millis(); |
| 40 | +} |
| 41 | + |
| 42 | +void sampleTask() { |
| 43 | + const unsigned long nowUs = micros(); |
| 44 | + if (g_state.nextExpectedUs == 0) { |
| 45 | + g_state.nextExpectedUs = nowUs; |
| 46 | + } |
| 47 | + |
| 48 | + const unsigned long lagUs = nowUs > g_state.nextExpectedUs ? nowUs - g_state.nextExpectedUs : 0; |
| 49 | + g_state.lagAccumUs += lagUs; |
| 50 | + if (lagUs > g_state.maxLagUs) { |
| 51 | + g_state.maxLagUs = lagUs; |
| 52 | + } |
| 53 | + if (lagUs > 1500UL) { |
| 54 | + ++g_state.fastMisses; |
| 55 | + } |
| 56 | + ++g_state.sampleRuns; |
| 57 | + g_state.nextExpectedUs += kSamplePeriodUs; |
| 58 | + if (nowUs > g_state.nextExpectedUs + kSamplePeriodUs) { |
| 59 | + g_state.nextExpectedUs = nowUs + kSamplePeriodUs; |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +void queueTask() { |
| 64 | + if (g_state.httpQueued < 4UL) { |
| 65 | + ++g_state.httpQueued; |
| 66 | + if (g_state.httpQueued > g_state.httpMaxQueue) { |
| 67 | + g_state.httpMaxQueue = g_state.httpQueued; |
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + if (g_state.mqttQueued < 6UL) { |
| 72 | + ++g_state.mqttQueued; |
| 73 | + } |
| 74 | +} |
| 75 | + |
| 76 | +void wifiTask() { |
| 77 | + if (g_state.wifiConnected) { |
| 78 | + return; |
| 79 | + } |
| 80 | + |
| 81 | + ++g_state.wifiConnectAttempts; |
| 82 | + if (g_state.connectPending) { |
| 83 | + g_state.connectPending = false; |
| 84 | + return; |
| 85 | + } |
| 86 | + |
| 87 | + g_state.connectPending = true; |
| 88 | + g_state.wifiConnected = true; |
| 89 | + ++g_state.wifiReconnects; |
| 90 | + g_state.mqttConnected = true; |
| 91 | +} |
| 92 | + |
| 93 | +void httpTask() { |
| 94 | + if (g_state.httpQueued == 0) { |
| 95 | + return; |
| 96 | + } |
| 97 | + |
| 98 | + ++g_state.httpConnectAttempts; |
| 99 | + if (g_state.httpConnectPending) { |
| 100 | + g_state.httpConnectPending = false; |
| 101 | + return; |
| 102 | + } |
| 103 | + |
| 104 | + g_state.httpConnectPending = true; |
| 105 | + --g_state.httpQueued; |
| 106 | + if (g_state.failNextHttp) { |
| 107 | + g_state.failNextHttp = false; |
| 108 | + ++g_state.httpSendFail; |
| 109 | + return; |
| 110 | + } |
| 111 | + |
| 112 | + g_state.failNextHttp = true; |
| 113 | + ++g_state.httpSendOk; |
| 114 | +} |
| 115 | + |
| 116 | +void mqttTask() { |
| 117 | + if (!g_state.mqttConnected) { |
| 118 | + ++g_state.mqttConnectAttempts; |
| 119 | + g_state.mqttConnected = true; |
| 120 | + return; |
| 121 | + } |
| 122 | + |
| 123 | + if (g_state.mqttQueued == 0) { |
| 124 | + return; |
| 125 | + } |
| 126 | + |
| 127 | + --g_state.mqttQueued; |
| 128 | + if (g_state.failNextMqtt) { |
| 129 | + g_state.failNextMqtt = false; |
| 130 | + ++g_state.mqttSendFail; |
| 131 | + return; |
| 132 | + } |
| 133 | + |
| 134 | + g_state.failNextMqtt = true; |
| 135 | + ++g_state.mqttSendOk; |
| 136 | +} |
| 137 | + |
| 138 | +void reportTask() { |
| 139 | + const unsigned long nowMs = millis(); |
| 140 | + if ((nowMs - g_state.lastSummaryAtMs) < kSummaryPeriodMs) { |
| 141 | + return; |
| 142 | + } |
| 143 | + |
| 144 | + g_state.lastSummaryAtMs = nowMs; |
| 145 | + const unsigned long windowMs = nowMs - g_state.startedAtMs; |
| 146 | + const unsigned long avgLagUs = g_state.sampleRuns == 0 ? 0 : g_state.lagAccumUs / g_state.sampleRuns; |
| 147 | + |
| 148 | + Serial.print("BASELINE_NETMODULES window_ms="); |
| 149 | + Serial.print(windowMs); |
| 150 | + Serial.print(" sample_runs="); |
| 151 | + Serial.print(g_state.sampleRuns); |
| 152 | + Serial.print(" fast_avg_lag_us="); |
| 153 | + Serial.print(avgLagUs); |
| 154 | + Serial.print(" fast_max_lag_us="); |
| 155 | + Serial.print(g_state.maxLagUs); |
| 156 | + Serial.print(" fast_miss="); |
| 157 | + Serial.print(g_state.fastMisses); |
| 158 | + Serial.print(" wifi_attempts="); |
| 159 | + Serial.print(g_state.wifiConnectAttempts); |
| 160 | + Serial.print(" wifi_reconnects="); |
| 161 | + Serial.print(g_state.wifiReconnects); |
| 162 | + Serial.print(" http_ok="); |
| 163 | + Serial.print(g_state.httpSendOk); |
| 164 | + Serial.print(" http_fail="); |
| 165 | + Serial.print(g_state.httpSendFail); |
| 166 | + Serial.print(" mqtt_ok="); |
| 167 | + Serial.print(g_state.mqttSendOk); |
| 168 | + Serial.print(" mqtt_fail="); |
| 169 | + Serial.print(g_state.mqttSendFail); |
| 170 | + Serial.print(" queue_max="); |
| 171 | + Serial.println(g_state.httpMaxQueue); |
| 172 | +} |
| 173 | + |
| 174 | +} // namespace |
| 175 | + |
| 176 | +void setup() { |
| 177 | + Serial.begin(115200); |
| 178 | + delay(50); |
| 179 | + |
| 180 | + const unsigned long startedAtMs = millis(); |
| 181 | + g_state.startedAtMs = startedAtMs; |
| 182 | + g_state.lastSummaryAtMs = startedAtMs; |
| 183 | + |
| 184 | + ZeroKernel.begin(boardMillis); |
| 185 | + ZeroKernel.setIdleStrategy(zerokernel::Kernel::kIdleSleep); |
| 186 | + ZeroKernel.addTask("Sample", sampleTask, 100, 0); |
| 187 | + ZeroKernel.addTask("Queue", queueTask, 250, 0); |
| 188 | + ZeroKernel.addTask("WiFi", wifiTask, 300, 0); |
| 189 | + ZeroKernel.addTask("Http", httpTask, 200, 0); |
| 190 | + ZeroKernel.addTask("Mqtt", mqttTask, 150, 0); |
| 191 | + ZeroKernel.addTask("Report", reportTask, 1000, 0); |
| 192 | +} |
| 193 | + |
| 194 | +void loop() { |
| 195 | + zerokernel::adapters::powerSaveTick(ZeroKernel); |
| 196 | +} |
0 commit comments