CoretechR / OMOTE

Open Source Remote Using ESP32 and LVGL
https://hackaday.io/project/191752
GNU General Public License v3.0
1.02k stars 114 forks source link

Refactored code base and added WIFI configuration menu #29

Closed bittnert closed 1 month ago

bittnert commented 11 months ago

To improve maintainability I refactored to code and tried to improve (lower) data and control coupling. I created modules with specific responsibilities. The communication between modules only happens via API functions and not via global variables or similar. I focused on the settings page and the wifi and battery handling for now. The other tabs are still not refactored yet.

Additionally, I changed the wifi handling. Now the credentials are no longer defined hard coded in the code but can be configured via the settings tab. The credentials are then stored in flash (after the connection was successful) so they don't need to be re-entered after reboot (or even after flashing a new firmware image).

Refactored code base:

Added WIFI configuration menu

CoretechR commented 11 months ago

Hi @bittnert, this is amazing! The WiFi configuration is exactly what I had in mind. There are some issues still when I run your code in the hardware: The backlight only comes on briefly and then turns dark. If I force the backlight on, I get to the "searching for networks" screen, but then it freezes. These problems can probably be solves fairly easily. I assume you don't have a PCB yet, right? I will take a closer look over the weekend and see if I can get it to run.

bittnert commented 11 months ago

Hi @CoretechR, unfortunately I don't have a PCB yet. I will need to order and assemble one. I used a breadboard to test the software.

About the screen turning black, I realized a difference in the initialization of the LEDC module between the original and the refactored code. I aligned this now and created another commit. Maybe you can check if this fixes the issue.

About the freeze, could you check the uart output? I currently have the suspicion that the firmware might go to sleep but does not turn of the LCD. When it goes to sleep it does not turn off the screen on my setup but I thought this is a hardware issue, not a software one.

We will probably have to change/update the handling of the sleep timer to not go into sleep as long as the we are searching for networks.

BR

CoretechR commented 11 months ago

Now it's stuck in a boot loop with this error: assert failed: ledc_clk_cfg_to_global_clk ledc.c:443 (false) I think something's wrong with the ldc initialization.

Dark1886 commented 11 months ago

@bittnert I am seeing the same behavior, here is the output from my unit.

[    23][D][esp32-hal-cpu.c:244] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
[    57][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 0 - WIFI_READY
[   150][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 2 - STA_START
[   151][E][Preferences.cpp:483] getString(): nvs_get_str len fail: SSID NOT_FOUND
[   154][E][Preferences.cpp:483] getString(): nvs_get_str len fail: password NOT_FOUND
no SSID or password stored

assert failed: ledc_clk_cfg_t�[    23][D][esp32-hal-cpu.c:244] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
[    57][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 0 - WIFI_READY
[   153][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 2 - STA_START
[   154][E][Preferences.cpp:483] getString(): nvs_get_str len fail: SSID NOT_FOUND
[   156][E][Preferences.cpp:483] getString(): nvs_get_str len fail: password NOT_FOUND
no SSID or password stored

assert failed: ledc_clk_cfg_to_global_clk ledc.c:443 (false)

Backtrace: 0x400840c9:0x3ffb1f40 0x4008cec9:0x3ffb1f60 0x40093375:0x3ffb1f80 0x40104eb5:0x3ffb20b0 0x401051b5:0x3ffb2110 0x400d2352:0x3ffb2150 0x400d3f9f:0x3ffb2250 0x40102212:0x3ffb2290

ELF file SHA256: 994b92633ee5d092

Rebooting...

But after a 30~ seconds of the device sitting there, the screen did boot up and I was able to get into the network scanning interface, although it did hang after the scan completed.

Rebooting...
[    23][D][esp32-hal-cpu.c:244] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
[    57][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 0 - WIFI_READY
[   153][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 2 - STA_START
[   153][E][Preferences.cpp:483] getString(): nvs_get_str len fail: SSID NOT_FOUND
[   156][E][Preferences.cpp:483] getString(): nvs_get_str len fail: password NOT_FOUND
no SSID or password stored

assert failed: ledc_clk_cfg_to_global_clk ledc.c:443 (false)

Backtrace: 0x400840c9:0x3ffb1f40 0x4008cec9:0x3ffb1f60 0x40093375:0x3ffb1f80 0x40104eb5:0x3ffb20b0 0x401051b5:0x3ffb2110 0x400d2352:0x3ffb2150 0x400d3f9f:0x3ffb2250 0x40102212:0x3ffb2290

ELF file SHA256: 994b92633ee5d092

Rebooting...
[    23][D][esp32-hal-cpu.c:244] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
[    57][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 0 - WIFI_READY
[   153][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 2 - STA_START
[   154][E][Preferences.cpp:483] getString(): nvs_get_str len fail: SSID NOT_FOUND
[   157][E][Preferences.cpp:483] getString(): nvs_get_str len fail: password NOT_FOUND
no SSID or password stored
[   563][I][esp32-hal-i2c.c:75] i2cInit(): Initialising I2C Master: sda=19 scl=22 freq=400000
[   564][W][Wire.cpp:301] begin(): Bus already started in Master Mode.
[   828][W][Wire.cpp:301] begin(): Bus already started in Master Mode.
Setup finised in 920ms.
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
charging?
[ 20454][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 1 - SCAN_DONE
WIFI scan done

29 found
---- Closed the serial port COM13 ----
bittnert commented 11 months ago

very interesting because on my side it works. I'm afraid I have to get the proper hardware before I can debug this which will take some time.

@CoretechR What we could try is to use ledcsetup and "invert" the signal in software. LEDC creates a PWM signal so inverting would basically flip the high and low portions of the signal (thats at least my understanding).

We could revert the last commit and then update the function bl_slider_event_cb in displaySettings.cpp to map the slider value. This code should invert the signal

*backlight_brightness = map(constrain(lv_slider_get_value(slider), 30, 255), 30, 255, 255, 30);

@Dark1886 From the UART output I see that you have found 29 networks. To be honest, I never tested it with so many networks, maybe the firmware has troubles with this amount. Could you try to limit the amout of networks to a smaller number by overwriting the "no_networks" variable in the WiFiEvent handler (in wifiHandler.cpp)?

MatthewColvin commented 11 months ago

Hey @bittnert have you checked out the abstraction branch?

I have started up a basic HAL to allow the UI code to be separate from the hardware. I think we have a few options here. We can possibly use your new code to drive the HAL or I have been toying with this idea of having small interfaces for individual hardware components which your new classes could be the implementation for.

Do you think we could chat sometime?

bittnert commented 11 months ago

Hi @MatthewColvin, I just checked out the abstraction branch and I think the goal of this branch was the same what I did so I think it would be a good idea to maybe merge the two approaches. I also saw that you used singleton classes which is something I was also thinking about and I think this is a good approach as we will always only have one object at a time.

I would like to have a chat about this. Unfortunately I'm not very familiar with GitHub (yet) as we are using bitbucket at work. What chat protocol/app would you propose and at what time? I'm currently on central European summer time.

MatthewColvin commented 11 months ago

Hey @bittnert it would probably be pretty good if you had discord because we can voice call and chat both. My username is .mcolvin. I am open to other chat apps too 🙂

I am in central standard time so may we can shoot for your evening sometime? 3 or 4 ish.

bittnert commented 11 months ago

Hey @MatthewColvin I added you in discord (request is now pending) and would be online today when ever you have time.

MatthewColvin commented 11 months ago

Hey @bittnert I don't seem to have a request what is your username. To be honest I don't know discord very well lol

bittnert commented 11 months ago

Hey @MatthewColvin, my username is bittnert.

CoretechR commented 11 months ago

@bittnert I can confirm that the WIFI dialog works when I limit no_networks. The 19 networks that I normally get, lead to the software freezing. Another issue is that when waking up from sleep, the esp32 often crashes a few times before starting (the output is Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.)

bittnert commented 11 months ago

@CoretechR @Dark1886 I now investigated the problem with the WIFI dialog and too many networks a bit and realized that the problem is in the LVGL library. The problem is, that after creating 46 lvgl object in the add_wifi_networks function, the core panics. Per wifi network I currently crate 3 object (a container, a label and an image).

Why exactly this happens I don't know. My guess is, that the lvgl memory management gets into troubles. One possible solution might be, that we split the networks into several pages where we only show a subset of networks at a time but then we shift the issue of memory management on our side as we would have to allocate and deallocate the memory to remember what networks were found.

CoretechR commented 11 months ago

@bittnert Maybe it's an option to just limit the networks to a smaller number. There might not be enough RAM left for a large number of additional LVGL objects.

bittnert commented 11 months ago

@CoretechR @Dark1886 I now updated the code for the wifi selection page handling.

The firmware now only shows 3 found networks at a time and you can switch between them using a "next" and "previous" button. Please see if it is working on your side now.

I also changed the backlight handling a bit (it should be inverted now).

MatthewColvin commented 11 months ago

Hey @bittnert, I know we talked about your classes being the inspiration for the new hardware module interfaces. Do you think I could use this PR to add those to the abstraction branch or do you have something in the works for that?

I also have not looked at your wifi menu code at all so should I try to port that over to abstraction too? I think we really need to look at busting up the OmoteUI class like you suggested.

CoretechR commented 10 months ago

@bittnert The backlight works now, thanks! On my board, the ESP32 still crashes during initialisation. It's either assert failed: ledc_clk_cfg_to_global_clk ledc.c:443 (false) when no WiFi network is selected or Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. after connecting to WiFi. Do you have an idea what could be causing this?

bittnert commented 10 months ago

@CoretechR I currently do not know exactly why it is crashing during initialization. Does it then start normally after it crashed or does it not come up at all? The first case I don't fully understand why the ledc module seems to crash. Maybe I forgot some initialization code needed before hand? The Exception when the WiFi network is selected could be a memory problem where I have some dangling pointer or similar which triggers this. I would need to search for it.

CoretechR commented 10 months ago

@bittnert It's really strange. The ESP32 crashes and endlessly reboots. With the ledc error, it sometimes manages to boot after a minute or two. So I can't completely rule out a hardware related issue. But with the same hardware my code runs fine. I tried to compare the initializations but couldn't find any differences.

CoretechR commented 10 months ago

@bittnert I have narrowed it down to the WIFI initializing and connecting to a network while the display setup runs. Maybe it's running out of RAM? When I move the wifihandler.begin(); after the display.setup() and display.setup_ui();, I get no more crashes. Also when I am using your PWM initialization, the backlight flashes white when turning on:

ledcSetup(LCD_BACKLIGHT_LEDC_CHANNEL, LCD_BACKLIGHT_LEDC_FREQUENCY, LCD_BACKLIGHT_LEDC_BIT_RESOLUTION);
  ledcAttachPin(this->backlight_pin, LCD_BACKLIGHT_LEDC_CHANNEL);
  ledcWrite(LCD_BACKLIGHT_LEDC_CHANNEL, 0);

After setting your #if to 0, the backlight works as expected.

One last issue I have is the settings page. The whole page seems to be nested in a box object with a gray background. Is that by design?

bittnert commented 10 months ago

@CoretechR Thanks for analyzing this problem. Its very interesting that the order of initialization makes such a different. Maybe we need to think about adding some PSRAM or so to handle the UI data as it seems to get quite big.

About the backlight flashing, my suspicion is, that the problem is a wrong initialization as you need the signal inverted. Maybe this code would work:

ledcSetup(LCD_BACKLIGHT_LEDC_CHANNEL, LCD_BACKLIGHT_LEDC_FREQUENCY, LCD_BACKLIGHT_LEDC_BIT_RESOLUTION);
  ledcWrite(LCD_BACKLIGHT_LEDC_CHANNEL, 255);
ledcAttachPin(this->backlight_pin, LCD_BACKLIGHT_LEDC_CHANNEL);
CoretechR commented 10 months ago

@bittnert PSRAM would surely help, especially when we are trying to add more features. I'd love to create a new version of the board with PSRAM and some other improvements. But keeping this compatible would be a nightmare. And everyone who has already ordered their board would miss out on new features.

The reason I did the PWM initialization without the ledcSetup functions was because of the inverted signal. I could not find a way to fix this without the backlight flashing while the remote boots up.

Michil783 commented 8 months ago

Hi @CoretechR, unfortunately I don't have a PCB yet. I will need to order and assemble one. I used a breadboard to test the software.

About the screen turning black, I realized a difference in the initialization of the LEDC module between the original and the refactored code. I aligned this now and created another commit. Maybe you can check if this fixes the issue.

About the freeze, could you check the uart output? I currently have the suspicion that the firmware might go to sleep but does not turn of the LCD. When it goes to sleep it does not turn off the screen on my setup but I thought this is a hardware issue, not a software one.

We will probably have to change/update the handling of the sleep timer to not go into sleep as long as the we are searching for networks.

BR

Hello bittnert, I have nearly fully populated PCBs. Only the switches are not soldered and the IR LED. I‘m located in Germany. If you are still interested in one, pleSe send me a PM. Kind regards Michael

KlausMu commented 6 months ago

I have nearly fully populated PCBs. Only the switches are not soldered and the IR LED. I‘m located in Germany. If you are still interested in one, pleSe send me a PM.

Hi @Michil783 , do you still have a nearly fully populated PCB (only IR and switches missing)? I'm in Germany and interested in it. How much would it be? How can I send a PM?

Michil783 commented 6 months ago

I have nearly fully populated PCBs. Only the switches are not soldered and the IR LED. I‘m located in Germany. If you are still interested in one, pleSe send me a PM.

Hi @Michil783 , do you still have a nearly fully populated PCB (only IR and switches missing)? I'm in Germany and interested in it. How much would it be? How can I send a PM?

Hello, you could send me a PM via my github account Michil783

bittnert commented 6 months ago

Hi @CoretechR, unfortunately I don't have a PCB yet. I will need to order and assemble one. I used a breadboard to test the software. About the screen turning black, I realized a difference in the initialization of the LEDC module between the original and the refactored code. I aligned this now and created another commit. Maybe you can check if this fixes the issue. About the freeze, could you check the uart output? I currently have the suspicion that the firmware might go to sleep but does not turn of the LCD. When it goes to sleep it does not turn off the screen on my setup but I thought this is a hardware issue, not a software one. We will probably have to change/update the handling of the sleep timer to not go into sleep as long as the we are searching for networks. BR

Hello bittnert, I have nearly fully populated PCBs. Only the switches are not soldered and the IR LED. I‘m located in Germany. If you are still interested in one, pleSe send me a PM. Kind regards Michael

Hi, sorry for my late reply. I would be very interested. Unfortunately, I did not find a way to send you a PM in github. Maybe it is user error but I did not see a "send PM" or similar button.

Are you on the omote discord server? If so we could communicate details there.

BR Thomas

Michil783 commented 6 months ago

Hi @CoretechR, unfortunately I don't have a PCB yet. I will need to order and assemble one. I used a breadboard to test the software. About the screen turning black, I realized a difference in the initialization of the LEDC module between the original and the refactored code. I aligned this now and created another commit. Maybe you can check if this fixes the issue. About the freeze, could you check the uart output? I currently have the suspicion that the firmware might go to sleep but does not turn of the LCD. When it goes to sleep it does not turn off the screen on my setup but I thought this is a hardware issue, not a software one. We will probably have to change/update the handling of the sleep timer to not go into sleep as long as the we are searching for networks. BR

Hello bittnert, I have nearly fully populated PCBs. Only the switches are not soldered and the IR LED. I‘m located in Germany. If you are still interested in one, pleSe send me a PM. Kind regards Michael

Hi, sorry for my late reply. I would be very interested. Unfortunately, I did not find a way to send you a PM in github. Maybe it is user error but I did not see a "send PM" or similar button.

Are you on the omote discord server? If so we could communicate details there.

BR Thomas

Hi Thomas, I‘m also on hackaday.io with the same account name michil783. BR Michael

Michil783 commented 6 months ago

I have nearly fully populated PCBs. Only the switches are not soldered and the IR LED. I‘m located in Germany. If you are still interested in one, pleSe send me a PM.

Hi @Michil783 , do you still have a nearly fully populated PCB (only IR and switches missing)? I'm in Germany and interested in it. How much would it be? How can I send a PM?

Hi, it seems that PMs are not possible in github, but I‘m registered on hackady.io with the same account name. BR Michael

KlausMu commented 1 month ago

I close this PR, since it is very old and not longer compatible with the latest software.