Upload files now through http, working fast and good. Implemented new network with dedicated router and fixed IP for processor.

This commit is contained in:
2025-11-09 21:26:16 +00:00
parent 34346e715d
commit dbcb8c50f7
12 changed files with 41975 additions and 40112 deletions

View File

@@ -2,8 +2,11 @@
#include "main.h"
const char *ssid = "CIA";
const char *password = "passespacarola";
const char *ssid = "IBVS_wuDa5d";
const char *password = "Yai6maiph6oi";
IPAddress processor_IP(172, 20, 50, 35);
IPAddress gateway(172, 16, 0, 1);
IPAddress subnet(255, 240, 0, 0);
// Touchscreen pinout
#define XPT2046_IRQ 36
@@ -16,7 +19,7 @@ int x, y, z;
#define SCREEN_HEIGHT 320
// MQTT settings
const char* mqtt_server_ip = "10.139.95.154";
const char* mqtt_server_ip = "172.20.50.35";
const int mqtt_port = 1883;
//const char* mqtt_user = "badge_device";
//const char* mqtt_password = "letmein";
@@ -57,7 +60,7 @@ ShortText item5 = {"Null", 4, 200};
lv_image_dsc_t* dynamic_img_dsc = NULL;
//WebServer server(80); // For web image uploader
WebServer server(80); // For web image uploader
#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];
@@ -174,9 +177,9 @@ void setup() {
wifi_connected = connect_wifi();
// For web image uploader
/* server.on("/upload", HTTP_POST, []() {}, handleImageUpload);
server.on("/upload", HTTP_POST, handleUploadComplete, handleImageUpload);
server.begin();
Serial.println("Web server started"); */
Serial.println("Web server started");
}
void loop() {
@@ -185,19 +188,16 @@ void loop() {
if (ibvs_mode == IBVS_BADGE) {
if (!configDone) {
Serial.println("Entering badge mode...");
vTaskDelay(1000 / portTICK_PERIOD_MS);
serial_config();
vTaskDelay(1000 / portTICK_PERIOD_MS);
Serial.println("If you want to upload your picture type the following in a terminal:");
Serial.printf("curl -F \"file=@yourfile.bin\" http://%s/upload\r\n", WiFi.localIP().toString().c_str());
configDone = true;
}
/* if (!get_imageDone) {
server.handleClient();
get_imageDone = true;
}
*/
// server.handleClient(); // For web image uploader
get_image();
server.handleClient(); // For web image uploader
if (winner != '0' && !winnerDone) {
Winner_Screen();
winnerDone = true;
@@ -207,26 +207,21 @@ void loop() {
if (ibvs_mode == IBVS_PROCESSOR) {
if (!configDone) {
Serial.println("Entering processor mode...");
WiFi.config(processor_IP, gateway, subnet);
set_var_ui_ip(WiFi.localIP().toString().c_str());
badge_registration();
configDone = true;
}
/* if (millis() - last_publish_time >= 60000) { // Debug
message = "MQTT server ping #" + String(ping_number++);
Serial.printf("Publishing message in topic '%s': %s\r\n", topic_test.c_str(), message.c_str());
mqtt_server.publish(topic_test, message);
last_publish_time = millis();
} */
if (vote_end) {
message = "3";
message = '3';
mqtt_server.publish(topic_winner, message);
vote_end = false;
}
}
// vTaskDelay(10 / portTICK_PERIOD_MS);
delay(10);
vTaskDelay(10 / portTICK_PERIOD_MS);
}
void serial_config() {
@@ -234,7 +229,6 @@ void serial_config() {
bool confirmed = false;
while (!confirmed) {
// Ask for name
Serial.println("Please enter your name:");
// Clear any existing input
@@ -281,7 +275,6 @@ void serial_config() {
confirmed = false;
while (!confirmed) {
// Ask for name
Serial.println("Please enter the Organization or Event name:");
// Clear any existing input
@@ -320,16 +313,16 @@ void serial_config() {
strcpy(orgev.text, buffer);
set_var_ui_orgev(buffer);
confirmed = true;
Serial.println("Organization/Event name saved!");
Serial.println("Organization/Event name saved!\r\n");
}
}
Serial.print("Here is your ID: ");
Serial.println(Badge_ID);
Serial.println("Write it down.");
Serial.println("Write it down.\r\n");
current_screen = 'C';
screenNeedsUpdate = true;
Serial.printf("Current screen is: %c\r\n", current_screen); // Debug
// DBG_L1("Current screen is: %c\r\n", current_screen); // Debug
}
void mqtt_subs() {
@@ -372,8 +365,9 @@ void mqtt_subs() {
}
else if (strcmp(topic, "voting/winner") == 0) {
winner = payload[0];
Serial.println("Im in the mqtt receive winner");
}
// Serial.println("Im in the mqtt receive winner");
DBG_L1("Im in the mqtt receive winner");
}
else if (strcmp(topic, "voting/ready") == 0) {
if (strcmp(payload, "start") == 0) {
current_screen = 'D';
@@ -381,13 +375,22 @@ void mqtt_subs() {
}
}
});
mqtt_client.subscribe("illegal", [](const char *topic, const char *payload) {
Serial.printf("Received message in topic '%s': %s\r\n", topic, payload);
if (strcmp(payload, Badge_ID) == 0) {
current_screen = 'I';
screenNeedsUpdate = true;
}
});
}
if (ibvs_mode == IBVS_PROCESSOR) {
mqtt_server.subscribe("voter#", [](const char * topic, const char * payload) {
Serial.printf("Received message in topic '%s': %s\r\n", topic, payload);
String curr_badge(topic);
curr_badge.replace("voter/", ""); // Remove all colons
curr_badge.replace("voter/", "");
curr_badge = curr_badge.substring(0, 8);
bool found = false;
@@ -402,12 +405,8 @@ void mqtt_subs() {
Serial.println("Badge is authorised");
curr_vote++;
} else {
Serial.println("Badge NOT found");
// This needs to move to screen manager in new filtering for illegal/curr_badge
// and if curr_badge matches then the next 2 lines
// current_screen = 'I';
// screenNeedsUpdate = true;
// in here it has to publish server something like illegal/curr_badge
Serial.println("Badge NOT found");
mqtt_server.publish("illegal", curr_badge);
}
if (curr_vote == num_badges) vote_end = true;
@@ -486,13 +485,13 @@ void screen_manager(void *pvParameters) {
while (1) {
if (start_screen < START_SCREEN_WAIT) { // If not the wanted seconds keep counting
start_screen++;
// Serial.printf("Counting: %d\r\n", start_screen); // Debug
DBG_L2("Counting: %d\r\n", start_screen);
}
else if (start_screen == START_SCREEN_WAIT && !wifi_connected) {
start_screen = START_SCREEN_WAIT - 600; // If wanted seconds but no wifi wait 1 second
}
else if (start_screen == START_SCREEN_WAIT && wifi_connected) {
Serial.println("Switching to screen G"); // Debug
DBG_L1("Switching to screen G\r\n"); // Debug
current_screen = 'G';
screenNeedsUpdate = true;
start_screen = START_SCREEN_WAIT+10;
@@ -500,7 +499,7 @@ void screen_manager(void *pvParameters) {
// Here we update the screen only if there is a change
if (screenNeedsUpdate) {
Serial.printf("Loading screen: %c\r\n", current_screen); // Debug
DBG_L1("Loading screen: %c\r\n", current_screen); // Debug
switch (current_screen) {
case 'A':
loadScreen(SCREEN_ID_START);
@@ -557,7 +556,7 @@ void mqtt_manager(void *pvParameters) {
mqtt_client.begin();
mqtt_subs();
ibvs_mode_done = true;
Serial.println("mqtt_subs() done once in badge mode"); // Debug
DBG_L1("mqtt_subs() done once in badge mode"); // Debug
}
mqtt_client.loop();
vTaskDelay(5 / portTICK_PERIOD_MS);
@@ -567,7 +566,7 @@ void mqtt_manager(void *pvParameters) {
mqtt_server.begin();
mqtt_subs();
ibvs_mode_done = true;
Serial.println("mqtt_subs() done once in processor mode"); // Debug
DBG_L1("mqtt_subs() done once in processor mode"); // Debug
}
mqtt_server.loop();
vTaskDelay(5 / portTICK_PERIOD_MS);
@@ -579,132 +578,63 @@ void mqtt_manager(void *pvParameters) {
}
void badge_registration() {
bool confirmed = false;
while (!confirmed) {
Serial.println("Input the badges ID for registration, comma separated :");
// Clear any existing input
while(Serial.available()) Serial.read();
// Wait for complete line with Enter
// String input = "";
while (true) {
if (Serial.available() > 0) {
while (!confirmed) {
badges = ""; // 2. start fresh
current = "";
Serial.println("Input the badges ID for comma-separated :");
while (Serial.available()) Serial.read(); // flush
// read full line
for (;;) {
if (Serial.available()) {
char c = Serial.read();
if (c == '\n' || c == '\r') {
if (badges.length() > 0) {
break; // Got Enter with text
} else {
Serial.println("Input the badges ID for registration, comma separated :");
// Continue waiting for input
}
} else {
badges+= c; // Add character to string
}
if (badges.length()) break;
Serial.println("Empty input, please Input the badges ID for comma-separated :");
} else badges += c;
}
delay(10);
}
// input.toCharArray(badges, sizeof(badges));
Serial.print("You entered: ");
Serial.println(badges);
Serial.println("Is this correct? (y/n)");
while (Serial.available() == 0) delay(10);
char response = Serial.read();
Serial.println('\n');
if (response == 'y' || response == 'Y') {
Serial.print("You entered: "); Serial.println(badges);
Serial.println("Correct? (y/n)");
while (!Serial.available()) delay(10);
char resp = Serial.read(); // get single char
// 3. discard the rest of the line
while (Serial.available()) Serial.read();
if (resp == 'y' || resp == 'Y') {
confirmed = true;
for (size_t i = 0; i < badges.length(); ++i) {
char c = badges[i];
if (c == ',') { // end of one badge
register_badges.push_back(current);
current = ""; // start next badge
} else {
current += c;
}
}
if (current.length()) register_badges.push_back(current); // last badge (no trailing comma)
num_badges = register_badges.size();
Serial.printf("%d badges were registered for voting :\r\n", (int)num_badges);
for (const String& each_b: register_badges) {
Serial.println(each_b);
}
}
}
}
void get_image() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
command.trim();
if (command.startsWith("UPLOAD_IMAGE:")) {
int colonPos = command.indexOf(':', 13);
String filename = command.substring(13, colonPos);
int fileSize = command.substring(colonPos + 1).toInt();
Serial.print("Receiving ");
Serial.print(filename);
Serial.print(" (");
Serial.print(fileSize);
Serial.println(" bytes)");
delay(1000);
fs::File file = SPIFFS.open("/" + filename, FILE_WRITE);
if (file) {
int totalRead = 0;
byte buffer[512]; // Larger buffer
unsigned long lastRead = millis();
while (totalRead < fileSize && (millis() - lastRead < 60000)) { // 60 second timeout
int available = Serial.available();
if (available > 0) {
int toRead = min(512, min(fileSize - totalRead, available));
Serial.readBytes(buffer, toRead); // Use readBytes instead of manual read
file.write(buffer, toRead);
totalRead += toRead;
lastRead = millis();
// Progress indicator
if (totalRead % 20000 == 0) {
Serial.print(totalRead);
Serial.print("/");
Serial.println(fileSize);
}
}
yield();
}
file.close();
Serial.print("Total received: ");
Serial.println(totalRead);
if (totalRead == fileSize) {
Serial.println("Upload complete!");
String fullPath = "/" + filename;
load_image(fullPath.c_str());
} else {
Serial.print("Upload failed - missing ");
Serial.print(fileSize - totalRead);
Serial.println(" bytes");
}
} else {
Serial.println("File open failed");
// split
for (size_t i = 0; i < badges.length(); ++i) {
char c = badges[i];
if (c == ',') {
register_badges.push_back(current);
current = "";
} else current += c;
}
if (current.length()) register_badges.push_back(current);
num_badges = register_badges.size();
Serial.printf("\r\n%u badges registered\r\n", num_badges);
for (const String& b : register_badges) Serial.println(b);
}
}
}
bool load_image(const char* filename) {
// FREE OLD IMAGE FIRST - CRITICAL!
static uint8_t* previousImageData = NULL;
if (previousImageData != NULL) {
free(previousImageData);
previousImageData = NULL;
Serial.println("Freed previous image memory");
}
fs::File file = SPIFFS.open(filename, FILE_READ);
if (!file) {
Serial.println("Failed to open image");
@@ -732,12 +662,14 @@ bool load_image(const char* filename) {
img_dsc.header.cf = LV_COLOR_FORMAT_ARGB8888;
img_dsc.header.w = 130;
img_dsc.header.h = 150;
img_dsc.header.stride = 130 * 4; // 4 bytes per pixel
img_dsc.header.stride = 130 * 4;
img_dsc.data = imageData;
img_dsc.data_size = fileSize;
lv_image_set_src(objects.picture, &img_dsc);
previousImageData = imageData; // Save for next time
Serial.println("Image loaded!");
return true;
}
@@ -769,3 +701,72 @@ bool connect_wifi() {
return true;
}
void listSPIFFS() {
Serial.println("Files in SPIFFS:");
fs::File root = SPIFFS.open("/");
fs::File file = root.openNextFile();
while(file) {
Serial.print(" ");
Serial.print(file.name());
Serial.print(" - ");
Serial.print(file.size());
Serial.println(" bytes");
file = root.openNextFile();
}
}
void handleImageUpload() {
HTTPUpload& upload = server.upload();
static fs::File uploadFile;
if (upload.status == UPLOAD_FILE_START) {
// Delete ALL files in SPIFFS before new upload
Serial.println("Cleaning SPIFFS...");
fs::File root = SPIFFS.open("/");
fs::File file = root.openNextFile();
while(file) {
if (!file.isDirectory()) { // ADD THIS CHECK
String name = String(file.name());
file.close();
SPIFFS.remove(name);
Serial.print("Deleted: ");
Serial.println(name);
file = root.openNextFile();
} else {
file.close();
file = root.openNextFile();
}
}
Serial.println("SPIFFS cleaned");
String filename = "/" + upload.filename;
Serial.print("Upload start: ");
Serial.println(filename);
uploadFile = SPIFFS.open(filename, FILE_WRITE);
if (!uploadFile) {
Serial.println("Failed to open file!");
}
}
else if (upload.status == UPLOAD_FILE_WRITE) {
if (uploadFile) {
uploadFile.write(upload.buf, upload.currentSize);
}
}
else if (upload.status == UPLOAD_FILE_END) {
if (uploadFile) {
uploadFile.close();
Serial.print("Upload complete: ");
Serial.println(upload.totalSize);
}
}
}
void handleUploadComplete() {
HTTPUpload& upload = server.upload();
String filename = "/" + upload.filename;
Serial.print("Loading image: ");
Serial.println(filename);
load_image(filename.c_str());
server.send(200, "text/plain", "Upload OK");
}