Public Access
Fix shifted pictures: non-blocking Nano drawing, frame check, refresh settings
The Nano's periodic full redraw blocked for ~0.8 s. A frame that arrived meanwhile overflowed its 64-byte serial buffer; lost bytes in a bitmap shift the rest of the image (picture moved up), and diff frames never repaired it. - Nano: all drawing (frames, effects, the dot refresh) runs from update() in ~1 ms slices; the refresh pauses while a frame is received or shown - New commands: C (reply with the image checksum) and I (refresh minutes, EEPROM) - ESP32: NanoMonitor asks for the checksum after frames and sends the whole image again on a mismatch, missing answer or Nano restart; counts ERR replies. Periodic whole-image resync. - Settings: "Dot refresh" and "Image resync" intervals (settings v5, v4 records are migrated) - System tab: loop timing, free memory, frame check counts - test_driver: the real driver against a simulated panel Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
58a7cb03c2
commit
090c2bf8ae
45 files changed
+1265
-157
No files matched your search
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Checks that the Nano shows what was sent. The Nano has no acknowledgement and drops
|
||||
// bytes when its serial buffer overflows; a lost byte in a bitmap shifts the rest of the
|
||||
// image (the dots after it land too early). After a frame the ESP32 asks for the checksum
|
||||
// of the Nano's image (C command, bufferCrc() in lib/BROSE9323) and compares it with its
|
||||
// own copy. A wrong checksum, a missing answer or a restarted Nano (READY) makes it send
|
||||
// the whole image again (repair). Besides that the whole image is sent again every
|
||||
// resync interval, which also fixes what the check can't see.
|
||||
//
|
||||
// Pure logic (tested in test/test_esp32); nano_link/nano_monitor does the serial part.
|
||||
|
||||
struct FrameCheckStats
|
||||
{
|
||||
uint32_t checks = 0; // answers that matched
|
||||
uint32_t mismatches = 0; // answers that didn't
|
||||
uint32_t no_reply = 0; // checks without an answer in FRAME_CHECK_TIMEOUT
|
||||
uint32_t errors = 0; // ERR: lines from the Nano
|
||||
uint32_t restarts = 0; // READY while it was on: the Nano restarted (power dip?)
|
||||
uint32_t repairs = 0; // whole image sent again because of one of the above
|
||||
char last_error[48] = "";
|
||||
};
|
||||
|
||||
class FrameCheck
|
||||
{
|
||||
public:
|
||||
// The Nano was switched on or off: forget the check in progress
|
||||
void reset(uint32_t now);
|
||||
|
||||
// A check (C) should be sent now: a frame was sent since the last one (frames_sent
|
||||
// changed), none is waiting for its answer and the last one is FRAME_CHECK_INTERVAL ago
|
||||
bool due(uint32_t frames_sent, uint32_t now) const;
|
||||
// The C was sent; expected: the checksum of the ESP32's copy
|
||||
void sent(uint16_t expected, uint32_t frames_sent, uint32_t now);
|
||||
|
||||
// One line from the Nano (without the '\n')
|
||||
void line(const char *text, uint32_t now);
|
||||
|
||||
// Call each loop(). True: send the whole image now (repair, or every resync_ms; 0 = no
|
||||
// periodic resync)
|
||||
bool resyncNow(uint32_t now, uint32_t resync_ms);
|
||||
|
||||
const FrameCheckStats &stats() const { return _stats; }
|
||||
|
||||
private:
|
||||
FrameCheckStats _stats;
|
||||
bool _pending = false;
|
||||
uint16_t _expected = 0;
|
||||
uint32_t _sent_at = 0;
|
||||
bool _checked_any = false; // since reset()
|
||||
uint32_t _checked_frames = 0;
|
||||
uint32_t _last_check = 0;
|
||||
bool _replied = false; // the Nano answered since reset(): its TX is wired
|
||||
bool _problem = false; // repair at the next chance
|
||||
uint32_t _last_resync = 0;
|
||||
};
|
||||
Reference in new issue
Block a user