• Scrambled

    Rhea Rae5 hours ago 0 comments

    If screen is scrambled switch pin D13 and D11.

    -RR

  • ST7920 Pin-Out

    Rhea Rae5 hours ago 0 comments

    Use EXP 3 Header!

    -RR

  • Ender Clock-Duino v1.0 Sketch

    Rhea Rae5 hours ago 0 comments

    #include <Arduino.h>
    #include <U8g2lib.h>
    #include <EEPROM.h>

    // ================= LCD =================
    const uint8_t PIN_LCD_CS = 10; // CS/RS
    U8G2_ST7920_128X64_1_HW_SPI u8g2(U8G2_R0, PIN_LCD_CS, U8X8_PIN_NONE);

    // ================= ENCODER =================
    const uint8_t PIN_ENC_A   = 2;
    const uint8_t PIN_ENC_B   = 3;
    const uint8_t PIN_ENC_BTN = 4;

    // If your encoder changes 2 numbers per click, set this to 2.
    // If it changes 1 per click, leave at 4.
    const int8_t TRANSITIONS_PER_DETENT = 4;

    // ================= UI TIMING =================
    const uint16_t LONG_MS     = 700;
    const uint16_t DEBOUNCE_MS = 25;

    // ================= EEPROM =================
    const int EEPROM_SIG_ADDR   = 0;
    const int EEPROM_TIME_ADDR  = 1;               // uint32_t (4 bytes)
    const int EEPROM_CHIME_ADDR = EEPROM_TIME_ADDR + 4; // uint8_t
    const int EEPROM_VOL_ADDR   = EEPROM_CHIME_ADDR + 1; // uint8_t
    const uint8_t EEPROM_SIG    = 0xA5;            // marker that EEPROM has valid data

    // ================= BUZZER =================
    const uint8_t PIN_BUZZER = 8;

    // Chime settings (editable, saved)
    bool    chime_enabled = true;
    uint8_t chime_volume_percent = 18; // editable 0..100 (0 = silent)

    // ================= CLOCK CORE =================
    uint32_t clock_sec = 0;
    uint32_t last_tick_ms = 0;

    // ================= SET MODE FIELDS =================
    bool set_mode = false;

    uint8_t edit_hour12 = 12;   // 1..12
    uint8_t edit_min    = 0;    // 0..59
    uint8_t edit_sec    = 0;    // 0..59 (frozen in SET)
    bool    edit_pm     = false; // false=AM, true=PM

    bool    edit_chime_enabled = true;
    uint8_t edit_volume_percent = 18;

    enum Sel : uint8_t { SEL_HOUR, SEL_MIN, SEL_AMPM, SEL_CHIME, SEL_VOL, SEL_TEST };
    Sel sel = SEL_HOUR;

    uint32_t saved_banner_until_ms = 0;

    // Track last hour we chimed so we only do it once per hour
    int8_t last_chimed_h24 = -1;

    // ================= ENCODER ISR =================
    volatile int16_t enc_delta = 0;
    volatile uint8_t enc_prev  = 0;

    static const int8_t ENC_TAB[16] = {
      0, -1,  1,  0,
      1,  0,  0, -1,
     -1,  0,  0,  1,
      0,  1, -1,  0
    };

    void enc_isr() {
      uint8_t a = digitalRead(PIN_ENC_A) ? 1 : 0;
      uint8_t b = digitalRead(PIN_ENC_B) ? 1 : 0;
      uint8_t cur = (a << 1) | b;
      uint8_t idx = (enc_prev << 2) | cur;
      enc_prev = cur;
      enc_delta += ENC_TAB[idx];
    }

    // ================= BUTTON =================
    bool btn_last_raw = true;
    bool btn_stable   = true;
    uint32_t btn_change_ms = 0;
    uint32_t btn_down_ms   = 0;
    bool long_fired = false;

    static void poll_button(bool &short_press, bool &long_press) {
      short_press = false;
      long_press  = false;

      bool raw = digitalRead(PIN_ENC_BTN); // HIGH idle, LOW pressed
      uint32_t now = millis();

      if (raw != btn_last_raw) {
        btn_last_raw = raw;
        btn_change_ms = now;
      }

      if ((now - btn_change_ms) > DEBOUNCE_MS) {
        if (btn_stable != raw) {
          btn_stable = raw;
          if (btn_stable == LOW) {
            btn_down_ms = now;
            long_fired = false;
          } else {
            if (!long_fired) short_press = true;
          }
        }
      }

      if (btn_stable == LOW && !long_fired && (now - btn_down_ms) >= LONG_MS) {
        long_fired = true;
        long_press = true;
      }
    }

    // ================= HELPERS =================
    static uint32_t wrap_day(uint32_t sec) { return sec % 86400UL; }

    static void sec_to_hms(uint32_t sec, uint8_t &h24, uint8_t &m, uint8_t &s) {
      sec = wrap_day(sec);
      h24 = sec / 3600UL;
      m   = (sec / 60UL) % 60UL;
      s ...

    Read more »