/* __ __ _______ _ _ __ __ | \/ | |__ __| (_|_) \/ | | \ / | __ _ _ __ __ _| |_ _____ _ _| \ / | __ _ _ __ ___ _ _ | |\/| |/ _` | '_ \ / _` | \ \ / / _ \| | | |\/| |/ _` | '_ ` _ \| | | | | | | | (_| | |_) | (_| | |\ V / (_) | | | | | | (_| | | | | | | |_| | |_| |_|\__,_| .__/ \__,_|_| \_/ \___/| |_|_| |_|\__,_|_| |_| |_|\__, | | | _/ | __/ | |_| |__/ |___/ Simple quiz "which district is lightened up?" Info about map: https://wiki.tmep.cz/doku.php?id=ruzne:led_mapa_okresu_cr Used components: - MapaTvojiMamy - LaskaKit ESP32-LPkit v2.4 - 0.91" OLED - Catalex touch sensor v2.0 (simply some capacative touch sensor) */ //////////////////// // Variables setup //////////////////// // After how go to "sleep" (LEDs off, display off, "wake up" by touching button) - default 5 minutes unsigned long offDelay = 300000; // LED strip - MapaTvojiMamy #define LEDS_COUNT 77 #define LEDS_PIN 14 #define CHANNEL 0 #define LEDS_BRIGHTNESS 10 // Touch button #define BUTTON_PIN 16 #define STATE_WHEN_TOUCHED HIGH // Display PINs #define DISPLAY_CLOCK_PIN 25 #define DISPLAY_DATA_PIN 26 // Variables for two lines of OLED display char *displayText1 = ""; char *displayText2 = ""; // Array with districts, index from 0 to corresponding LED char *districts[] { "Cheb", "Sokolov", "Karlovy Vary", "Chomutov", "Louny", "Most", "Teplice", "Litomerice", "Usti nad Labem", "Decin", "Ceska Lipa", "Liberec", "Jablonec nad Nisou", "Semily", "Jicin", "Trutnov", "Nachod", "Hradec Kralove", "Rychnov nad Kneznou", "Usti nad Orlici", "Pardubice", "Chrudim", "Svitavy", "Sumperk", "Jesenik", "Bruntal", "Olomouc", "Opava", "Ostrava-mesto", "Karvina", "Frydek-Mistek", "Novy Jicin", "Vsetin", "Prerov", "Zlin", "Kromeriz", "Uherske Hradiste", "Hodonin", "Vyskov", "Prostejov", "Blansko", "Brno-mesto", "Brno-venkov", "Breclav", "Znojmo", "Trebic", "Zdar nad Sazavou", "Jihlava", "Havlickuv Brod", "Pelhrimov", "Jindrichuv Hradec", "Tabor", "Ceske Budejovice", "Cesky Krumlov", "Prachatice", "Strakonice", "Pisek", "Klatovy", "Domazlice", "Tachov", "Plzen-sever", "Plzen-mesto", "Plzen-jih", "Rokycany", "Rakovnik", "Kladno", "Melnik", "Mlada Boleslav", "Nymburk", "Kolin", "Kutna Hora", "Benesov", "Pribram", "Beroun", "Praha-zapad", "Praha-vychod", "Praha" }; /////////// // Code /////////// // Display #include #include U8G2_SSD1306_128X32_UNIVISION_1_SW_I2C u8g2(U8G2_R0, DISPLAY_CLOCK_PIN, DISPLAY_DATA_PIN, U8X8_PIN_NONE); // Strip #include "Freenove_WS2812_Lib_for_ESP32.h" Freenove_ESP32_WS2812 strip = Freenove_ESP32_WS2812(LEDS_COUNT, LEDS_PIN, CHANNEL, TYPE_GRB); // To know when we should go to sleep unsigned long lastTouchTime = 0; // More things to initialize int lastId = 50, isOn = 1, firstTime = 1, gameTime = 0; void setup() { u8g2.begin(); pinMode(BUTTON_PIN, INPUT); Serial.begin(115200); delay(5); Serial.println(); strip.begin(); strip.setBrightness(LEDS_BRIGHTNESS); } void randomLEDs() { for(int i = 0; i < LEDS_COUNT; i = i + 1) { strip.setLedColorData(i, strip.Wheel(map(rand() % 100, -15, 40, 170, 0))); } strip.show(); } void powerDown() { Serial.println("go offline"); isOn = 0; strip.setBrightness(0); randomLEDs(); u8g2.setPowerSave(true); } void powerUp() { isOn = 1; firstTime = 1; Serial.println("go online"); strip.setBrightness(LEDS_BRIGHTNESS); u8g2.setPowerSave(false); } void waitForButtonTouch() { int ButtonTouched = 0; while(ButtonTouched == 0) { boolean newState = digitalRead(BUTTON_PIN); // Touching the button? if(newState == STATE_WHEN_TOUCHED) { ButtonTouched = 1; // Are we offline? "Power up"! if(isOn == 0) { powerUp(); } lastTouchTime = millis(); Serial.print("Button touched."); // Reset button state to untouched break; } // Let's go "offline" if(isOn == 1 && ((millis() - lastTouchTime) > offDelay)) { powerDown(); } } } void drawOnDisplay() { u8g2.firstPage(); do { u8g2.setFont(u8g2_font_ncenB10_tr); u8g2.drawStr(0, 12, displayText1); u8g2.drawStr(0, 26, displayText2); } while (u8g2.nextPage()); } void countDownProcedure() { drawOnDisplay(); strip.setBrightness(LEDS_BRIGHTNESS); randomLEDs(); delay(200); strip.setBrightness(6); strip.setAllLedsColor(204, 204, 204); strip.show(); delay(200); } void loop() { // First time? Run intro! if(isOn == 1 && firstTime == 1) { // Something like "animation" randomLEDs(); displayText1 = "Mapa"; displayText2 = "OKR"; drawOnDisplay(); delay(1000); randomLEDs(); displayText1 = "MapaTvoji"; displayText2 = "OKRESNI"; drawOnDisplay(); delay(1000); randomLEDs(); displayText1 = "MapaTvojiMamy"; displayText2 = "OKRESNI KVIZ"; drawOnDisplay(); for(int i = 6; i > 0; i = i - 1) { delay(i * 100); randomLEDs(); } displayText1 = "MapaTvojiMamy"; displayText2 = "Dotkni se! :)"; drawOnDisplay(); waitForButtonTouch(); displayText1 = "Budeme hrat!"; displayText2 = "Priprav se..."; drawOnDisplay(); delay(1000); displayText1 = "HRAJEM!"; displayText2 = ""; drawOnDisplay(); delay(1000); firstTime = 0; } // Let's play! while(isOn == 1 && firstTime == 0) { displayText2 = ""; displayText1 = "3"; countDownProcedure(); displayText1 = "2"; countDownProcedure(); displayText1 = "1"; countDownProcedure(); // Random district int districtID = 0; int generate = 1; while(generate == 1) { districtID = esp_random() % 100; if(districtID < LEDS_COUNT) { generate = 0; } } // Show district on map for(int i = 0; i < LEDS_COUNT; i = i + 1) { if(i == districtID) { strip.setBrightness(LEDS_BRIGHTNESS); strip.setLedColorData(i, 0x00FF00); } else { strip.setBrightness(3); strip.setLedColorData(i, 0xCCCCCC); } } strip.show(); displayText1 = "Jaky je to okres?"; displayText2 = "Dotkni se!"; drawOnDisplay(); // Blink with district we are guessing strip.setBrightness(LEDS_BRIGHTNESS); for(int i = 0; i < 12; i = i + 1) { if(i % 2 == 1) { strip.setLedColorData(districtID, 0x00FF00); } else { strip.setLedColorData(districtID, 0xFF0000); } strip.show(); delay(200); } waitForButtonTouch(); // Didn't woke up? Show answer and move on if(firstTime == 0) { displayText1 = "Odpoved je..."; displayText2 = ""; drawOnDisplay(); delay(500); displayText1 = districts[districtID]; drawOnDisplay(); delay(3000); } } // Show texts on display if(isOn == 1) { drawOnDisplay(); } }