First Version working - needs tweaking
This commit is contained in:
		
							
								
								
									
										6
									
								
								data/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								data/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										12
									
								
								data/css/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								data/css/style.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | .table-kgg,.table-kgg>td | ||||||
|  | { | ||||||
|  | 	background-color:#F5C6CB | ||||||
|  | } | ||||||
|  | .table-gof,.table-gof>td | ||||||
|  | { | ||||||
|  | 	background-color:#FFEEBA | ||||||
|  | } | ||||||
|  | .table-miliz,.table-miliz>td | ||||||
|  | { | ||||||
|  | 	background-color:#BAC9FF | ||||||
|  | } | ||||||
							
								
								
									
										98
									
								
								data/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								data/index.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="en"> | ||||||
|  |   <head> | ||||||
|  |     <meta charset="utf-8"> | ||||||
|  |     <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||||
|  |  | ||||||
|  |     <title>Dark Emergency CTF Timer - by hiabuto.de</title> | ||||||
|  |  | ||||||
|  |     <meta name="description" content="A project, designed by hiabuto.de"> | ||||||
|  |     <meta name="author" content="Marcel Peterkau"> | ||||||
|  |  | ||||||
|  |     <link href="css/bootstrap.min.css" rel="stylesheet"> | ||||||
|  |     <link href="css/style.css" rel="stylesheet"> | ||||||
|  |  | ||||||
|  |   </head> | ||||||
|  |   <body> | ||||||
|  |  | ||||||
|  |     <div class="container-fluid"> | ||||||
|  | 	<div class="row"> | ||||||
|  | 		<div class="col-md-12"> | ||||||
|  | 			<h3> | ||||||
|  | 				Dark Emergency CTF Timer | ||||||
|  | 			</h3> | ||||||
|  | 			<table class="table"> | ||||||
|  | 				<thead> | ||||||
|  | 					<tr> | ||||||
|  | 						<th> | ||||||
|  | 							# | ||||||
|  | 						</th> | ||||||
|  | 						<th> | ||||||
|  | 							Team | ||||||
|  | 						</th> | ||||||
|  | 						<th> | ||||||
|  | 							Points | ||||||
|  | 						</th> | ||||||
|  | 						<th> | ||||||
|  | 							Status | ||||||
|  | 						</th> | ||||||
|  | 					</tr> | ||||||
|  | 				</thead> | ||||||
|  | 				<tbody> | ||||||
|  | 					<tr class="table-kgg"> | ||||||
|  | 						<td> | ||||||
|  | 							1 | ||||||
|  | 						</td> | ||||||
|  | 						<td> | ||||||
|  | 							KGG | ||||||
|  | 						</td> | ||||||
|  | 						<td> | ||||||
|  | 							%POINTS_KGG% | ||||||
|  | 						</td> | ||||||
|  | 						<td> | ||||||
|  | 							%ACTIVE_KGG% | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					<tr class="table-miliz"> | ||||||
|  | 						<td> | ||||||
|  | 							2 | ||||||
|  | 						</td> | ||||||
|  | 						<td> | ||||||
|  | 							Miliz | ||||||
|  | 						</td> | ||||||
|  | 						<td> | ||||||
|  | 							%POINTS_MILIZ% | ||||||
|  | 						</td> | ||||||
|  | 						<td> | ||||||
|  | 							%ACTIVE_MILIZ% | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 					<tr class="table-gof"> | ||||||
|  | 						<td> | ||||||
|  | 							3 | ||||||
|  | 						</td> | ||||||
|  | 						<td> | ||||||
|  | 							GOF | ||||||
|  | 						</td> | ||||||
|  | 						<td> | ||||||
|  | 							%POINTS_GOF% | ||||||
|  | 						</td> | ||||||
|  | 						<td> | ||||||
|  | 							%ACTIVE_GOF% | ||||||
|  | 						</td> | ||||||
|  | 					</tr> | ||||||
|  | 				</tbody> | ||||||
|  | 			</table>  | ||||||
|  | 			<form  action="index.html" method="get" role="form"> | ||||||
|  | 				<div class="form-group">		  | ||||||
|  | 					<label for="commandInput">Command</label> | ||||||
|  | 					<input type="text" class="form-control" id="commandInput" name="command" /> | ||||||
|  | 				</div> | ||||||
|  | 				<button type="submit" class="btn btn-primary">Submit</button> | ||||||
|  | 			</form> | ||||||
|  | 		</div> | ||||||
|  | 	</div> | ||||||
|  | </div> | ||||||
|  |   </body> | ||||||
|  | </html> | ||||||
| @@ -8,8 +8,14 @@ | |||||||
| ; Please visit documentation for the other options and examples | ; Please visit documentation for the other options and examples | ||||||
| ; https://docs.platformio.org/page/projectconf.html | ; https://docs.platformio.org/page/projectconf.html | ||||||
|  |  | ||||||
| [env:nanoatmega328new] | [env:d1_mini] | ||||||
| platform = atmelavr | platform = espressif8266 | ||||||
| board = nanoatmega328new | board = d1_mini | ||||||
|  | board_build.filesystem = littlefs | ||||||
|  | board_build.ldscript = eagle.flash.4m2m.ld | ||||||
|  |  | ||||||
| framework = arduino | framework = arduino | ||||||
| lib_deps = smougenot/TM1637@0.0.0-alpha+sha.9486982048 | lib_deps = | ||||||
|  |     smougenot/TM1637@0.0.0-alpha+sha.9486982048 | ||||||
|  |     me-no-dev/ESP Async WebServer @ ^1.2.3 | ||||||
|  |     sstaub/Ticker @ ^4.2.0 | ||||||
							
								
								
									
										237
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										237
									
								
								src/main.cpp
									
									
									
									
									
								
							| @@ -1,11 +1,26 @@ | |||||||
| #include <Arduino.h> | #include <Arduino.h> | ||||||
| #include <TM1637Display.h> | #include <TM1637Display.h> | ||||||
|  | #include <Ticker.h> | ||||||
|  | #include <DNSServer.h> | ||||||
|  | #ifdef ESP32 | ||||||
|  | #include <WiFi.h> | ||||||
|  | #include <AsyncTCP.h> | ||||||
|  | #elif defined(ESP8266) | ||||||
|  | #include <ESP8266WiFi.h> | ||||||
|  | #include <ESPAsyncTCP.h> | ||||||
|  | #endif | ||||||
|  | #include "ESPAsyncWebServer.h" | ||||||
|  | #include "LittleFS.h" | ||||||
|  |  | ||||||
| // Module connection pins (Digital Pins) | // Module connection pins (Digital Pins) | ||||||
| #define CLK 2 | #define CLK 2 | ||||||
| #define DIO_GOF 3 | #define DIO_GOF_7SEG 0 | ||||||
| #define DIO_MIL 4 | #define DIO_MIL_7SEG 5 | ||||||
| #define DIO_KGG 5 | #define DIO_KGG_7SEG 4 | ||||||
|  |  | ||||||
|  | #define DIO_GOF_TRG 12 | ||||||
|  | #define DIO_MIL_TRG 13 | ||||||
|  | #define DIO_KGG_TRG 14 | ||||||
|  |  | ||||||
| enum Parties | enum Parties | ||||||
| { | { | ||||||
| @@ -15,9 +30,17 @@ enum Parties | |||||||
|   KGG |   KGG | ||||||
| }; | }; | ||||||
|  |  | ||||||
| TM1637Display disp_GOF(CLK, DIO_GOF); | void SevenSeg_Output(); | ||||||
| TM1637Display disp_MIL(CLK, DIO_MIL); | void ticker_callback(); | ||||||
| TM1637Display disp_KGG(CLK, DIO_KGG); | void serialOut_callback(); | ||||||
|  |  | ||||||
|  | TM1637Display disp_GOF(CLK, DIO_GOF_7SEG); | ||||||
|  | TM1637Display disp_MIL(CLK, DIO_MIL_7SEG); | ||||||
|  | TM1637Display disp_KGG(CLK, DIO_KGG_7SEG); | ||||||
|  | DNSServer dnsServer; | ||||||
|  | AsyncWebServer server(80); | ||||||
|  | Ticker PartyTicker(ticker_callback, 500, 0, MILLIS); | ||||||
|  | Ticker SerialOutputTicker(serialOut_callback, 5000, 0, MILLIS); | ||||||
|  |  | ||||||
| Parties activeParty = NONE; | Parties activeParty = NONE; | ||||||
|  |  | ||||||
| @@ -28,87 +51,186 @@ uint8_t KGG_dot = 0; | |||||||
| uint8_t GOF_dot = 0; | uint8_t GOF_dot = 0; | ||||||
| uint8_t MIL_dot = 0; | uint8_t MIL_dot = 0; | ||||||
|  |  | ||||||
| void setBrightness() | String processor(const String &var) | ||||||
| { | { | ||||||
|  |   char buffer[16] = {0}; | ||||||
|  |  | ||||||
|   switch (activeParty) |   if (var == "POINTS_KGG") | ||||||
|   { |     itoa(Count_KGG, buffer, 10); | ||||||
|   case GOF: |  | ||||||
|     disp_GOF.setBrightness(7); |  | ||||||
|     disp_MIL.setBrightness(0); |  | ||||||
|     disp_KGG.setBrightness(0); |  | ||||||
|     break; |  | ||||||
|  |  | ||||||
|   case MILIZ: |   if (var == "POINTS_GOF") | ||||||
|     disp_GOF.setBrightness(0); |     itoa(Count_GOF, buffer, 10); | ||||||
|     disp_MIL.setBrightness(7); |  | ||||||
|     disp_KGG.setBrightness(0); |  | ||||||
|     break; |  | ||||||
|  |  | ||||||
|   case KGG: |   if (var == "POINTS_MILIZ") | ||||||
|     disp_GOF.setBrightness(0); |     itoa(Count_MILIZ, buffer, 10); | ||||||
|     disp_MIL.setBrightness(0); |  | ||||||
|     disp_KGG.setBrightness(7); |  | ||||||
|     break; |  | ||||||
|  |  | ||||||
|   case NONE: |   if (var == "ACTIVE_KGG") | ||||||
|   default: |     return activeParty == KGG ? "ACTIVE" : "INACTIVE"; | ||||||
|     disp_GOF.setBrightness(0); |  | ||||||
|     disp_MIL.setBrightness(0); |   if (var == "ACTIVE_GOF") | ||||||
|     disp_KGG.setBrightness(0); |     return activeParty == GOF ? "ACTIVE" : "INACTIVE"; | ||||||
|     break; |  | ||||||
|   } |   if (var == "ACTIVE_MILIZ") | ||||||
|  |     return activeParty == MILIZ ? "ACTIVE" : "INACTIVE"; | ||||||
|  |  | ||||||
|  |   return String(buffer); | ||||||
| } | } | ||||||
|  |  | ||||||
| void tickCounter() | String getValue(String data, char separator, int index) | ||||||
| { | { | ||||||
|   static boolean tick_flag = false; |   int found = 0; | ||||||
|   if (millis() % 1000 > 500) |   int strIndex[] = {0, -1}; | ||||||
|  |   int maxIndex = data.length() - 1; | ||||||
|  |  | ||||||
|  |   for (int i = 0; i <= maxIndex && found <= index; i++) | ||||||
|   { |   { | ||||||
|     if (!tick_flag) |     if (data.charAt(i) == separator || i == maxIndex) | ||||||
|  |     { | ||||||
|  |       found++; | ||||||
|  |       strIndex[0] = strIndex[1] + 1; | ||||||
|  |       strIndex[1] = (i == maxIndex) ? i + 1 : i; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return found > index ? data.substring(strIndex[0], strIndex[1]) : ""; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class CaptiveRequestHandler : public AsyncWebHandler | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |   CaptiveRequestHandler() {} | ||||||
|  |   virtual ~CaptiveRequestHandler() {} | ||||||
|  |  | ||||||
|  |   bool canHandle(AsyncWebServerRequest *request) | ||||||
|  |   { | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void handleRequest(AsyncWebServerRequest *request) | ||||||
|   { |   { | ||||||
|  |  | ||||||
|  |     Serial.print("Requested URL: "); | ||||||
|  |     Serial.println(request->url()); | ||||||
|  |  | ||||||
|  |     //List all parameters | ||||||
|  |     int params = request->params(); | ||||||
|  |     for (int i = 0; i < params; i++) | ||||||
|  |     { | ||||||
|  |       AsyncWebParameter *p = request->getParam(i); | ||||||
|  |       if (p->isFile()) | ||||||
|  |       { //p->isPost() is also true | ||||||
|  |         Serial.printf("FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size()); | ||||||
|  |       } | ||||||
|  |       else if (p->isPost()) | ||||||
|  |       { | ||||||
|  |         Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |         Serial.printf("GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (LittleFS.exists(request->url()) == false) | ||||||
|  |     { | ||||||
|  |       request->send(404, "text/plain", "Not found"); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (request->url() == "/" || request->url() == "/index.html") | ||||||
|  |     { | ||||||
|  |       request->send(LittleFS, "/index.html", String(), false, processor); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (getValue(request->url(), '/', 1) == "css") | ||||||
|  |     { | ||||||
|  |       request->send(LittleFS, request->url(), "text/css"); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void SevenSeg_Output() | ||||||
|  | { | ||||||
|  |   disp_GOF.setBrightness(activeParty == GOF ? 7 : 0); | ||||||
|  |   disp_MIL.setBrightness(activeParty == MILIZ ? 7 : 0); | ||||||
|  |   disp_KGG.setBrightness(activeParty == KGG ? 7 : 0); | ||||||
|  |  | ||||||
|  |   disp_GOF.showNumberDecEx(Count_GOF / 20, GOF_dot, true, 4, 0); | ||||||
|  |   disp_MIL.showNumberDecEx(Count_MILIZ / 20, MIL_dot, true, 4, 0); | ||||||
|  |   disp_KGG.showNumberDecEx(Count_KGG / 20, KGG_dot, true, 4, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ticker_callback() | ||||||
|  | { | ||||||
|   switch (activeParty) |   switch (activeParty) | ||||||
|   { |   { | ||||||
|   case GOF: |   case GOF: | ||||||
|     Count_GOF++; |     Count_GOF++; | ||||||
|         GOF_dot = 0x50; |     GOF_dot = GOF_dot == 0x80 || GOF_dot == 0x00 ? 0x10 : GOF_dot << 1; | ||||||
|  |     MIL_dot = 0; | ||||||
|  |     KGG_dot = 0; | ||||||
|     break; |     break; | ||||||
|  |  | ||||||
|   case MILIZ: |   case MILIZ: | ||||||
|     Count_MILIZ++; |     Count_MILIZ++; | ||||||
|         MIL_dot = 0x50; |     MIL_dot = MIL_dot == 0x80 || MIL_dot == 0x00 ? 0x10 : MIL_dot << 1; | ||||||
|  |     GOF_dot = 0; | ||||||
|  |     KGG_dot = 0; | ||||||
|     break; |     break; | ||||||
|  |  | ||||||
|   case KGG: |   case KGG: | ||||||
|     Count_KGG++; |     Count_KGG++; | ||||||
|         KGG_dot = 0x50; |     KGG_dot = KGG_dot == 0x80 || KGG_dot == 0x00 ? 0x10 : KGG_dot << 1; | ||||||
|  |     GOF_dot = 0; | ||||||
|  |     MIL_dot = 0; | ||||||
|     break; |     break; | ||||||
|  |  | ||||||
|   default: |   default: | ||||||
|     break; |     break; | ||||||
|   } |   } | ||||||
|     } | } | ||||||
|     tick_flag = true; |  | ||||||
|   } | void serialOut_callback() | ||||||
|   else | { | ||||||
|  |  | ||||||
|  |   static uint32_t SerialPrintCount = 0; | ||||||
|  |  | ||||||
|  |   if (SerialPrintCount % 10 == 0) | ||||||
|   { |   { | ||||||
|     tick_flag = false; |     Serial.println("|    GOF    |   MILIZ   |    KGG    |"); | ||||||
|     KGG_dot = 0x40; |  | ||||||
|     MIL_dot = 0x40; |  | ||||||
|     GOF_dot = 0x40; |  | ||||||
|   } |   } | ||||||
|  |   Serial.printf("  %9d   %9d   %9d\n", Count_GOF, Count_MILIZ, Count_KGG); | ||||||
|  |   SerialPrintCount++; | ||||||
| } | } | ||||||
|  |  | ||||||
| void setup() | void setup() | ||||||
| { | { | ||||||
|  |   pinMode(DIO_GOF_TRG, INPUT_PULLUP); | ||||||
|  |   pinMode(DIO_MIL_TRG, INPUT_PULLUP); | ||||||
|  |   pinMode(DIO_KGG_TRG, INPUT_PULLUP); | ||||||
|  |  | ||||||
|   Serial.begin(9600); |   Serial.begin(9600); | ||||||
|  |  | ||||||
|  |   LittleFS.begin(); | ||||||
|  |  | ||||||
|  |   WiFi.softAP("Dark Emergency CTF Timer"); | ||||||
|  |   dnsServer.start(53, "*", WiFi.softAPIP()); | ||||||
|  |  | ||||||
|  |   server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); //only when requested from AP | ||||||
|  |   server.begin(); | ||||||
|  |  | ||||||
|  |   PartyTicker.start(); | ||||||
|  |   SerialOutputTicker.start(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void loop() | void loop() | ||||||
| { | { | ||||||
|   tickCounter(); |   PartyTicker.update(); | ||||||
|   setBrightness(); |   SerialOutputTicker.update(); | ||||||
|  |   dnsServer.processNextRequest(); | ||||||
|  |   SevenSeg_Output(); | ||||||
|  |  | ||||||
|   while (Serial.available() > 0) |   while (Serial.available() > 0) | ||||||
|   { |   { | ||||||
| @@ -132,17 +254,18 @@ void loop() | |||||||
|       activeParty = MILIZ; |       activeParty = MILIZ; | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
|  |     case 'x': | ||||||
|  |       SerialOutputTicker.stop(); | ||||||
|  |       Serial.println("SerialOutputTicker.stop()"); | ||||||
|  |       break; | ||||||
|  |  | ||||||
|  |     case 'y': | ||||||
|  |       SerialOutputTicker.resume(); | ||||||
|  |       Serial.println("SerialOutputTicker.resume()"); | ||||||
|  |       break; | ||||||
|  |  | ||||||
|     default: |     default: | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   int temp; |  | ||||||
|  |  | ||||||
|   temp = Count_GOF / 3600 * 100 + (Count_GOF / 60) % 60; |  | ||||||
|   disp_GOF.showNumberDecEx(temp / 60, GOF_dot, true, 4, 0); |  | ||||||
|   temp = Count_MILIZ / 3600 * 100 + (Count_MILIZ / 60) % 60; |  | ||||||
|   disp_MIL.showNumberDecEx(temp, MIL_dot, true, 4, 0); |  | ||||||
|   temp = Count_KGG / 3600 * 100 + (Count_KGG / 60) % 60; |  | ||||||
|   disp_KGG.showNumberDecEx(temp, KGG_dot, true, 4, 0); |  | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user
	 Peterkau Marcel
					Peterkau Marcel