First Version working - needs tweaking
This commit is contained in:
parent
4750fbb9b3
commit
2c6bf4ee6c
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
|
235
src/main.cpp
235
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);
|
||||||
|
|
||||||
|
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);
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user