Keep talking and nobody explodes Docs

Joran — Binaire led puzzel

Deze puzzel, gemaakt door Joran, is een binaire led puzzel waarbij spelers een geheim getal moeten raden door middel van een potentiometer en een drukknop. De puzzel maakt gebruik van een 4-cijferig 7-segment display en 8 binaire leds om feedback te geven over de gekozen waarde.

Foto van de binaire led puzzel

    #include <WiFi.h> // Nodig voor ESP-NOW
    // https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi
    #include <esp_now.h> //communicatie protocol
    // https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP_NOW

    #define SR_DATA 4 // Pin voor data van shift register
    #define SR_LATCH 5 // Pin voor latch van shift register
    #define SR_CLOCK 6 // Pin voor clock van shift register

    #define SEG_D1 7 // Pin voor digit 1 van 7-segment display
    #define SEG_D2 8 // Pin voor digit 2 van 7-segment display
    #define SEG_D3 9 // Pin voor digit 3 van 7-segment display
    #define SEG_D4 10 // Pin voor digit 4 van 7-segment display

    const int BIN_PINS[8] = {35, 36, 37, 38, 39, 40, 41, 42}; // Pins voor binaire leds

    #define RGB_R  45 // Pin voor rood led van RGB led
    #define RGB_G  48 // Pin voor groen led van RGB led
    #define RGB_B  47 // Pin voor blauw led van RGB led

    #define POT_PIN  1 // Pin voor potentiometer
    #define BTN_PIN  14 // Pin voor drukknop

    #define POT_MAX  4095 // Maximale waarde van potentiometer (12-bit ADC)

    uint8_t receiverMAC[] = {0x80, 0xB5, 0x4E, 0xC6, 0xF6, 0x48}; // MAC adres van wifi kit           

    enum Color { RED = 1, GREEN = 2, BLUE = 3 };
    Color cableColor;

    typedef struct { Color color; } Message;
    Message msg;

    enum Phase { BINARY,DONE };
    Phase phase = BINARY;

    uint8_t secretCode = 0;
    uint8_t selectedVal = 0;

    bool lastBtn = HIGH;
    unsigned long lastDebounce = 0;

    const uint8_t SEG_DIGITS[10] = {
      0b00111111,  // 0
      0b00000110,  // 1
      0b01011011,  // 2
      0b01001111,  // 3
      0b01100110,  // 4
      0b01101101,  // 5
      0b01111101,  // 6
      0b00000111,  // 7
      0b01111111,  // 8
      0b01101111,  // 9
    };

    const uint8_t SEG_BLANK = 0b00000000;
    const uint8_t SEG_DASH  = 0b01000000;

    uint8_t segBuf[4] = {SEG_BLANK, SEG_BLANK, SEG_BLANK, SEG_BLANK};

    void sendSegment(uint8_t data) {
      digitalWrite(SR_LATCH, LOW);
      shiftOut(SR_DATA, SR_CLOCK, MSBFIRST, data);
      digitalWrite(SR_LATCH, HIGH);
    }

    void refreshDisplay() {
      static uint32_t last = 0;
      static uint8_t digit = 0;
      if (micros() - last < 2000) return;
      last = micros();

      digitalWrite(SEG_D1, HIGH);
      digitalWrite(SEG_D2, HIGH);
      digitalWrite(SEG_D3, HIGH);
      digitalWrite(SEG_D4, HIGH);

      sendSegment(segBuf[digit]);

      switch (digit) {
        case 0: digitalWrite(SEG_D1, LOW); break;
        case 1: digitalWrite(SEG_D2, LOW); break;
        case 2: digitalWrite(SEG_D3, LOW); break;
        case 3: digitalWrite(SEG_D4, LOW); break;
      }
      digit = (digit + 1) & 0x03;
    }

    void showNumber(uint8_t val) {
      segBuf[0] = SEG_BLANK;
      segBuf[1] = (val >= 100) ? SEG_DIGITS[val / 100]       : SEG_BLANK;
      segBuf[2] = (val >= 10)  ? SEG_DIGITS[(val / 10) % 10] : SEG_BLANK;
      segBuf[3] = SEG_DIGITS[val % 10];
    }

    void showDashes() {
      for (int i = 0; i < 4; i++) segBuf[i] = SEG_DASH;
    }

    void showBinaryLEDs(uint8_t val) {
      for (int i = 0; i < 8; i++)
        digitalWrite(BIN_PINS[i], (val >> (7 - i)) & 1);
    }

    void setRGB(bool r, bool g, bool b) {
      digitalWrite(RGB_R, r);
      digitalWrite(RGB_G, g);
      digitalWrite(RGB_B, b);
    }

    void showCableRGB(Color color) {
      setRGB(color == RED, color == GREEN, color == BLUE);
    }

    void sendColor(Color color) {
      msg.color = color;
      esp_now_send(receiverMAC, (uint8_t *)&msg, sizeof(msg));
    }

    void setup() {
      pinMode(SR_DATA,  OUTPUT);
      pinMode(SR_CLOCK, OUTPUT);
      pinMode(SR_LATCH, OUTPUT);

      pinMode(SEG_D1, OUTPUT); digitalWrite(SEG_D1, HIGH);
      pinMode(SEG_D2, OUTPUT); digitalWrite(SEG_D2, HIGH);
      pinMode(SEG_D3, OUTPUT); digitalWrite(SEG_D3, HIGH);
      pinMode(SEG_D4, OUTPUT); digitalWrite(SEG_D4, HIGH);

      for (int i = 0; i < 8; i++) pinMode(BIN_PINS[i], OUTPUT);

      pinMode(RGB_R, OUTPUT);
      pinMode(RGB_G, OUTPUT);
      pinMode(RGB_B, OUTPUT);

      pinMode(BTN_PIN, INPUT);

      analogReadResolution(12);
      analogSetPinAttenuation(POT_PIN, ADC_11db);

      WiFi.mode(WIFI_STA);
      esp_now_init();
      esp_now_peer_info_t peer = {};
      memcpy(peer.peer_addr, receiverMAC, 6);
      peer.channel = 0;
      peer.encrypt = false;
      esp_now_add_peer(&peer);

      randomSeed(analogRead(0));
      secretCode = random(1, 256);
      cableColor = (Color)random(1, 4);

      showBinaryLEDs(secretCode);
      setRGB(false, false, false);
    }

    void loop() {
      refreshDisplay();

      if (phase == DONE) return;

      if (phase == BINARY) {
        static int filtered = 0;

        int raw = analogRead(POT_PIN);
        filtered = (filtered * 7 + raw) / 8;

        int clamped = constrain(filtered, 0, POT_MAX);
        selectedVal = map(clamped, 0, POT_MAX, 0, 255);

        showNumber(selectedVal);

        bool btn = digitalRead(BTN_PIN);

        if (btn == LOW && lastBtn == HIGH && millis() - lastDebounce > 80) {
          lastDebounce = millis();

          int margin = max(1, secretCode * 5 / 100);
          bool correct = abs(selectedVal - secretCode) <= margin;

          int specialMargin = 5;
          bool isSpecial = abs(selectedVal - 100) <= specialMargin;

          if (correct || isSpecial) {
            showCableRGB(cableColor);
            sendColor(cableColor);
            showDashes();
            phase = DONE;
          }
        }

        lastBtn = btn;
      }
    }
          
Tinkercad schema voor de binaire puzzel