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.
#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;
}
}