diff --git a/client/client.ino b/client/client.ino new file mode 100644 index 0000000000000000000000000000000000000000..279748f7e27b47796de9b3b2eee1bd2a350ff4b0 --- /dev/null +++ b/client/client.ino @@ -0,0 +1,188 @@ +#include <WiFi.h> +#include <Ticker.h> +#include <WiFiManager.h> + +#define LED0 26 +#define LED1 18 +#define LED2 19 +#define BUTTON 22 + +IPAddress server(192,168,4,1); +WiFiClient client; +WiFiManager wifiManager; + +Ticker tickerPing; +Ticker tickerGame; +Ticker tickerToggle; +Ticker tickerEnd; + +char stringBuffer[50]; +int bufferLength = 0; +int buttonState = 0; +int lastButtonState = 0; +int gameBuffer = -1; +int gameCount = 0; +int id = -1; + +unsigned long elapsedTime = 0; +unsigned long pressedTime = 0; + +enum GameState { + IDLE, // Ruhezustand + GAME_1, // Spiel 1 Reaktionsspiel + GAME_2, // Spiel 2 Quiz + GAME_3, // Spiel 3, usw. + OPTION_MENU, // Optionen anzeigen +}; + +GameState gameState = IDLE; + +// Ping an Server senden +void tickPing(){ + client.println("<PING>"); +} + +// LED blinken lassen +void toggle(int led){ + digitalWrite(led, !digitalRead(led)); +} + +void end(){ + tickerToggle.detach(); +} + +// im Config-Mode LED blau blinken lassen +void configModeCallback (WiFiManager *myWiFiManager) { + tickerToggle.attach(0.2, toggle, LED1); +} + +void setup(){ + Serial.begin(115200); + + pinMode(LED0, OUTPUT); + pinMode(LED1, OUTPUT); + pinMode(LED2, OUTPUT); + + pinMode(BUTTON, INPUT); + + tickerToggle.attach(1.0, toggle, LED1); + + //wifiManager.resetSettings(); + wifiManager.setAPCallback(configModeCallback); + + if (!wifiManager.autoConnect("AutoConnectAP")) { + Serial.println("failed to connect and hit timeout"); + ESP.restart(); + delay(1000); + } + + Serial.println(WiFi.softAPIP()); + Serial.println("!--- Connecting To " + wifiManager.getConfigPortalSSID() + " ---!"); + + tickerToggle.detach(); + digitalWrite(LED1, LOW); + + Serial.println("!-- Client Device Connected --!"); + + Serial.println("Connected To : " + String(WiFi.SSID())); + Serial.println("Signal Strenght : " + String(WiFi.RSSI()) + " dBm"); + Serial.print ("Server IP Address : "); + Serial.println(server); + Serial.print ("Device IP Address : "); + Serial.println(WiFi.localIP()); + + client.stop(); + if(client.connect(server, 9001)){ + Serial.println ("<CONNECTED>"); + client.println ("<CONNECTED>"); + tickerPing.attach(1.0, tickPing); + } +} + +void loop(){ + if(WiFi.status() != WL_CONNECTED){ + ESP.restart(); + delay(1000); + } + + buttonState = digitalRead(BUTTON); + + if(lastButtonState == LOW && buttonState == HIGH){ // button gedrückt + pressedTime = millis(); + + if(gameState == GAME_1){ + client.println("<PRESSED>"); + } + } + else if(lastButtonState == HIGH && buttonState == LOW) { // button losgelassen + elapsedTime = millis() - pressedTime; + + if(elapsedTime > 15000){ // neustarten + wifiManager.resetSettings(); + ESP.restart(); + delay(1000); + } + else if(elapsedTime >= 6000){ // id anzeigen + tickerToggle.attach(0.5, toggle, LED1); + tickerEnd.once(id, end); + } + else if(elapsedTime >= 4000 && gameState == GAME_2){ // Spiel 2 aktuelle Punktzahl + tickerToggle.attach(0.5, toggle, LED1); + tickerEnd.once(gameCount, end); + } + else if(elapsedTime >= 2000 && gameState == GAME_2){ // Spiel 2 Rücksetzen, wer zurücksetzt bekommt einen Punkt + gameCount++; + client.println("<OFF>"); + } + else if(elapsedTime >= 50 && gameState == GAME_2){ // Spiel 2 spielen + client.println("<PRESSED>"); + } + + } + lastButtonState = buttonState; + + if(client.available()){ + char c = client.read(); + if((int)c >= 32 && bufferLength < 50 - 1){ + stringBuffer[bufferLength++] = c; + } + else if(c == '\n'&& bufferLength > 0){ + stringBuffer[bufferLength] = '\0'; + + if(strstr(stringBuffer, "<GREEN>")){ + digitalWrite(LED0, HIGH); + }else if(strstr(stringBuffer, "<BLUE>")){ + digitalWrite(LED1, HIGH); + }else if(strstr(stringBuffer, "<ORANGE>")){ + digitalWrite(LED2, HIGH); + }else if(strstr(stringBuffer, "<OFF>")){ + digitalWrite(LED0, LOW); + digitalWrite(LED1, LOW); + digitalWrite(LED2, LOW); + }else if (strstr(stringBuffer, "<ID_")) { + char *start = stringBuffer + 4; + char *end = strstr(stringBuffer, ">"); + if (end != nullptr) { + *end = '\0'; + id = atoi(start); + } + }else if (strstr(stringBuffer, "<GAME_")) { + char *start = stringBuffer + 6; + char *end = strstr(stringBuffer, ">"); + if (end != nullptr) { + *end = '\0'; + gameBuffer = atoi(start); + gameState = static_cast<GameState>(gameBuffer); + gameBuffer = -1; + } + }else if (strstr(stringBuffer, "<IDLE>")) { + digitalWrite(LED0, LOW); + digitalWrite(LED1, LOW); + digitalWrite(LED2, LOW); + gameState = IDLE; + gameBuffer = -1; + } + bufferLength = 0; + } + } +} diff --git a/server/server.ino b/server/server.ino new file mode 100644 index 0000000000000000000000000000000000000000..30dd0d518eac9bf59fa71adf9d48fc6370a4ad7e --- /dev/null +++ b/server/server.ino @@ -0,0 +1,329 @@ +#include <WiFi.h> +#include <Ticker.h> + +#define LED0 26 +#define LED1 18 +#define LED2 19 +#define BUTTON 22 +#define MAXSC 5 +#define GAMES 2 + +const char *ssid = "Buzzer"; +const char *password = "00000000"; + +WiFiServer server(9001); +WiFiClient clients[MAXSC]; + +Ticker tickerClients; +Ticker tickerPing; +Ticker tickerGame; +Ticker tickerToggle; +Ticker tickerEnd; + +int clientState[MAXSC] = {0}; +int bufferLength[MAXSC] = {0}; + +char stringBuffer[MAXSC][20] = {""}; + +int gameBuffer = -1; +int gameCount = 0; +int buttonState = 0; +int lastButtonState = 0; + +unsigned long elapsedTime = 0; +unsigned long pressedTime = 0; +unsigned long startTime = 0; + +enum GameState { + IDLE, // Ruhezustand + GAME_1, // Spiel 1 Reaktionsspiel + GAME_2, // Spiel 2 Quiz + GAME_3, // Spiel 3, usw. + OPTION_MENU, // Optionen anzeigen +}; + +GameState gameState = IDLE; + +void newButtonGame1(){ + int count = 1; + int old = gameBuffer; + + for(int i = 1; i < MAXSC; i++){ + if(clients[i].connected()){ + clients[i].println("<OFF>"); + count++; + } + } + gameBuffer = random(2, count + 1); + count = 0; + for(int i = old; i <= MAXSC; i++){ + if(i == MAXSC){ + i = 0; + } + + if(i == 0){ + count++; + } + else if(clients[i].connected()){ + count++; + } + if(count == gameBuffer){ + gameBuffer = i; + gameCount++; + if(gameBuffer == 0){ + digitalWrite(LED0, HIGH); + } + else{ + clients[gameBuffer].println("<GREEN>"); + } + break; + } + } +} + +void tickPing(){ + for(int i = 1; i < MAXSC; i++){ + if(clientState[i]){ + if(clientState[i] == 2){ + clients[i].stop(); + clientState[i] = 0; + if(i == gameBuffer && gameState == GAME_1){ + newButtonGame1(); + } + Serial.print(i); Serial.println(": disconnect"); + continue; + } + clientState[i] = 2; + } + } +} + +void tickClients(){ + if (server.hasClient()){ + for(int i = 1; i <= MAXSC; i++){ + if(i == MAXSC){ + WiFiClient client = server.available(); + client.stop(); + break; + } + + if(!clients[i].connected()){ + clients[i].stop(); + clients[i] = server.available(); + clientState[i] = 1; + clients[i].println("<ID_" + String(i) + ">"); + if(gameState == GAME_1 || gameState == GAME_2 ){ + clients[i].println("<GAME_" + String(gameState) + ">"); + } + break; + } + } + } +} + +// LED blinken lassen +void toggle(int led){ + digitalWrite(led, !digitalRead(led)); +} + +void end(){ + tickerToggle.detach(); +} + +void tickGame(int time){ + tickerToggle.attach(0.5, toggle, LED1); + tickerEnd.once(time, end); +} + +void setup(){ + delay(1000); + Serial.begin(115200); + + pinMode(LED0, OUTPUT); + pinMode(LED1, OUTPUT); + pinMode(LED2, OUTPUT); + + pinMode(BUTTON, INPUT); + + SetWifi(); +} + +void loop(){ + buttonState = digitalRead(BUTTON); + + if(lastButtonState == LOW && buttonState == HIGH){ // button gedrückt + pressedTime = millis(); + if(gameState == GAME_1 && gameBuffer == 0){ // Spiel1 spielen + digitalWrite(LED0, LOW); + newButtonGame1(); + } + } + else if(lastButtonState == HIGH && buttonState == LOW) { // button losgelassen + elapsedTime = millis() - pressedTime; + + if(elapsedTime > 15000){ // neustarten + ESP.restart(); + delay(1000); + } + else if(elapsedTime >= 10000){ // Anzahl Clients anzeigen + int count = 0; + for(int i = 1; i < MAXSC; i++){ + if (clients[i].connected()){ + count++; + } + } + tickerToggle.attach(0.5, toggle, LED1); + tickerEnd.once(count, end); + } + + else if(elapsedTime >= 5000 && gameState == IDLE){ // Option öffnen + gameState = OPTION_MENU; + gameBuffer = 1; + tickerGame.attach(gameBuffer + 2, tickGame, gameBuffer); + } + else if(elapsedTime >= 5000 && gameState == OPTION_MENU){ // Option schließen + tickerGame.detach(); + gameState = static_cast<GameState>(gameBuffer); + for(int i = 1; i < MAXSC; i++){ + if(clients[i].connected()){ + clients[i].println("<GAME_" + String(gameState) + ">"); + } + } + gameBuffer = -1; + + if(gameState == GAME_1){ + gameBuffer = 0; + gameCount = 0; + startTime = millis(); + newButtonGame1(); + } + } + else if(elapsedTime >= 8000 && ( gameState == GAME_1 || gameState == GAME_2 )){ // Spiel beenden + digitalWrite(LED0, LOW); + digitalWrite(LED1, LOW); + digitalWrite(LED2, LOW); + gameState = IDLE; + gameBuffer = -1; + gameCount = 0; + for(int i = 1; i < MAXSC; i++){ + if(clients[i].connected()){ + clients[i].println("<IDLE>"); + } + } + } + else if(elapsedTime >= 50 && gameState == OPTION_MENU){ // Optionen hochzählen + gameBuffer++; + if(gameBuffer > GAMES){ + gameBuffer = 1; + } + tickerGame.attach(gameBuffer + 2, tickGame, gameBuffer); + } + + else if(elapsedTime >= 4000 && gameState == GAME_2){ // Spiel 2 aktuelle Punktzahl + tickerToggle.attach(0.5, toggle, LED1); + tickerEnd.once(gameCount, end); + } + else if(elapsedTime >= 2000 && gameState == GAME_2){ // Spiel 2 Rücksetzen, wer zurücksetzt bekommt einen Punkt + digitalWrite(LED0, LOW); + digitalWrite(LED2, LOW); + gameBuffer = -1; + gameCount++; + for(int i = 1; i < MAXSC; i++){ + if(clients[i].connected()){ + clients[i].println("<OFF>"); + } + } + } + else if(elapsedTime >= 50 && gameState == GAME_2 && gameBuffer == -1){ // Spiel2 spielen + digitalWrite(LED0, HIGH); + gameBuffer = 0; + for(int i = 1; i < MAXSC; i++){ + if(clients[i].connected()){ + clients[i].println("<ORANGE>"); + } + } + } + } + lastButtonState = buttonState; + + for(int i = 1; i < MAXSC; i++){ + if (clients[i].connected()){ + while(clients[i].available()){ + char c = clients[i].read(); + if((int)c >= 32 && bufferLength[i] < 20 - 1){ + stringBuffer[i][bufferLength[i]++] = c; + } + else if(c == '\n' && bufferLength[i] > 0){ + stringBuffer[i][bufferLength[i]] = '\0'; + Serial.print(String(i) + ": "); + Serial.println(stringBuffer[i]); + + if(strstr(stringBuffer[i], "<PRESSED>")){ + if(gameState == GAME_1 && i == gameBuffer){ // Spiel 1 + newButtonGame1(); + } + else if(gameState == GAME_2){ //Spiel 2 + if(gameBuffer == -1){ + gameBuffer = i; + clients[i].println("<GREEN>"); + digitalWrite(LED2, HIGH); + for(int z = 1; z < MAXSC; z++){ + if(clients[z].connected() && i != z){ + clients[z].println("<ORANGE>"); + } + } + } + } + } + else if(strstr(stringBuffer[i], "<OFF>")){ + digitalWrite(LED0, LOW); + digitalWrite(LED2, LOW); + gameBuffer = -1; + for(int i = 1; i < MAXSC; i++){ + if(clients[i].connected()){ + clients[i].println("<OFF>"); + } + } + } + else if(strstr(stringBuffer[i], "<PING>")){ + clientState[i] = 1; + } + + bufferLength[i] = 0; + } + } + } + } + + if(millis() - startTime >= 60000 && gameState == GAME_1){ // Spiel 1 Ende der Spielzeit + tickerToggle.attach(0.5, toggle, LED1); + tickerEnd.once(gameCount, end); + digitalWrite(LED0, LOW); + digitalWrite(LED1, LOW); + digitalWrite(LED2, LOW); + gameState = IDLE; + gameBuffer = -1; + for(int i = 1; i < MAXSC; i++){ + if(clients[i].connected()){ + clients[i].println("<IDLE>"); + } + } + } +} + +void SetWifi(){ + WiFi.disconnect(); + WiFi.mode(WIFI_AP_STA); + WiFi.softAP(ssid, password); + Serial.println("WIFI < " + String(ssid) + " > ... Started"); + + delay(1000); + + Serial.print("AccessPoint IP : "); + Serial.println(WiFi.softAPIP()); + + server.begin(); + Serial.println("Server Started"); + tickerPing.attach(2.5, tickPing); + tickerClients.attach(0.01, tickClients); +}