Open-Smartwatch / open-smartwatch-os

The Open-Smartwatch Operating System.
https://open-smartwatch.github.io
GNU General Public License v3.0
984 stars 161 forks source link

Allow using reduced WiFi power to improve stability #264

Closed FranseFrikandel closed 1 year ago

FranseFrikandel commented 2 years ago

As is well known, the current OSW hardware has insufficient power, which causes crashes during WiFi usage.

In my personal testing, it appeared reducing the WiFi transmit power made my watch crash a bit less abruptly, however it wasen't enough to get WiFi working. However it may be enough for some people to either get it to work in the first place, or to get WiFi operating more reliably.

Setting the power for ESP32 to the lowest can be done using:

WiFi.setTxPower(WIFI_POWER_MINUS_1dBm);

In my testing, I added this line every time before WiFi mode was set in the updateWifiConfig() function that can be found in src/OswServiceTaskWiFi.cpp. There's probably a more elegant way to handle this, presumably this only needs to be set once on startup.

This doesn't appear to be documented in Espressif documentation. It seems this is the best source I have found on this: https://github.com/G6EJD/ESP32-8266-Adjust-WiFi-RF-Power-Output

The repository also has the methods of reducing transmit power for the ESP8266.

The example .ino file suggests reducing transmit power saves around 30mA.

Obviously, reducing WiFi transmission power will reduce the WiFi range. The simple solution is to allow users to change thier transmit power via config.h, so they can tune for thier specific watch's stability.

uvwxy commented 2 years ago

IIRC, lowering the cpu clock to 80MHz also improves things. Could you also give that a try? See OswAppPowerDemo

uvwxy commented 2 years ago

For some it might be even less work to upgrade the hardware to fix it this:

xc6209 (3.3V) is my recommendation for U10

https://open-smartwatch.github.io/watches/light-edition/

RuffaloLavoisier commented 2 years ago

Could you also give that a try? See OswAppPowerDemo

https://github.com/Open-Smartwatch/open-smartwatch-os/blob/develop/src/apps/_experiments/power_demo.cpp

FranseFrikandel commented 2 years ago

IIRC, lowering the cpu clock to 80MHz also improves things. Could you also give that a try? See OswAppPowerDemo

Appears to be slightly better, dropping it way down to like 20 MHz, it no longer resets the watch. Still appears to lock up however, but presumably the voltage drop isn't quite as big. Should be possible to confirm with an oscilliscope but I don't have one unfortunatly.

I thought XC6209 is what installed as standard and was the component causing the issue?

uvwxy commented 2 years ago

My bad, I got the parts mixed up: replacing it with a ME6211 will do the trick.

XC6209 is indeed the part that is limited to 300mA

simonmicro commented 2 years ago

Hmmm, how do we approach this? I think just adding a define for the currently affected platforms by default would be a good idea (inside platformio.ini). This way all currently affected users would receive a fix and all users with a patched PCB can remove the flag as needed...

I would place the "energy save" mode into the wifi task, possibly with its own little warning icon during use - similar to the low memory mode I've introduced recently.

I would also combine all measures we can get together, like WiFi transmit power or core clocks. Would this be fine?

RuffaloLavoisier commented 2 years ago

Hmmm, how do we approach this? I think just adding a define for the currently affected platforms by default would be a good idea (inside platformio.ini). This way all currently affected users would receive a fix and all users with a patched PCB can remove the flag as needed...

There is also a way to exclude unused developed feature. (Like ANIMATION, RAW SCREEN SERVER) - not include PIO.ini

uvwxy commented 2 years ago

@simonmicro sounds good to me.

For historical purposes:

Screenshot 2022-07-12 at 14 23 32 Screenshot 2022-07-12 at 14 24 26

Another idea for a hardware bodge that might help: maybe joining the two LDO's together might help (although not recommended).

My personal use case never included wifi much on the light editions. And in the cases when I did use the wifi to sync via NTP it worked, maybe because I'm sitting so close to the AP (2m).

FranseFrikandel commented 2 years ago

The WiFi working or not is probably just down to plain luck. Manufacturing variations in both the ESP's and the LDO's on the watch probably just mean some pairs work well and others don't. I am kind of doubtful joining LDO's is going to work, I believe you'd normally add a small resistance to the output of the LDO before the point you join them to prevent small output voltage differences causing issues, like one LDO taking up all the load.

I'm unfortunatly not experienced at all in SMD soldering, so if I am going to try swapping in another LDO I'll probably order extra components and a PCB to do it on rather than trying it on the fully assembled PCB. The couple times I have tried removing components from PCBs weren't great.

uvwxy commented 2 years ago

Yeah, scrap the parallel LDO idea 🧠💨

Lorenzosciacca commented 2 years ago

I don't know if i can help, but this is my personal experience related to Wi-Fi problems. I'm currently using the version 3.2 from lilygo and the code of the commit [bc08af4]. Everything seems to be ok while connecting to the Wi-Fi, both in AP e client mode. Initially i was able to enter the index page and the update page, but not the config page. While i was trying to access the config page the watch was crashing after calling getConfigJSON(), with the serial output i figured out that it wasn't able to perform: "config["entries"][i]["value"] = key->toString();" inside getConfigJSON(). Anyway, i tried many solutions as: lower clock rate or less tx power, both of them failed.

The output was always similar to this: " Memory monitor [etc.. ] Guru Meditation Error: Core 0 panic'ed (Unhandled debug exception) ... "

Then i found this: https://github.com/espressif/arduino-esp32/issues/3481, the problem was similar and someone suggested to set a larger stack size. This worked for me, the workerStackSize i use now is 5KB. (in OswServiceManager.h -> -- const unsigned workerStackSize = 1024 + ((1024 + 1024 + 1024) _SERVICE_WIFI); ++ const unsigned workerStackSize = 1024 + ((1024 + 2048 + 1024) _SERVICE_WIFI); ) Now, i'm able to use the config page without problems.

I also found out that someone changed this value to a larger one, in another branch probably: https://github.com/Open-Smartwatch/open-smartwatch-os/commit/fd5bb4fcaa9359780f7e77dbee5817e3116d84b0 The value used here is much larger than the one i used. I don't know exactly how much stack is needed to run: wifi service, webserver, updater and probably other things i don't know. Anyway, i hope this will help. ps: i have to specify that sometimes continues to crash, but not so frequently, and not while loading the config page.