#pragma once #include "UiTypes.h" #include "Config.h" // Nextion serial HMI driver. No Nextion library - the protocol is small: // // Nextion -> remote: custom frames the HMI's touch events send with printh: // '#' [value] e.g. printh 23 01 41 (ToggleArm) // printh 23 02 56 + prints hSpeed.val,1 // Command bytes are listed in NEXTION.md and in NextionUI.cpp. // Native Nextion return frames (terminated FF FF FF) are also parsed so a // display reset (0x88 "ready") triggers a full redraw. // // remote -> Nextion: plain instructions ("bArm.txt=\"ARMED\"" + FF FF FF). // // The remote is authoritative: buttons are plain buttons (not dual-state), // they only send requests, and render() repaints whatever the remote state // actually is. A Nextion reboot or a dropped byte self-heals on the next // periodic full refresh. class NextionUI { public: void begin(); bool poll(UiEvent& out); // call every loop; returns one decoded event at a time void render(const UiView& v, uint32_t now_ms); private: enum class Rx : uint8_t { Idle, CustomLen, CustomBody, Native }; Rx rx_ = Rx::Idle; uint8_t body_[4]; uint8_t body_len_ = 0, body_got_ = 0; uint8_t native_first_ = 0, native_len_ = 0, ff_run_ = 0; UiView shown_; bool force_full_ = true; uint32_t last_full_ms_ = 0; uint32_t last_link_ms_ = 0; void cmd(const char* fmt, ...); void pushState(const UiView& v, bool full); void pushLink(const UiView& v); bool decodeCustom(UiEvent& out); };