Registration of badges and receiving votes only of voting badges implemented.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -954,4 +954,9 @@
|
||||
.pio/libdeps/esp32dev/PicoMQTT/src/PicoMQTT/autoid.h \
|
||||
.pio/libdeps/esp32dev/PicoMQTT/src/PicoMQTT/utils.h \
|
||||
.pio/libdeps/esp32dev/PicoMQTT/src/PicoMQTT/server.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/WebServer.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/HTTP_Method.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nghttp/port/include/http_parser.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/Uri.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/detail/RequestHandler.h \
|
||||
.pio/libdeps/esp32dev/ui/vars.h
|
||||
|
||||
Binary file not shown.
@@ -952,4 +952,9 @@
|
||||
.pio/libdeps/esp32dev/PicoMQTT/src/PicoMQTT/autoid.h \
|
||||
.pio/libdeps/esp32dev/PicoMQTT/src/PicoMQTT/utils.h \
|
||||
.pio/libdeps/esp32dev/PicoMQTT/src/PicoMQTT/server.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/WebServer.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/HTTP_Method.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nghttp/port/include/http_parser.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/Uri.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/detail/RequestHandler.h \
|
||||
.pio/libdeps/esp32dev/ui/vars.h .pio/libdeps/esp32dev/ui/actions.h
|
||||
|
||||
Binary file not shown.
@@ -952,4 +952,9 @@
|
||||
.pio/libdeps/esp32dev/PicoMQTT/src/PicoMQTT/autoid.h \
|
||||
.pio/libdeps/esp32dev/PicoMQTT/src/PicoMQTT/utils.h \
|
||||
.pio/libdeps/esp32dev/PicoMQTT/src/PicoMQTT/server.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/WebServer.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/HTTP_Method.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/nghttp/port/include/http_parser.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/Uri.h \
|
||||
/home/ricardo/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/detail/RequestHandler.h \
|
||||
.pio/libdeps/esp32dev/ui/vars.h .pio/libdeps/esp32dev/ui/actions.h
|
||||
|
||||
Binary file not shown.
@@ -620,7 +620,8 @@
|
||||
|
||||
/*File system interfaces for common APIs */
|
||||
|
||||
/*API for fopen, fread, etc*/
|
||||
|
||||
/*API for fopen, fread, etc */
|
||||
#define LV_USE_FS_STDIO 0
|
||||
#if LV_USE_FS_STDIO
|
||||
#define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
|
||||
|
||||
@@ -676,6 +676,30 @@ void tick_screen_ibvs_processor() {
|
||||
}
|
||||
}
|
||||
|
||||
void create_screen_not_authorized() {
|
||||
lv_obj_t *obj = lv_obj_create(0);
|
||||
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_t *parent_obj = obj;
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
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 !!!");
|
||||
}
|
||||
}
|
||||
|
||||
tick_screen_not_authorized();
|
||||
}
|
||||
|
||||
void tick_screen_not_authorized() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef void (*tick_screen_func_t)();
|
||||
@@ -688,6 +712,7 @@ tick_screen_func_t tick_screen_funcs[] = {
|
||||
tick_screen_vote_results,
|
||||
tick_screen_ibvs_mode,
|
||||
tick_screen_ibvs_processor,
|
||||
tick_screen_not_authorized,
|
||||
};
|
||||
void tick_screen(int screen_index) {
|
||||
tick_screen_funcs[screen_index]();
|
||||
@@ -709,4 +734,5 @@ void create_screens() {
|
||||
create_screen_vote_results();
|
||||
create_screen_ibvs_mode();
|
||||
create_screen_ibvs_processor();
|
||||
create_screen_not_authorized();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef struct _objects_t {
|
||||
lv_obj_t *vote_results;
|
||||
lv_obj_t *ibvs_mode;
|
||||
lv_obj_t *ibvs_processor;
|
||||
lv_obj_t *not_authorized;
|
||||
lv_obj_t *obj0;
|
||||
lv_obj_t *obj1;
|
||||
lv_obj_t *obj2;
|
||||
@@ -50,6 +51,7 @@ enum ScreensEnum {
|
||||
SCREEN_ID_VOTE_RESULTS = 6,
|
||||
SCREEN_ID_IBVS_MODE = 7,
|
||||
SCREEN_ID_IBVS_PROCESSOR = 8,
|
||||
SCREEN_ID_NOT_AUTHORIZED = 9,
|
||||
};
|
||||
|
||||
void create_screen_start();
|
||||
@@ -75,6 +77,9 @@ void tick_screen_ibvs_mode();
|
||||
|
||||
void create_screen_ibvs_processor();
|
||||
void tick_screen_ibvs_processor();
|
||||
|
||||
void create_screen_not_authorized();
|
||||
void tick_screen_not_authorized();
|
||||
|
||||
void tick_screen_by_id(enum ScreensEnum screenId);
|
||||
void tick_screen(int screen_index);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define MAIN_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <vector>
|
||||
#include <lvgl.h>
|
||||
#include <TFT_eSPI.h>
|
||||
#include <XPT2046_Touchscreen.h>
|
||||
@@ -10,11 +11,15 @@
|
||||
#include <WiFi.h>
|
||||
#include <PicoMQTT.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <WebServer.h>
|
||||
#include "vars.h"
|
||||
#include "actions.h"
|
||||
|
||||
|
||||
#define IBVS_BADGE 1
|
||||
#define IBVS_PROCESSOR 2
|
||||
#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
|
||||
|
||||
|
||||
// Struct objects for main data
|
||||
|
||||
336
src/main.cpp
336
src/main.cpp
@@ -1,10 +1,9 @@
|
||||
#include <Arduino.h>
|
||||
#include "main.h"
|
||||
|
||||
#define START_SCREEN_WAIT 4 * 200 // First number is the time in seconds
|
||||
|
||||
const char *ssid = "";
|
||||
const char *password = "";
|
||||
const char *ssid = "CIA";
|
||||
const char *password = "passespacarola";
|
||||
|
||||
// Touchscreen pinout
|
||||
#define XPT2046_IRQ 36
|
||||
@@ -17,7 +16,7 @@ int x, y, z;
|
||||
#define SCREEN_HEIGHT 320
|
||||
|
||||
// MQTT settings
|
||||
const char* mqtt_server_ip = "10.164.67.98";
|
||||
const char* mqtt_server_ip = "10.139.95.154";
|
||||
const int mqtt_port = 1883;
|
||||
//const char* mqtt_user = "badge_device";
|
||||
//const char* mqtt_password = "letmein";
|
||||
@@ -25,6 +24,8 @@ PicoMQTT::Client mqtt_client(mqtt_server_ip);
|
||||
PicoMQTT::Server mqtt_server;
|
||||
|
||||
// Global variables
|
||||
size_t num_badges;
|
||||
size_t curr_vote = 0;
|
||||
int start_screen = 0;
|
||||
int ibvs_mode = 0;
|
||||
int ping_number = 0;
|
||||
@@ -32,14 +33,18 @@ unsigned long last_publish_time = 0;
|
||||
bool ibvs_mode_done = false;
|
||||
bool screenNeedsUpdate = true;
|
||||
bool configDone = false;
|
||||
bool get_imageDone = true;
|
||||
bool get_imageDone = false;
|
||||
bool winnerDone = false;
|
||||
bool vote_end = false;
|
||||
bool wifi_connected = false;
|
||||
char current_screen = 'A';
|
||||
char winner = '0';
|
||||
char Badge_ID[9];
|
||||
String badges;
|
||||
std::vector<String> register_badges;
|
||||
String current;
|
||||
String topic_test = "voting/ready";
|
||||
String topic_winner = "voting/winner";
|
||||
String message = "Testing da thing #";
|
||||
LongText question = {"To be or not to be ?", 4, 40};
|
||||
ShortText orgev = {" ATO", 4, 4};
|
||||
@@ -50,7 +55,9 @@ ShortText item3 = {"Maybe", 4, 140};
|
||||
ShortText item4 = {"Abstain", 4, 170};
|
||||
ShortText item5 = {"Null", 4, 200};
|
||||
|
||||
//lv_image_dsc_t dynamic_image;
|
||||
lv_image_dsc_t* dynamic_img_dsc = NULL;
|
||||
|
||||
//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];
|
||||
@@ -66,10 +73,76 @@ void setup() {
|
||||
}
|
||||
Serial.println("SPIFFS Mounted Successfully");
|
||||
|
||||
|
||||
String LVGL_Arduino = String("LVGL Library Version: ") + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
|
||||
Serial.println(LVGL_Arduino);
|
||||
// Start LVGL
|
||||
lv_init();
|
||||
|
||||
// ----------- SPIFFS driver for LVGL -----------------------------------
|
||||
// Register SPIFFS with LVGL
|
||||
static lv_fs_drv_t fs_drv;
|
||||
lv_fs_drv_init(&fs_drv);
|
||||
fs_drv.letter = 'S';
|
||||
|
||||
fs_drv.open_cb = [](lv_fs_drv_t *drv, const char *path, lv_fs_mode_t mode) -> void* {
|
||||
fs::File *file = new fs::File();
|
||||
|
||||
// Add leading slash if not present
|
||||
String fullPath = path;
|
||||
if (!fullPath.startsWith("/")) {
|
||||
fullPath = "/" + fullPath;
|
||||
}
|
||||
|
||||
Serial.print("Opening: ");
|
||||
Serial.println(fullPath);
|
||||
|
||||
if (mode == LV_FS_MODE_RD) {
|
||||
*file = SPIFFS.open(fullPath, FILE_READ);
|
||||
} else {
|
||||
*file = SPIFFS.open(fullPath, FILE_WRITE);
|
||||
}
|
||||
|
||||
if (file->operator bool()) {
|
||||
Serial.println("File opened successfully!");
|
||||
return (void*)file;
|
||||
} else {
|
||||
Serial.println("File open failed!");
|
||||
delete file;
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
fs_drv.close_cb = [](lv_fs_drv_t *drv, void *file_p) -> lv_fs_res_t {
|
||||
fs::File *file = (fs::File*)file_p;
|
||||
file->close();
|
||||
delete file;
|
||||
return LV_FS_RES_OK;
|
||||
};
|
||||
|
||||
fs_drv.read_cb = [](lv_fs_drv_t *drv, void *file_p, void *buf, uint32_t btr, uint32_t *br) -> lv_fs_res_t {
|
||||
fs::File *file = (fs::File*)file_p;
|
||||
*br = file->read((uint8_t*)buf, btr);
|
||||
return LV_FS_RES_OK;
|
||||
};
|
||||
|
||||
fs_drv.seek_cb = [](lv_fs_drv_t *drv, void *file_p, uint32_t pos, lv_fs_whence_t whence) -> lv_fs_res_t {
|
||||
fs::File *file = (fs::File*)file_p;
|
||||
file->seek(pos);
|
||||
return LV_FS_RES_OK;
|
||||
};
|
||||
|
||||
fs_drv.tell_cb = [](lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p) -> lv_fs_res_t {
|
||||
fs::File *file = (fs::File*)file_p;
|
||||
*pos_p = file->position();
|
||||
return LV_FS_RES_OK;
|
||||
};
|
||||
|
||||
lv_fs_drv_register(&fs_drv);
|
||||
Serial.println("LVGL FS driver registered");
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Register print function for debugging
|
||||
lv_log_register_print_cb(log_print);
|
||||
|
||||
@@ -100,7 +173,10 @@ void setup() {
|
||||
xTaskCreate(mqtt_manager, "Manage_mqtt", 8192, NULL, 1, NULL);
|
||||
|
||||
wifi_connected = connect_wifi();
|
||||
|
||||
// For web image uploader
|
||||
/* server.on("/upload", HTTP_POST, []() {}, handleImageUpload);
|
||||
server.begin();
|
||||
Serial.println("Web server started"); */
|
||||
}
|
||||
|
||||
void loop() {
|
||||
@@ -113,10 +189,13 @@ void loop() {
|
||||
configDone = true;
|
||||
}
|
||||
|
||||
if (!get_imageDone) {
|
||||
get_image();
|
||||
/* if (!get_imageDone) {
|
||||
server.handleClient();
|
||||
get_imageDone = true;
|
||||
}
|
||||
*/
|
||||
|
||||
// server.handleClient(); // For web image uploader
|
||||
get_image();
|
||||
|
||||
if (winner != '0' && !winnerDone) {
|
||||
@@ -132,7 +211,7 @@ void loop() {
|
||||
configDone = true;
|
||||
}
|
||||
|
||||
/* if (millis() - last_publish_time >= 60000) {
|
||||
/* 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);
|
||||
@@ -140,11 +219,14 @@ void loop() {
|
||||
} */
|
||||
|
||||
if (vote_end) {
|
||||
|
||||
message = "3";
|
||||
mqtt_server.publish(topic_winner, message);
|
||||
vote_end = false;
|
||||
}
|
||||
|
||||
}
|
||||
vTaskDelay(8000 / portTICK_PERIOD_MS);
|
||||
// vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void serial_config() {
|
||||
@@ -301,8 +383,34 @@ void mqtt_subs() {
|
||||
});
|
||||
}
|
||||
if (ibvs_mode == IBVS_PROCESSOR) {
|
||||
mqtt_server.subscribe("#", [](const char * topic, const char * payload) {
|
||||
Serial.printf("Received message in topic '%s': %s\r\n", topic, payload);
|
||||
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 = curr_badge.substring(0, 8);
|
||||
|
||||
bool found = false;
|
||||
for (const String& badge : register_badges) {
|
||||
if (curr_badge == badge) { // exact match
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
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
|
||||
}
|
||||
|
||||
if (curr_vote == num_badges) vote_end = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -310,7 +418,7 @@ void mqtt_subs() {
|
||||
void mqtt_send_result(char result) {
|
||||
|
||||
char topic[32];
|
||||
sprintf(topic, "voting/%s", Badge_ID);
|
||||
sprintf(topic, "voter/%s", Badge_ID);
|
||||
mqtt_client.publish(topic, String(result).c_str());
|
||||
Serial.printf("Published \'%c\' to topic : ", result);
|
||||
Serial.println(topic);
|
||||
@@ -426,6 +534,10 @@ void screen_manager(void *pvParameters) {
|
||||
break;
|
||||
case 'H':
|
||||
loadScreen(SCREEN_ID_IBVS_PROCESSOR);
|
||||
// lv_scr_load_anim(objects.vote_wait, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, false);
|
||||
break;
|
||||
case 'I':
|
||||
loadScreen(SCREEN_ID_NOT_AUTHORIZED);
|
||||
// lv_scr_load_anim(objects.vote_wait, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, false);
|
||||
break;
|
||||
}
|
||||
@@ -441,11 +553,11 @@ void screen_manager(void *pvParameters) {
|
||||
void mqtt_manager(void *pvParameters) {
|
||||
while (1) {
|
||||
if (ibvs_mode == IBVS_BADGE) {
|
||||
if (!ibvs_mode_done){
|
||||
if (!ibvs_mode_done) {
|
||||
mqtt_client.begin();
|
||||
mqtt_subs();
|
||||
ibvs_mode_done = true;
|
||||
Serial.println("mqtt_subs() done once in badge mode"); // Debug
|
||||
Serial.println("mqtt_subs() done once in badge mode"); // Debug
|
||||
}
|
||||
mqtt_client.loop();
|
||||
vTaskDelay(5 / portTICK_PERIOD_MS);
|
||||
@@ -468,110 +580,165 @@ 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) {
|
||||
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
|
||||
}
|
||||
}
|
||||
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') {
|
||||
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() {
|
||||
Serial.println("DEBUG: get_image() called");
|
||||
|
||||
if (Serial.available() > 0) {
|
||||
Serial.println("DEBUG: Data available!");
|
||||
String command = Serial.readStringUntil('\n');
|
||||
command.trim();
|
||||
|
||||
Serial.print("DEBUG: Command = '");
|
||||
Serial.print(command);
|
||||
Serial.println("'");
|
||||
|
||||
if (command.startsWith("UPLOAD_IMAGE:")) {
|
||||
// Extract filename and size
|
||||
int colonPos = command.indexOf(':', 13);
|
||||
String filename = command.substring(13, colonPos);
|
||||
int fileSize = command.substring(colonPos + 1).toInt();
|
||||
|
||||
Serial.println("Ready to receive image");
|
||||
Serial.print("Filename: ");
|
||||
Serial.println(filename);
|
||||
Serial.print("Size: ");
|
||||
Serial.println(fileSize);
|
||||
Serial.print("Receiving ");
|
||||
Serial.print(filename);
|
||||
Serial.print(" (");
|
||||
Serial.print(fileSize);
|
||||
Serial.println(" bytes)");
|
||||
|
||||
// Read data as it arrives
|
||||
Serial.println("DEBUG: Starting to receive data...");
|
||||
fs::File file = SPIFFS.open("/" + filename, FILE_WRITE);
|
||||
if (file) {
|
||||
Serial.println("DEBUG: File opened");
|
||||
byte buffer[128]; // Smaller buffer
|
||||
int remaining = fileSize;
|
||||
int bytesReceived = 0;
|
||||
unsigned long startTime = millis();
|
||||
|
||||
while (remaining > 0 && (millis() - startTime < 30000)) {
|
||||
int available = Serial.available();
|
||||
if (available > 0) {
|
||||
int toRead = min(remaining, min(128, available));
|
||||
int actualRead = Serial.readBytes(buffer, toRead);
|
||||
file.write(buffer, actualRead);
|
||||
remaining -= actualRead;
|
||||
bytesReceived += actualRead;
|
||||
delay(1000);
|
||||
|
||||
// Print progress every 10KB
|
||||
if (bytesReceived % 10000 < 128) {
|
||||
Serial.print("Received: ");
|
||||
Serial.print(bytesReceived);
|
||||
Serial.print(" / ");
|
||||
Serial.println(fileSize);
|
||||
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");
|
||||
}
|
||||
}
|
||||
yield(); // Feed watchdog
|
||||
}
|
||||
|
||||
file.close();
|
||||
Serial.print("DEBUG: File closed. Bytes received: ");
|
||||
Serial.println(bytesReceived);
|
||||
|
||||
if (remaining == 0) {
|
||||
Serial.println("Image uploaded successfully!");
|
||||
String fullPath = "/" + filename;
|
||||
Serial.println("DEBUG: Calling load_image...");
|
||||
load_image(fullPath.c_str());
|
||||
} else {
|
||||
Serial.print("ERROR: Incomplete upload. Remaining: ");
|
||||
Serial.println(remaining);
|
||||
}
|
||||
} else {
|
||||
Serial.println("Failed to open file for writing");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool load_image(const char* filename) {
|
||||
fs::File file = SPIFFS.open(filename, FILE_READ);
|
||||
if (!file) {
|
||||
Serial.println("Failed to open image file");
|
||||
Serial.println("Failed to open image");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t fileSize = file.size();
|
||||
Serial.print("Image file size: ");
|
||||
Serial.print("Loading raw image, size: ");
|
||||
Serial.println(fileSize);
|
||||
|
||||
// Allocate memory for the image data
|
||||
// Allocate memory for raw pixel data
|
||||
uint8_t* imageData = (uint8_t*)malloc(fileSize);
|
||||
if (!imageData) {
|
||||
Serial.println("Failed to allocate memory for image");
|
||||
Serial.println("Memory allocation failed");
|
||||
file.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the entire file into memory
|
||||
// Read raw data
|
||||
file.read(imageData, fileSize);
|
||||
file.close();
|
||||
|
||||
// Set the image source to the loaded data
|
||||
// LVGL will decode the BMP automatically
|
||||
lv_image_set_src(objects.picture, imageData);
|
||||
// Create LVGL image descriptor for raw ARGB8888
|
||||
static lv_image_dsc_t img_dsc;
|
||||
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.data = imageData;
|
||||
img_dsc.data_size = fileSize;
|
||||
|
||||
Serial.println("Image loaded successfully!");
|
||||
lv_image_set_src(objects.picture, &img_dsc);
|
||||
|
||||
Serial.println("Image loaded!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -600,4 +767,5 @@ bool connect_wifi() {
|
||||
mac.replace(":", ""); // Remove all colons
|
||||
strcpy(Badge_ID, mac.substring(0, 8).c_str()); // Get first 8 characters, 4 bytes
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user