#include <WiFi.h>
#include <WebServer.h>
#include "FS.h"
#include "LittleFS.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
//screen position definitions
#define TFTnothing 0
#define TFTcentre 1
#define TFTleft 2
#define TFTright 3
#define TFTnoErase -1
#define TFTtextSmall 1
#define TFTtextMedium 2
#define TFTtextLarge 3
#define btnUnlock 5
#define btnTest 35
#define ledUnlock 25
byte buttonResult;
unsigned long xxcurrent;
unsigned long xxfinal;
unsigned long ota_progress_millis;
#define TFT_DC 2
#define TFT_CS 15
#define FORMAT_LITTLEFS_IF_FAILED true
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
String playerNames[8]={"aaaaaaaaaaaa", //The name of each player
"bbbbbbbbbbbb",
"cccccccccccc",
"dddddddddddd",
"eeeeeeeeeeee",
"ffffffffffff",
"gggggggggggg",
"hhhhhhhhhhhh"
};
int playerScores[8];
String teams[2]={"Team A","Team B"}; //The team name
String teamFN[2]={"1001","3001"};
byte textLines[3]={30,15,10} ;
int16_t textY[3]={0,0,0}; //1-3 holds char height for each of the text sizes
//size & text lines 1/30, 2/15, 3/10
WebServer server(80);
void getTextHeights() {
int16_t x1, y1;
uint16_t w, h;
String dummy;
//get the line height for each of the screen modes
//I was going to manually set the numbers, but keep this in
//just in case we ever change the font.
dummy="Ay";
tft.setTextSize(1);
tft.getTextBounds(dummy,0,0, &x1, &y1, &w, &h);
textY[1]=h;
tft.setTextSize(2);
tft.getTextBounds(dummy, 0,0, &x1, &y1, &w, &h);
textY[2]=h;
tft.setTextSize(3);
tft.getTextBounds(dummy, 0,0, &x1, &y1, &w, &h);
textY[3]=h;
}
void printat(String text, int posX, int posY, byte tSize, int eraseColour, byte action) {
int16_t x1, y1;
uint16_t w, h;
String tempText;
bool IBM;
char tchar[3];
long princhar;
//set eraseColour to background colour or -1 for no erase
tft.setTextSize(tSize);
Serial.println(text.substring(0,2));
if (text.substring(0,2)=="0x") { //set the correct size
//it is a char
Serial.println(text);
tempText=text.substring(2,4);
Serial.println("-"+tempText);
tempText.toCharArray(tchar,3);
tchar[2]='\0';
Serial.println(tchar);
tempText="X";
IBM=true;
} else {
IBM=false;
tempText=text;
}
switch (action) {
case TFTcentre: //we would never position on pixel 1
tft.getTextBounds(tempText, 0, 0, &x1, &y1, &w, &h); //get the physical size of the text "box"
posX=(tft.width()-w)/2;
break;
case TFTright:
tft.getTextBounds(tempText, 0, 0, &x1, &y1, &w, &h); //get the physical size of the text "box"
posX=tft.width()-(w+1);
break;
case TFTleft:
posX=0;
break;
}
posY=posY*textY[tSize];
tft.setCursor(posX,posY);
if (eraseColour>-1) {
tft.getTextBounds(tempText, posX, posY, &x1, &y1, &w, &h); //get the position this time,
tft.fillRect( x1, posY, w, h,eraseColour);
}
if (IBM==false) {
tft.print(text);
} else {
//tft.print("*");
princhar=strtoul(tchar, NULL, 16);
Serial.println(princhar);
tft.write(princhar);
}
}
void setup() {
String dummy;
int lp;
int step;
Serial.begin(115200);
//Now set up the File System
// if (!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)) {
// #if (useSerialOutput)
// Serial.println("LittleFS Mount Failed");
// #endif
// return;
// } else {
// #if (useSerialOutput)
// Serial.println("LittleFS Mounted OK");
// #endif
// }
tft.begin();
tft.setRotation(1);
tft.setTextWrap(false);
tft.setTextSize(TFTtextMedium);
pinMode(btnUnlock,INPUT);
pinMode(ledUnlock,OUTPUT);
tft.setTextColor(ILI9341_WHITE);
getTextHeights();
WiFi.mode(WIFI_AP);
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
//Then start the simulation, and open http://localhost:9080 in another browser tab.
Serial.println(" Connected!");
server.on("/", handle_OnConnect);
server.on("/index", HTTP_POST, handle_OnConnect);
server.on("/fupload", HTTP_POST, []() {
server.send(200);
}, handleUploadFile);
server.begin();
Serial.println("HTTP server started");
Serial.println("");
Serial.print("Local mode Connected to ");
Serial.print("IP address: ");
Serial.println(WiFi.softAPIP());
}
void handle_OnConnect() { //This builds the INDEX web page (eg on connect)
#if (useSerialOutput)
Serial.println("ON Connect");
#endif
// send the HTTP response body
String html = F("<pre><form action='");
html += F("/fupload' method='post' action='' enctype='multipart/form-data'>");
html += F("<b>Upload Sequence File : <br><br>");
html += F("<input type='file' name='upload'></b>");
html += F(" <input type='submit' value=' Upload '></form></pre><br>");
server.send(200, "text/html", html);
delay(10);
}
void handleUploadFile() {
static File fsUploadFile;
//static String upfil;
HTTPUpload& uploadfile = server.upload();
if (uploadfile.status == UPLOAD_FILE_START) {
String filename = uploadfile.filename;
// if (!filename.endsWith(".dsq")) {
// String redir = "/?page=file&upl=nonseqfile&name=" + filename;
// server.sendHeader("Location", redir); // Redirect the client to the file page
// server.send(303);
// return;
// }
if (!filename.startsWith("/")) filename = "/" + filename;
// if (LittleFS.exists(filename)) {
// uint8_t len = filename.length();
// String fil = filename.substring(0, len - 4) + "0" + F(".dsq");
// filename = fil;
// while (LittleFS.exists(filename)) {
// char c = filename.charAt(filename.length() - 5);
// if (c == '9') c = 'A';
// else if (c == 'Z') c = 'a';
// else if (c == 'z') {
// String refil = filename.substring(0, filename.length() - 5) + "00" + ".dsq";
// filename = refil;
// c = '0';
// }
// else c++;
// filename[filename.length() - 5] = c;
// }
// }
fsUploadFile = LittleFS.open(filename, "w");
if (!fsUploadFile) {
Serial.println("Upload Failed");
// String redir = F("/?page=file&upl=failcreate&name=");
// redir += HashURLFilename(filename.substring(1, filename.length() - 4));
// server.sendHeader("Location", redir); // Redirect the client to the file page
// server.send(303);
}
//upfil = HashURLFilename(filename.substring(1, filename.length() - 4));
}
else if (uploadfile.status == UPLOAD_FILE_WRITE) {
if (fsUploadFile) fsUploadFile.write(uploadfile.buf, uploadfile.currentSize); // Write the received bytes to the file
}
else if (uploadfile.status == UPLOAD_FILE_END) {
if (fsUploadFile) { // If the file was successfully created
fsUploadFile.close(); // Close the file again
Serial.println("Upload Complete successful");
// String redir = "/?page=file&upl=success&name=" + upfil;
// server.sendHeader("Location", redir); // Redirect the client to the file page
// server.send(303);
}
else {
//String redir = "/?page=file&upl=failcreate&name=" + upfil;
Serial.println("Upload Failed");
//server.sendHeader("Location", redir); // Redirect the client to the file page
//server.send(303);
}
}
}
void loop() {
// for (int lp=0;lp<8;lp++) {
// pressbutton(lp);
// delay(1000);
// }
delay(1000);
}
// void pressbutton(int btn) {
// int twidth;
// twidth=tft.width()/2;
// if (btn<4) {
// printat(" ",0,5+btn,TFTtextMedium,ILI9341_RED,TFTnothing);
// } else {
// printat(" ",twidth,5+(btn-4),TFTtextMedium,ILI9341_RED,TFTnothing);
// }
// }
// void dotest() {
// int lp;
// int twidth;
// String tName;
// twidth=tft.width()/2;
// Serial.println(twidth);
// tft.fillScreen(ILI9341_RED);
// tft.setTextColor(ILI9341_YELLOW);
// printat("Test Mode",0,0,TFTtextMedium,TFTnoErase,TFTcentre);
// printat("---------",0,1,TFTtextMedium,TFTnoErase,TFTcentre);
// tName=teams[0].substring(0,10);
// printat(tName,20,3,TFTtextMedium,TFTnoErase,TFTnothing);
// tName=teams[1].substring(0,10);
// printat(tName,twidth+20,3,TFTtextMedium,TFTnoErase,TFTnothing);
// for (lp=0;lp<4;lp++) {
// printat("0x2A",0,5+lp,TFTtextMedium,TFTnoErase,TFTnothing);
// tName=playerNames[lp].substring(0,10);
// printat(tName,20,5+lp,TFTtextMedium,TFTnoErase,TFTnothing);
// printat("0x2A",twidth,5+lp,TFTtextMedium,TFTnoErase,TFTnothing);
// tName=playerNames[lp+4].substring(0,10);
// printat(tName,twidth+20,5+lp,TFTtextMedium,TFTnoErase,TFTnothing);
// }
// }
void TFTscoreScreen() {
int lp;
int twidth;
String tName;
twidth=tft.width()/2;
tft.fillScreen(ILI9341_BLUE);
tft.setTextColor(ILI9341_YELLOW);
printat(teams[0],40,0,TFTtextMedium,TFTnoErase,TFTnothing);
printat(teams[1],40,8,TFTtextMedium,TFTnoErase,TFTnothing);
for (lp=0;lp<4;lp++) {
printat(playerNames[lp],40,2+lp,TFTtextMedium,TFTnoErase,TFTnothing);
}
for (lp=4;lp<8;lp++) {
printat(playerNames[lp],40,6+lp,TFTtextMedium,TFTnoErase,TFTnothing);
}
for (lp=0;lp<4;lp++) {
printat("100",0,2+lp,TFTtextMedium,TFTnoErase,TFTnothing);
}
for (lp=4;lp<8;lp++) {
printat("100",0,6+lp,TFTtextMedium,TFTnoErase,TFTnothing);
}
tft.setTextColor(ILI9341_BLUE, ILI9341_WHITE);
printat("100",0,6,TFTtextMedium,TFTnoErase,TFTnothing);
printat("100",0,14,TFTtextMedium,TFTnoErase,TFTnothing);
}
// void TFTshowReadyScreen() {
// int buttonResult;
// int buttonTest;
// String ipaddr;
// String WSssid="PODoom";
// ipaddr="100.100.100.100";
// tft.fillScreen(ILI9341_BLUE);
// tft.setTextColor(ILI9341_YELLOW);
// printat("Prepare for the quiz",0,0,TFTtextMedium,TFTnoErase,TFTcentre);
// printat("--------------------",0,1,TFTtextMedium,TFTnoErase,TFTcentre);
// printat("Change your device WiFi",0,3,TFTtextMedium,TFTnoErase,TFTleft);
// printat("settings to connect to",0,4,TFTtextMedium,TFTnoErase,TFTleft);
// tft.setTextColor(ILI9341_BLACK, ILI9341_WHITE);
// printat(WSssid,0,6,TFTtextMedium,TFTnoErase,TFTcentre);
// tft.setTextColor(ILI9341_YELLOW);
// printat("and type this adress into ",0,8,TFTtextMedium,TFTnoErase,TFTleft);
// printat("your web browser",0,9,TFTtextMedium,TFTnoErase,TFTleft);
// tft.setTextColor(ILI9341_BLACK, ILI9341_WHITE);
// printat("http://"+ipaddr,0,11,TFTtextMedium,TFTnoErase,TFTcentre);
// tft.setTextColor(ILI9341_WHITE);
// printat("Enter the player and team",0,13,TFTtextMedium,TFTnoErase,TFTleft);
// printat("names, then press UNLOCK",0,14,TFTtextMedium,TFTnoErase,TFTleft);
// do {
// buttonResult=digitalRead(btnUnlock);
// server.handleClient(); //check for webserver events
// } while (buttonResult==0); //wait for the Unlock button.
// tft.fillScreen(ILI9341_BLUE);
// tft.setTextColor(ILI9341_YELLOW);
// printat(teams[0],0,3,TFTtextLarge,TFTnoErase,TFTcentre);
// printat("vs",0,4,TFTtextLarge,TFTnoErase,TFTcentre);
// printat(teams[1],0,5,TFTtextLarge,TFTnoErase,TFTcentre);
// tft.setTextColor(ILI9341_RED, ILI9341_WHITE);
// printat("Start",0,13,TFTtextMedium,TFTnoErase,TFTright);
// printat("Sys Test",0,1,TFTtextMedium,TFTnoErase,TFTright);
// do {
// buttonResult=digitalRead(btnUnlock);
// buttonTest=digitalRead(btnTest);
// if (buttonTest!=0) {
// TFTshowTestingScreen();
// }
// server.handleClient(); //check for webserver events
// } while (buttonResult==0); //wait for the Unlock button.
// }
// void test() {
// String ipaddr;
// int16_t x1, y1;
// uint16_t w, h;
// //ipaddr="http://"+String(WiFi.localIP())+"/update";
// ipaddr="http://192.168.11.4/update";
// //set eraseColour to background colour or -1 for no erase
// tft.setTextSize(2); //set the correct size
// tft.getTextBounds(ipaddr, 0, 0, &x1, &y1, &w, &h); //get the physical size of the text "box"
// tft.fillScreen(ILI9341_RED);
// tft.setTextColor(ILI9341_YELLOW);
// printat("OTA mode engaged",0,0,2,-1,TFTcentre);
// printat("----------------",0,1,2,-1,TFTcentre);
// printat("Use your web browser",0,6,2,-1,TFTleft);
// printat("to browse to",0,7,2,-1,TFTleft);
// if (w>tft.width()) {
// tft.setTextSize(1);
// printat(ipaddr,0,17,1,-1,TFTleft);
// } else {
// printat(ipaddr,0,9,2,-1,TFTleft);
// }
// tft.setTextColor(ILI9341_WHITE);
// tft.setTextSize(2);
// printat("OTA switch can now be",0,13,2,-1,TFTcentre);
// printat("turned off",0,14,2,-1,TFTcentre);
// }
// void test() {
// String ipaddr="192.168.100.100";
// String OTAssid="GDoffice";
// String OTApass="this is the password";
// int cntLeft;
// bool dropout;
// bool offon;
// byte linecnt;
// int TMRwifiResponseTime=10;
// bool connected;
// tft.fillScreen(ILI9341_BLUE);
// tft.setTextColor(ILI9341_YELLOW);
// printat("Waiting for WiFi to engage",0,0,2,-1,TFTcentre);
// printat("--------------------------",0,1,2,-1,TFTcentre);
// printat("Trying to connect to",0,4,2,-1,TFTleft);
// printat(OTAssid,0,5,2,-1,TFTleft);
// dropout=false; //set the flag
// cntLeft=TMRwifiResponseTime+1; //How many seconds to wait
// linecnt=0;
// // Wait for connection
// while (dropout==false) {
// //dropout=(WiFi.status() == WL_CONNECTED);
// dropout=(random(0,500)==500);
// cntLeft--;
// if (cntLeft<=0) {
// dropout=true;
// }
// digitalWrite(ledUnlock,offon);
// offon=(offon==false);
// delay(1000);
// //Serial.println(String(WiFi.status()));
// if (cntLeft>=0) {
// printat(" "+String(cntLeft)+" ",0,5,3,ILI9341_BLUE,TFTcentre);
// }
// }
// digitalWrite(ledUnlock,0);
// connected=false;
// //if (WiFi.status() != WL_CONNECTED) {
// if (connected==false) {
// tft.fillScreen(ILI9341_RED);
// tft.setTextColor(ILI9341_YELLOW);
// printat("WiFi Error",0,0,2,-1,TFTcentre);
// printat("----------",0,1,2,-1,TFTcentre);
// printat("No WiFi connection for",0,3,2,-1,TFTleft);
// printat("'"+OTAssid+"'",0,4,2,-1,TFTleft);
// printat("Check that WiFi is 2.4Ghz",0,8,2,-1,TFTcentre);
// printat("and not using the same",0,9,2,-1,TFTcentre);
// printat("SSID with 5Ghz",0,10,2,-1,TFTcentre);
// tft.setTextColor(ILI9341_WHITE);
// printat("Press UNLOCK to reboot",0,14,2,-1,TFTcentre);
// do {
// buttonResult=digitalRead(btnUnlock);
// //server.handleClient(); //check for webserver events
// } while (buttonResult==0); //wait for the Unlock button.
// ESP.restart();
// }
// tft.setTextColor(ILI9341_WHITE);
// printat("Press UNLOCK ",0,13,2,-1,TFTcentre);
// printat("to start the quiz",0,14,2,-1,TFTcentre);
//}
void prog(size_t xcurrent, size_t xfinal) {
// Log every 1 second
if (millis() - ota_progress_millis > 1000) {
ota_progress_millis = millis();
tft.setTextColor(ILI9341_WHITE);
printat(String(xcurrent),0,6,2,ILI9341_BLACK,TFTleft);
}
}
void start(size_t xfinal) {
// Log when OTA has started
Serial.println("OTA update started!");
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
printat("OTA update started",0,0,2,0,TFTcentre);
printat("------------------",0,1,2,0,TFTcentre);
printat("bytes of "+String(xfinal),80,6,2,0,0);
}
void complete(bool success) {
// Log when OTA has finished
tft.fillScreen(ILI9341_BLACK);
if (success) {
tft.setTextColor(ILI9341_GREEN);
printat("OTA update completed",0,3,2,0,TFTcentre);
printat("successfully!",0,4,2,0,TFTcentre);
Serial.println("OTA update finished successfully!");
} else {
tft.setTextColor(ILI9341_RED);
printat("OTA update ERROR!",0,3,2,0,TFTcentre);
Serial.println("OTA update ERROR!");
}
tft.setTextColor(ILI9341_WHITE);
printat("Press UNLOCK to restart",0,14,2,0,TFTcentre);
do {
buttonResult=digitalRead(btnUnlock);
//server.handleClient(); //check for webserver events
//ElegantOTA.loop();
} while (buttonResult==0); //wait for the Unlock button.
ESP.restart();
}