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
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:nanoatmega328new]
|
||||
platform = atmelavr
|
||||
board = nanoatmega328new
|
||||
[env:d1_mini]
|
||||
platform = espressif8266
|
||||
board = d1_mini
|
||||
board_build.filesystem = littlefs
|
||||
board_build.ldscript = eagle.flash.4m2m.ld
|
||||
|
||||
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
|
255
src/main.cpp
255
src/main.cpp
@ -1,11 +1,26 @@
|
||||
#include <Arduino.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)
|
||||
#define CLK 2
|
||||
#define DIO_GOF 3
|
||||
#define DIO_MIL 4
|
||||
#define DIO_KGG 5
|
||||
#define DIO_GOF_7SEG 0
|
||||
#define DIO_MIL_7SEG 5
|
||||
#define DIO_KGG_7SEG 4
|
||||
|
||||
#define DIO_GOF_TRG 12
|
||||
#define DIO_MIL_TRG 13
|
||||
#define DIO_KGG_TRG 14
|
||||
|
||||
enum Parties
|
||||
{
|
||||
@ -15,9 +30,17 @@ enum Parties
|
||||
KGG
|
||||
};
|
||||
|
||||
TM1637Display disp_GOF(CLK, DIO_GOF);
|
||||
TM1637Display disp_MIL(CLK, DIO_MIL);
|
||||
TM1637Display disp_KGG(CLK, DIO_KGG);
|
||||
void SevenSeg_Output();
|
||||
void ticker_callback();
|
||||
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;
|
||||
|
||||
@ -28,87 +51,186 @@ uint8_t KGG_dot = 0;
|
||||
uint8_t GOF_dot = 0;
|
||||
uint8_t MIL_dot = 0;
|
||||
|
||||
void setBrightness()
|
||||
String processor(const String &var)
|
||||
{
|
||||
char buffer[16] = {0};
|
||||
|
||||
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)
|
||||
{
|
||||
int found = 0;
|
||||
int strIndex[] = {0, -1};
|
||||
int maxIndex = data.length() - 1;
|
||||
|
||||
for (int i = 0; i <= maxIndex && found <= index; i++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
case GOF:
|
||||
disp_GOF.setBrightness(7);
|
||||
disp_MIL.setBrightness(0);
|
||||
disp_KGG.setBrightness(0);
|
||||
Count_GOF++;
|
||||
GOF_dot = GOF_dot == 0x80 || GOF_dot == 0x00 ? 0x10 : GOF_dot << 1;
|
||||
MIL_dot = 0;
|
||||
KGG_dot = 0;
|
||||
break;
|
||||
|
||||
case MILIZ:
|
||||
disp_GOF.setBrightness(0);
|
||||
disp_MIL.setBrightness(7);
|
||||
disp_KGG.setBrightness(0);
|
||||
Count_MILIZ++;
|
||||
MIL_dot = MIL_dot == 0x80 || MIL_dot == 0x00 ? 0x10 : MIL_dot << 1;
|
||||
GOF_dot = 0;
|
||||
KGG_dot = 0;
|
||||
break;
|
||||
|
||||
case KGG:
|
||||
disp_GOF.setBrightness(0);
|
||||
disp_MIL.setBrightness(0);
|
||||
disp_KGG.setBrightness(7);
|
||||
Count_KGG++;
|
||||
KGG_dot = KGG_dot == 0x80 || KGG_dot == 0x00 ? 0x10 : KGG_dot << 1;
|
||||
GOF_dot = 0;
|
||||
MIL_dot = 0;
|
||||
break;
|
||||
|
||||
case NONE:
|
||||
default:
|
||||
disp_GOF.setBrightness(0);
|
||||
disp_MIL.setBrightness(0);
|
||||
disp_KGG.setBrightness(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void tickCounter()
|
||||
void serialOut_callback()
|
||||
{
|
||||
static boolean tick_flag = false;
|
||||
if (millis() % 1000 > 500)
|
||||
|
||||
static uint32_t SerialPrintCount = 0;
|
||||
|
||||
if (SerialPrintCount % 10 == 0)
|
||||
{
|
||||
if (!tick_flag)
|
||||
{
|
||||
|
||||
switch (activeParty)
|
||||
{
|
||||
case GOF:
|
||||
Count_GOF++;
|
||||
GOF_dot = 0x50;
|
||||
break;
|
||||
|
||||
case MILIZ:
|
||||
Count_MILIZ++;
|
||||
MIL_dot = 0x50;
|
||||
break;
|
||||
|
||||
case KGG:
|
||||
Count_KGG++;
|
||||
KGG_dot = 0x50;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
tick_flag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
tick_flag = false;
|
||||
KGG_dot = 0x40;
|
||||
MIL_dot = 0x40;
|
||||
GOF_dot = 0x40;
|
||||
Serial.println("| GOF | MILIZ | KGG |");
|
||||
}
|
||||
Serial.printf(" %9d %9d %9d\n", Count_GOF, Count_MILIZ, Count_KGG);
|
||||
SerialPrintCount++;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(DIO_GOF_TRG, INPUT_PULLUP);
|
||||
pinMode(DIO_MIL_TRG, INPUT_PULLUP);
|
||||
pinMode(DIO_KGG_TRG, INPUT_PULLUP);
|
||||
|
||||
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()
|
||||
{
|
||||
tickCounter();
|
||||
setBrightness();
|
||||
PartyTicker.update();
|
||||
SerialOutputTicker.update();
|
||||
dnsServer.processNextRequest();
|
||||
SevenSeg_Output();
|
||||
|
||||
while (Serial.available() > 0)
|
||||
{
|
||||
@ -132,17 +254,18 @@ void loop()
|
||||
activeParty = MILIZ;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
SerialOutputTicker.stop();
|
||||
Serial.println("SerialOutputTicker.stop()");
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
SerialOutputTicker.resume();
|
||||
Serial.println("SerialOutputTicker.resume()");
|
||||
break;
|
||||
|
||||
default:
|
||||
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