#ifndef BROSE9323_H #define BROSE9323_H #include #include "dot_sequence.h" #ifdef ESPSERIAL #include "frame_commands.h" #endif //#define FLIPDOT_PLCC_ADAPTER // ESPSERIAL is set per target via build_flags in platformio.ini (-D ESPSERIAL for the ESP32) class BROSE9323 : public Adafruit_GFX { private: uint16_t _flip_time; uint16_t _flip_gap = 0; // pause after each pulse in us, lets the coil supply recover uint8_t _pulses = 1; // pulses for each dot that changed uint8_t _effect = EFFECT_INSTANT; uint16_t _effect_time = 1500; // ms, how long an effect takes uint8_t _effect_flags = 0; // EFFECT_FLAG_... const uint8_t _panel_width; const uint8_t _buffer_width; const uint16_t _buffer_size; uint8_t *_old_buffer = NULL; uint8_t *_new_buffer = NULL; bool _direct_mode = false; #ifdef ESPSERIAL Stream *stream; #else uint8_t _active_panel = 255; uint8_t _active_col = 255; uint8_t _active_row = 255; bool _active_data; // After boot the physical dot state is unknown, so the first display() redraws everything bool _force_next = true; // A running effect (display() with an effect other than EFFECT_INSTANT) DotSequence _sequence; bool _animating = false; uint8_t _running_effect = EFFECT_INSTANT; // _effect, or the one chosen for EFFECT_RANDOM uint8_t _phase = 0; // EFFECT_FLAP: 0 = to yellow, 1 = the new image uint8_t _push_shift = 0; // EFFECT_PUSH: column shift 1..width uint16_t _push_pos = 0; // EFFECT_PUSH: dot within the shift bool _animate_all = false; // flip every dot, not only the changed ones bool _drawing = false; // the buffer changed since the last display(): pause uint32_t _step_time = 0; // us per step uint32_t _next_step = 0; // micros() of the next step #ifndef FLIPDOT_PLCC_ADAPTER const uint8_t ENABLE = 7, ADDR_0 = 3, ADDR_1 = 5, ADDR_2 = 6, COL_DATA = 4, COL_0 = 8, COL_1 = 10, COL_2 = 9, COL_3 = 11, COL_4 = 12, ROW_0 = A3, ROW_1 = A4, ROW_2 = A2, ROW_3 = A0, ROW_4 = A1, ROW_RESET = 13, ROW_SET = A5; #else const uint8_t RELAY = 2, ENABLE = 3, ADDR_0 = 7, ADDR_1 = 6, ADDR_2 = 5, COL_DATA = 4, COL_0 = 12, COL_1 = 11, COL_2 = 10, COL_3 = 9, COL_4 = 8, ROW_0 = 13, //1 A1 CHECK ROW_1 = A0, //2 A2 ROW_2 = A1, //4 A3 ROW_3 = A2, //8 13 CHECK ROW_4 = A3, //F A0 ROW_RESET = A4, ROW_SET = A5; #endif void _selectColumn(uint8_t); void _selectPanel(uint8_t); void _selectRow(uint8_t); void _setData(bool); void _strobe(void); bool _shown(uint8_t x, uint8_t y) const; bool _changed(uint8_t x, uint8_t y) const; bool _wanted(uint8_t x, uint8_t y) const; void _flipTo(uint8_t x, uint8_t y, bool on, uint8_t pulses); void _flipDot(uint8_t x, uint8_t y, uint8_t pulses); bool _pushDot(void); void _drawAll(bool all); void _startEffect(bool all); #endif public: BROSE9323(uint8_t, uint8_t, uint8_t, uint16_t ft = 280); #ifdef ESPSERIAL void begin(Stream * = &Serial); // Shows a full screen bitmap (drawBitmap format) and ends the frame (D, or D1 when // instant). changes_only: only the dots that differ from the last frame are sent // (frame_commands.h); otherwise the whole screen. Returns the characters sent (0: // nothing changed, nothing sent). size_t showBitmap(const uint8_t *bitmap, bool changes_only, bool instant = false); #endif void begin(void); // Shows the buffer: the changed dots, all with force. instant: without the refresh // effect (frames of moving content, e.g. scrolling text). ESP32: sends D or D1. void display(bool force = false, bool instant = false); void drawPixel(int16_t x, int16_t y, uint16_t color); void fillScreen(uint16_t); void setDirect(bool); void setTiming(uint16_t); // Pause after each flip pulse in us void setGap(uint16_t); // Pulses for each changed dot (a second pulse catches dots that didn't flip). Full // redraws use one pulse per dot. void setPulses(uint8_t); // How display() shows a new frame (RefreshEffect), how long it takes in ms (pushing // can take longer: it flips many dots per step) and EFFECT_FLAG_... flags. // Effects run in steps from update(), so call that often (every loop). void setEffect(uint8_t effect, uint16_t time_ms, uint8_t flags = 0); #ifndef ESPSERIAL // Runs the next steps of an effect. Returns busy(). bool update(void); // An effect is running (paused while a new frame is being drawn into the buffer) bool busy(void) const; #endif #ifndef ESPSERIAL void printBuffer(void); #endif size_t print(const char *ifsh); // State of a dot as of the last display() call (ESP32: shadow copy for the web UI) bool shownPixel(int16_t x, int16_t y) const; }; #endif //BROSE9323_H