Buonasera a tutti, sto cercando da tempo di realizzare un macropad (stile Streamdeck), quindi con pulsanti, un encoder magnetico e uno schermo ili9488, per la cui grafica ho usato, per semplicità, Squareline studio (che usa la libreria LVGL). Tuttavia sta dando molti più problemi di quel che mi aspettavo, in particolar modo negli ultimi giorni non da un effettivo errore ma compare sul monitor seriale "Guru Meditation Error", riportato per intero qui sotto:
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d8727 PS : 0x00060b30 A0 : 0x800d9f61 A1 : 0x3ffb20d0
A2 : 0x00000000 A3 : 0x00000001 A4 : 0x00060920 A5 : 0x3f46724c
A6 : 0x00001017 A7 : 0x00000004 A8 : 0x00000000 A9 : 0x3ffb8188
A10 : 0x80000001 A11 : 0xb33fffff A12 : 0x80091c2f A13 : 0x3ffbcbe0
A14 : 0x00000003 A15 : 0x00060023 SAR : 0x00000020 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000004 LBEG : 0x4008bf4d LEND : 0x4008bf5d LCOUNT : 0xffffffff
Backtrace: 0x400d8724:0x3ffb20d0 0x400d9f5e:0x3ffb20f0 0x400da2bd:0x3ffb21d0 0x400d1cfc:0x3ffb21f0 0x400d2986:0x3ffb2210 0x40107838:0x3ffb2270 0x400919ae:0x3ffb2290
ELF file SHA256: d2d544ab05d1f87b
Da quel che ho letto online ho capito che si tratta di un problema di allocazione della memoria, in quanto si sta chiedendo di accedere a dei byte "illegali", ma oltre a questo problema generale non sono in grado di leggerci di più.
La cosa strana è che non ho fatto chissà che modifiche (o addirittura nessuna) che mi spunta nuovamente. Ho già provato in molti modi (alleggerendo di molto il buffer per lvgl, togliendo varie librerie bluetoth che potrebbero dare problemi...) ma non sono riuscito a capirne il perché.
Vi lascio qui il codice, perdonatemi se non è proprio bellissimo e soprattutto se è un po' disortinato
#include <AS5600.h>
#include <lvgl.h>
#include <TFT_eSPI.h>
#include <ui.h>
#include <Keypad.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <UrlEncode.h>
#include <WiFiUdp.h>
WiFiClient client;
HTTPClient http;
WiFiUDP udp;
const char* hostPC = "192.168.1.9";
const int udpPort = 4210;
//Var. encoder
AS5600 as5600;
float primoangolo;
float angolo;
int difangolo;
//Var. wifi
const char* ssid = "censurato";
const char* password = "censurato";
//Var. whatsapp bot
String phoneNumber = "censurato";
String apiKey = "censurato";
bool LED;
//Var. pagine
int screen = 1;
int enc = 0;
//Inizializzazione schermo
unsigned long mil = millis();
static const uint16_t screenWidth = 480;
static const uint16_t screenHeight = 320;
#define LVGL_BUFFER_LINES 20
static lv_color_t buf1[screenWidth * LVGL_BUFFER_LINES];
TFT_eSPI tft = TFT_eSPI( screenWidth, screenHeight );
void my_disp_flush (lv_display_t *disp, const lv_area_t *area, uint8_t *pixelmap)
{
uint32_t w = ( area->x2 - area->x1 + 1 );
uint32_t h = ( area->y2 - area->y1 + 1 );
if (LV_COLOR_16_SWAP) {
size_t len = lv_area_get_size( area );
lv_draw_sw_rgb565_swap( pixelmap, len );
}
tft.startWrite();
tft.setAddrWindow( area->x1, area->y1, w, h );
tft.pushColors( (uint16_t*) pixelmap, w * h, true );
tft.endWrite();
lv_disp_flush_ready( disp );
}
static uint32_t my_tick_get_cb (void) { return millis(); }
//Inizializzazione keypad
const byte ROWS = 3;
const byte COLS = 3;
int keys[ROWS][COLS] = {
{1,2,3},
{4,5,6},
{7,8,9}
};
byte rowPins[ROWS] = {23, 32, 25};
byte colPins[COLS] = {13, 14, 12};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
//Funzione whatsapp bot
void sendMessage(String message){
String url = "https://api.callmebot.com/whatsapp.php?phone=" + phoneNumber + "&apikey=" + apiKey + "&text=" + urlEncode(message);
HTTPClient http2;
http2.begin(url);
http2.addHeader("Content-Type", "application/x-www-form-urlencoded");
int httpResponseCode = http2.POST(url);
if (httpResponseCode == 200){
Serial.print("Message sent successfully");
}
else{
Serial.println("Error sending the message");
Serial.print("HTTP response code: ");
Serial.println(httpResponseCode);
}
http2.end();
}
//Funzione invio macro
void macro(String macro){
udp.beginPacket(hostPC, udpPort);
udp.print(macro);
udp.endPacket();
Serial.println("Inviato: "+ macro);
delay(100);
}
void setup ()
{
Serial.begin( 9600 );
Serial.println("Inizializzazione lv...");
lv_init();
Serial.println("lvgl inizializzato");
if (!buf1) {
Serial.println("Allocazione buffer fallita!");
while(1);
}
#if LV_USE_LOG != 0
lv_log_register_print_cb( my_print );
#endif
Serial.println("Inizializzazione tft");
tft.begin();
tft.setRotation( 3 );
tft.setSwapBytes(true);
Serial.println("tft inizializzazione");
static lv_disp_t* disp;
disp = lv_display_create( screenWidth, screenHeight );
Serial.println("flush start");
lv_display_set_buffers( disp, buf1, NULL, screenWidth * LVGL_BUFFER_LINES, LV_DISPLAY_RENDER_MODE_PARTIAL);
Serial.println("flush 2");
lv_display_set_flush_cb( disp, my_disp_flush );
Serial.println("display flush");
lv_tick_set_cb( my_tick_get_cb );
ui_init();
Serial.println( "Setup done");
delay(500);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
keypad.addEventListener(keypadEvent);
as5600.begin();
as5600.setDirection(AS5600_CLOCK_WISE);
primoangolo = as5600.rawAngle() * 360.0 / 4096;
delay(100);
macro("funziono");
}
lv_obj_t* schermi[]{ui_Screen1, ui_Screen2, ui_Screen3};
//Macro funzioni
void vuota(){
Serial.println("vuoto")
}
void Change(int schermo){
lv_scr_load(schermi[schermo]);
screen = schermo;
}
void setLED(String aggiunta){
http.useHTTP10(true);
String urlLED = "http://192.168.1.14/win" + aggiunta;
http.begin(client, urlLED);
http.GET();
http.end();
}
void setRGB(int red, int green, int blue){
setLED("&FX=0&R="+String(red)+"&G="+String(green)+"&B="+String(blue));
}
void setLedColorHSV(float h, double s, double v) {
double r=0;
double g=0;
double b=0;
double hf=h/60.0;
int i=(int)floor(h/60.0);
double f = h/60.0 - i;
double pv = v * (1 - s);
double qv = v * (1 - s*f);
double tv = v * (1 - s * (1 - f));
switch (i)
{
case 0:
r = v;
g = tv;
b = pv;
break;
case 1:
r = qv;
g = v;
b = pv;
break;
case 2:
r = pv;
g = v;
b = tv;
break;
case 3:
r = pv;
g = qv;
b = v;
break;
case 4:
r = tv;
g = pv;
b = v;
break;
case 5:
r = v;
g = pv;
b = qv;
break;
}
int red=constrain((int)255*r,0,255);
int green=constrain((int)255*g,0,255);
int blue=constrain((int)255*b,0,255);
setRGB(red,green,blue);
}
//Funzioni
void func1 (){
macro("sospendi");
Serial.println("func 1");
}
void func1HOLD (){
macro("spegni");
Serial.println("func 1");
}
void func2 (){
Serial.println("func 2");
}
void func2HOLD (){
Change(3);
float partenza = angolo;
Serial.println("func 2 hold");
}
void func3 (){
macro("Google");
Serial.println("func 3");
}
void func3HOLD (){
macro("scuola");
Serial.println("func 3 hold");
}
void func4 (){
macro("screenshot1");
Serial.println("func 4");
}
void func4HOLD (){
macro("screenshot2");
Serial.println("func 4 hold");
}
void func5 (){
macro("pausa");
Serial.println("func 5");
}
void func6 (){
macro("next");
Serial.println("func 6");
}
void func7 (){
macro("spotify");
Serial.println("func 7");
}
void func8 (){
Change(2);
Serial.println("func 8");
}
void func9 (){
Change(1);
Serial.println("func 9");
}
void func10(){
sendMessage("/trova");
Serial.println("func 10");
}
void func11 (){
Serial.println("func 11");
}
void func12 (){
Serial.println("func 12");
}
void func13 (){
macro("note");
Serial.println("func 13");
}
void func14 (){
macro("AI");
Serial.println("func 14");
}
void func14HOLD (){
macro("AIfoto");
Serial.println("func 14 hold");
}
void func15 (){
Change(3);
Serial.println("func 15");
}
void funcencoder(){
enc = (enc+1)%5;
}
//Array funzioni
void (*function[2][8])(void) =
{
{func1,func2,func3,func4,func5,func6,func7,func8},
{func9,func10,func11,func12,func13,func14,func15,vuota},
};
void (*functionHOLD[2][8])(void) =
{
{func1HOLD,func2HOLD,func3HOLD,func4HOLD,vuota,vuota,vuota,vuota},
{vuota,vuota,vuota,vuota,func14HOLD,vuota,vuota,vuota},
};
void keypadEvent(KeypadEvent key){
if (keypad.getState() == PRESSED){
while (keypad.getState() == PRESSED){
delay(1);
}
if (keypad.getState() == HOLD){
Serial.println("HOLD");
functionHOLD[screen][key]();
}
else{
Serial.println("PRESSED");
function[screen][key]();
}
}
}
void loop ()
{
delay(1000);
Change(2);
delay(1000);
Change(1);
macro(".");
angolo = as5600.rawAngle() * (360.0 / 4096);
difangolo = int(primoangolo-angolo);
if (abs(difangolo)>1 && screen != 4){
switch(enc){
case 1:
if (difangolo > 0){
for(int i=0;i<=abs(difangolo);i++){
macro("volume up");
delay(1);
}
}
else{
for(int i=0;i<=abs(difangolo);i++){
macro("volume down");
delay(1);
}
}
case 2:
setLED("&A=~"+String(difangolo));
}
}
if (screen == 4){
setLedColorHSV(angolo,1,1);
}
int key = keypad.getKey();
lv_timer_handler();
}
A giudicare dai Serial.print usati per il debug, non è un problema di inizializzazione delle varie librerie, errore, da quel che ho letto, molto comune in questi casi.
Grazie in anticipo per chiunque provi almeno a darmi una mano!