First Version working - needs tweaking

This commit is contained in:
Peterkau Marcel 2021-06-09 15:01:40 +02:00
parent 4750fbb9b3
commit 2c6bf4ee6c
5 changed files with 315 additions and 70 deletions

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
View 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
View 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>

View File

@ -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

View File

@ -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);
if (var == "POINTS_GOF")
itoa(Count_GOF, buffer, 10);
if (var == "POINTS_MILIZ")
itoa(Count_MILIZ, buffer, 10);
if (var == "ACTIVE_KGG")
return activeParty == KGG ? "ACTIVE" : "INACTIVE";
if (var == "ACTIVE_GOF")
return activeParty == GOF ? "ACTIVE" : "INACTIVE";
if (var == "ACTIVE_MILIZ")
return activeParty == MILIZ ? "ACTIVE" : "INACTIVE";
return String(buffer);
}
String getValue(String data, char separator, int index)
{ {
case GOF: int found = 0;
disp_GOF.setBrightness(7); int strIndex[] = {0, -1};
disp_MIL.setBrightness(0); int maxIndex = data.length() - 1;
disp_KGG.setBrightness(0);
break;
case MILIZ: for (int i = 0; i <= maxIndex && found <= index; i++)
disp_GOF.setBrightness(0); {
disp_MIL.setBrightness(7); if (data.charAt(i) == separator || i == maxIndex)
disp_KGG.setBrightness(0); {
break; found++;
strIndex[0] = strIndex[1] + 1;
case KGG: strIndex[1] = (i == maxIndex) ? i + 1 : i;
disp_GOF.setBrightness(0);
disp_MIL.setBrightness(0);
disp_KGG.setBrightness(7);
break;
case NONE:
default:
disp_GOF.setBrightness(0);
disp_MIL.setBrightness(0);
disp_KGG.setBrightness(0);
break;
} }
} }
void tickCounter() return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}
class CaptiveRequestHandler : public AsyncWebHandler
{ {
static boolean tick_flag = false; public:
if (millis() % 1000 > 500) CaptiveRequestHandler() {}
virtual ~CaptiveRequestHandler() {}
bool canHandle(AsyncWebServerRequest *request)
{ {
if (!tick_flag) 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
{ {
tick_flag = false;
KGG_dot = 0x40; static uint32_t SerialPrintCount = 0;
MIL_dot = 0x40;
GOF_dot = 0x40; if (SerialPrintCount % 10 == 0)
{
Serial.println("| GOF | MILIZ | KGG |");
} }
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);
} }