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

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -618,7 +618,7 @@ void create_screen_ibvs_processor() {
lv_obj_t *parent_obj = obj;
{
lv_obj_t *obj = lv_spinner_create(parent_obj);
lv_obj_set_pos(obj, 211, 120);
lv_obj_set_pos(obj, 232, 100);
lv_obj_set_size(obj, 80, 80);
lv_spinner_set_anim_params(obj, 1000, 60);
}
@@ -638,7 +638,7 @@ void create_screen_ibvs_processor() {
lv_obj_t *obj = lv_textarea_create(parent_obj);
objects.obj11 = obj;
lv_obj_set_pos(obj, 10, 180);
lv_obj_set_size(obj, 180, 50);
lv_obj_set_size(obj, 208, 50);
lv_textarea_set_max_length(obj, 128);
lv_textarea_set_one_line(obj, false);
lv_textarea_set_password_mode(obj, false);
@@ -681,7 +681,7 @@ void create_screen_not_authorized() {
objects.not_authorized = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, 320, 240);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff7e2929), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffff0000), LV_PART_MAIN | LV_STATE_DEFAULT);
{
lv_obj_t *parent_obj = obj;
{
@@ -689,8 +689,8 @@ void create_screen_not_authorized() {
lv_obj_set_pos(obj, 26, 97);
lv_obj_set_size(obj, 268, 47);
lv_label_set_long_mode(obj, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_style_text_font(obj, &lv_font_montserrat_24, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_label_set_text(obj, "This Badge is no authorized in this voting session !!!");
lv_obj_set_style_text_font(obj, &lv_font_montserrat_40, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_label_set_text(obj, "This Badge is not authorized in this voting session !!!");
}
}

View File

@@ -21,6 +21,13 @@
#define START_SCREEN_WAIT (4 * 200) // First number is the time in seconds
#define NUM_OF_BADGES (10 + (10*8)) // First and second number have to be equal and is the number of badges
// 0 = off
// 1 = level-1 (verbose) prints ONLY level-1 messages
// 2 = level-2 (normal) prints level-2 AND (because level-2 “contains” level-1) also level-1
#define DBG_LEVEL 1 // change at build-time
#define DBG_L1(fmt, ...) do { if (DBG_LEVEL >= 1) Serial.printf(fmt, ##__VA_ARGS__); } while (0)
#define DBG_L2(fmt, ...) do { if (DBG_LEVEL >= 2) Serial.printf(fmt, ##__VA_ARGS__); } while (0)
// Struct objects for main data
struct ShortText {
@@ -49,7 +56,9 @@ void log_print(lv_log_level_t level, const char * buf);
void touchscreen_read(lv_indev_t * indev, lv_indev_data_t * data);
void screen_manager(void *pvParameters);
void mqtt_manager(void *pvParameters);
void get_image();
bool load_image(const char* filename);
void listSPIFFS();
void handleImageUpload();
void handleUploadComplete();
#endif

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");
}