Page 1 of 1

Huge newbie with disgusting spaghetti code, ESP32 freezes

Posted: Thu Oct 21, 2021 6:35 am
by Blitz54
Alright. I'll start off by saying I'm sorry for the pain I will cause some of you. I know my code is gonna be painful for some of you, and there's a few incomplete parts, but what matters is it works... but now it doesn't, which is why I'm here.

I started off with an Arduino Mega and an TFT 9486. Everything worked fine, but it was much to slow to update. It's going to replace my fuel gauge, temp gauge, and also show the current gear I'm in, along with other small things I might add. I bought an ESP32 WROOM because it was incredibly faster. I moved my code over from MCU Friend and am now using TFT_eSPI. I did that, and everything worked fine, however I noticed the gear changing was still a little slow, depending on when I pressed the button. There was too many things being checked in loop, which I will of course clean up and improve over time.

Now, smart ol' me realized there was 2 cores I could utilize. So the plan was Gear selection on one, and all the other non critical + instant functions on the other core. Since I've created tasks and divided the workload, my ESP32 hates me. I can provide the logs when I'm not dead tired, but it keeps giving me watchdog timeout errors. No matter how much taskdelay I give core 0.

It's probably obvious to someone else, but the kind of issues I'm experience are as followed:
1. spamming the gear one button will eventually cause a freeze. Sometimes it takes dozens, sometimes it takes three presses.
2. it seems to bug out less when "warm", first time I plug it in it seems more likely to freeze
3. my opening image will sometimes load half the picture, same thing, only when cold.
4. sometimes the screen will freeze when spamming the button, but the serial monitor still works

It's extremely inconsistent. Sometimes it works for hours, other times it instantly bugs out.

link to codepile which I hope works
https://www.codepile.net/pile/kNJg1APv

Re: Huge newbie with disgusting spaghetti code, ESP32 freezes

Posted: Thu Oct 21, 2021 8:27 am
by ESP_Sprite
Thanks for the spaghetti-code warning. I've seen people post worse while not seeing any problem with it...

My guess would be that the TFT code is not re-entrant, that is, you cannot have two tasks call something that writes to the TFT at the same time as the two calls will interfere. You can solve that by either use a FreeRTOS mutex to make sure only one is writing at a time. Alternatively, change the functions of your tasks a little bit: have one (or more) tasks read the sensors and watch the buttons, and when change is needed, have them poke the other tasks (using FreeRTOS task notifications, queues, semaphores, whatnot) to actually draw the new information.

Re: Huge newbie with disgusting spaghetti code, ESP32 freezes

Posted: Fri Oct 22, 2021 5:45 am
by Blitz54
ESP_Sprite wrote:
Thu Oct 21, 2021 8:27 am
Thanks for the spaghetti-code warning. I've seen people post worse while not seeing any problem with it...

My guess would be that the TFT code is not re-entrant, that is, you cannot have two tasks call something that writes to the TFT at the same time as the two calls will interfere.
I think you may have nailed it. I haven't fixed the code yet, but if I spam the gear button which is on task 1, it consistently crashes if task 2 is about to write something, like the temperature or the low washer fluid. The temperature takes a second to show up upon boot, so that would also make sense as to why it felt random at times. Sometimes it was on the initial write, sometimes it was when temperature updated or washer sensor updated. Also explains why this all worked on a single core.

I'll have to look into FreeRTOS tasks more like you suggest. I didn't want to have every sensor on one core as it might be too many to keep the gear printing instant. I don't want to bug you too much, but is there a way I could have Core 1 scanning the gear buttons, and Core 0 scanning all my other sensors usually, but whenever Core 1 needs something printed to the screen, have it interrupt Core 0 to print, then return to it's normal scanning? No other prints/updates need to be instant. Just want to make sure I don't head into this trying to do something that isn't possible.

Thanks tons!

Re: Huge newbie with disgusting spaghetti code, ESP32 freezes

Posted: Fri Oct 22, 2021 8:25 am
by ESP_Sprite
Suggest you refactor your code into a number of tasks for that; you're not limited to just two and FreeRTOS will 'invisibly' handle the juggling of tasks running on one core for you. In this case, you want a low-prio task on core 0 to do the sensor scanning as well as a (normally sleeping) task on core 0 to do the printing, and a task on core 1 scanning the gear buttons. Both the button and sensor task can wake the printing task to update the display (using a queue or semaphore or whatever) and core 0 will go and do that.