-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add wifi.suspend() and node.sleep() #1231
Conversation
👍 for merge as soon as we get the next master drop out of the way imo. |
Would it be useful to add functions to allow this API to be used in source rather than just in Lua? |
As requested by mjmcginty I will be adding the function |
@dnc40085 once you do pls resolve the merge conflicts, too. |
@marcelstoer will do. Any idea when dev will be upgraded to SDK 1.5.4? there is a new function |
No idea, there's no issue for that and I'm not aware of anyone working on that secretly. You're probably aware that NodeMCU is moving to RTOS-SDK but I'm not involved because I lack the required know-how. |
Oh I see, never mind then, I'll save that feature for a future PR. |
@jmattsson I've almost got this PR ready but I'm having a problem getting the sleep function to play nicely with the UART. In the course of development of this feature, I have been using the WiFi event monitor to print event messages and occasionally it goes to sleep while the uart is still transmitting, leaving the TX pin low and the TX led on, then when I wake it up it finishes emptying the buffer. I was thinking maybe I could add a TX active flag to Any thoughts? |
@dnc40085 It seems reasonable to me to leave it to the user, won't we need to stop timers and such anyway? Not only that, anything capable of drawing current through or controlled by an i/o will have to be managed, otherwise the point of sleeping is negated. The obvious use case to me is to wait until any external activity has stopped before sleeping... in fact I can't think of a desirable or even acceptable use case where an app would want to sleep while anything was going on. (That doesn't mean there isn't one, just that it defies my imagination.) In any case, I'm down with having to curtail serial output prior to making this call, just part of necessary prep. And the worst consequence for failing to do so does not seem dire. My 2 cents... well that might be a nickel's worth -- keep the change. :-) And thanks for your efforts. |
The wifi suspend is impacting the UART?! That sounds like the WiFi suspend is shutting down the auxillary/peripheral clock altogether then >.< I imagine that would impact some other things as well then (SPI, etc) Like @mjmcginty says, this might be something best handled with lots of user documentation. Maybe I should poke @devsaurus for his opinion here as well? |
As far as I know, the timers pick up where they left off when ESP comes out of light sleep.
That is what I'm trying to do, but I can't find any functions in the uart driver that tell me whether or not the uart is busy. |
It's impossible to know what async external input sources are about to send, the best that can be done is to infer an idle state from a period of inactivity. I suspect you ran into this because status change events caused while setting up to sleep, generated uart output as you were calling it. With all due respect and appreciation, you might be over-thinking it just a bit. IMHO, in this scenario an amount of time elapsed with no activity is a definitive measure of 'not busy', and activity is in the eye of application code. |
Light sleep not modem sleep. wifi sleep does not affect uart, it just disables wifi. |
My experiences in pickup bars tell me that displays of urgency and desperation have the opposite effect. However, the feature has not been present in previous versions, so zero worry of impact to existing code, and I would be happy to have it even if it dumped the uart buffer and filled it with garbage on wake up! :-) |
@dnc40085 any progress? |
@mjmcginty My apologies for the delay, I had to go out of town and haven't had access to an ESP for testing. |
@dnc40085 awesome, thank you! I came up with a little thing that lets you test an ESP-12 without soldering it at all, just got the boards from being printed yesterday. (I think I have all the components on hand, might have to order some headers from Digikey.) How can I get one to you? |
I created a new milestone for the next master drop. Let me know whether this one should be added to it or not. |
295f905
to
808d3ba
Compare
I'd say go ahead, but I keep randomly getting an error that simply says my init.lua can be found here Normal: NodeMCU 1.5.4 build unspecified powered by Lua 5.1.4 on SDK 1.5.4(baaeaebb)
>
STA - CONNECTED
SSID: myssid
BSSID: xx:xx:xx:xx:xx:xx
Channel: 11
STA - GOT IP
IP: 10.0.0.5
MASK: 255.255.255.0
GW: 10.0.0.1
node.sleep({wake_gpio=4})
>
STA - DISCONNECTED
SSID: myssid
BSSID: 5���```3:xx:xx:xx:xx << see NOTE at bottom of post
reason: 8
STA - CONNECTED
SSID: myssid
BSSID: xx:xx:xx:xx:xx:xx
Channel: 11
STA - GOT IP
IP: 10.0.0.5
MASK: 255.255.255.0
GW: 10.0.0.1 abnormal: NodeMCU 1.5.4 build unspecified powered by Lua 5.1.4 on SDK 1.5.4(baaeaebb)
>
STA - CONNECTED
SSID: myssid
BSSID: xx:xx:xx:xx:xx:xx
Channel: 11
STA - GOT IP
IP: 10.0.0.5
MASK: 255.255.255.0
GW: 10.0.0.1
node.sleep({wake_gpio=4})
fpm 737
ets Jan 8 2013,rst cause:2, boot mode:(3,6)
load 0x40100000, len 25576, room 16
tail 8
chksum 0x84
load 0x3ffe8000, len 2204, room 0
tail 12
chksum 0x75
ho 0 tail 12 room 4
load 0x3ffe889c, len 8, room 12
tail 8
chksum 0x91
csum 0x91
��r�l�l���l`���r�l�l��l`���r�l��
NodeMCU 1.5.4 build unspecified powered by Lua 5.1.4 on SDK 1.5.4(baaeaebb)
>
STA - CONNECTED
SSID: myssid
BSSID: xx:xx:xx:xx:xx:xx
Channel: 11
STA - GOT IP
IP: 10.0.0.5
MASK: 255.255.255.0
GW: 10.0.0.1 I'm not sure what is causing this crash~~,but I think it might be caused by the uart, because I never get this problem when the event monitor is not running.~~ NOTE: This is the uart glitch i was referring to in my previous post. in this instance the ESP8266 enters LIGHT_SLEEP after the 5 is printed, the remaining chars are printed upon cpu resume. |
808d3ba
to
99af70c
Compare
Please disregard the parts of my previous post concerning the error As for the above mentioned UART glitch, I did some testing with an ammeter and the glitch is causing an increase in current draw when the esp enters light sleep, causing the sleep current to be different each time the ESP8266 enters light sleep, making it difficult to estimate how long it would last on battery. I was thinking maybe a function or flag could be added to allow suspension of the UART output before executing Any suggestions would be much appreciated. |
99af70c
to
57fd447
Compare
This was almost done but has been sitting idle for too long. Is there consensus whether it should be merged (once rebased of course) even with the UART glitch? |
I thought I was almost done with it, but then I ran into a problem with some timers preventing timed light sleep. To remedy the timer problem, I've implemented the ability to suspend timers. I just got the timer suspend/resume functionality working properly a few days ago, and I'm currently cleaning up my mess to get it ready for merging. As for the timer suspend add-on, since it is required by My apologies for taking so long with this PR, it's been a real head scratcher. |
@marcelstoer thank you for letting me know |
0d0d3ce
to
210ae98
Compare
I believe I've fixed the UART glitch, I just needed to check the TX buffer to ensure it was empty before issuing the sleep command. This PR now passes all of my personal tests. |
40b571a
to
eb21581
Compare
Added timer suspend functionality Added functions: * wifi.suspend * wifi.resume * node.sleep * tmr.suspend * tmr.suspend_all * tmr.resume * tmr.resume_all
eb21581
to
9612fd9
Compare
@marcelstoer I found some errors in the documentation that need to be fixed before merge to the master branch, I will be submitting a PR shortly. |
@dnc40085, It might be worth a comment in the documentation for One other point which "advanced" programmers understand but will confuse most beginners: your requesting routine has to return / exit after executing the suspend request, because the suspend isn't actioned by the SDK until you've returned control to it. It will then invoke the suspend callback once the suspend activities are completed. Ditto resume. |
@TerryE I did mention the 500 ms guideline in example:
I'm not sure of the best way to document this... wifi.suspend()Suspend Wifi to reduce current consumption. Please note:
syntax... |
@dnc40085, I am working through some issues on my Lua 5.3 port and this has bumped my against your mods here. My concern isn't with the functionality, but with the implementation strategy. We are building and using a Lua RTS which has its own embedded memory management systems and sets of structures and functions for array / list management. Yet, I reviewing this implementation in depth, I realise that:
This all amounts to a future maintenance burden for quite a narrow albeit very useful functionality. I just feel that the whole implementation would have been simpler and cleaner if you'd stuck to the Lua way for implementing new functionality for a Lua module. |
@TerryE Funny you mention this, lately I've been thinking of updating the implementation to use the Lua memory management system and since implementation I've wondered if there was a simpler way I could implement the dynamic array. I've been looking at the functions in I'll get to work on a remedy for this issue and try and get it done in a timely manner. |
@dnc40085, a slight aside: before I got involved with this Lua project, I was interested in and contributed to some of the core components of the PHP system, and it is interesting to compare and contrast the two. The reason that we can use Lua and not PHP as an embedded RTS on an IoT device is that the Lua architecture is tight and normalised. In essence there is only one way of doing anything in Lua and the authors use that way wherever they need it. By resisting the urge to implement a special approach to optimise a specific case, the overall consequence is that the whole remains lean and mean. So to your Q about how to implement dynamic arrays, my answer is simple: use the Lua way. Don't reinvent your own. So in this case use its API for array handling. But also why not follow the general Lua approach for handling exceptional error conditions which is to use the lua error system to throw the error where it occurs and avoid rolling this back up the call stack. If errors are thrown then code can be written assuming that any called function has done the intended purpose so the implementation is simpler, faster and easier to understand and maintain. And another principle, that I would also suggest for changes to an embedded RTS for an IoT: stick to the minimal implementation of any aspect of any new functional requirement unless there are compelling advantages for generalising or extending the scope. If I go back to the i original scope of this patch it was to implement a light-sleep and wake function, so that a class of Lua implementations (ones which spent a lot of time dormant and only occasionally needed to do processing) could save power, but to do this using a simple API and without crashing the application. This last point was a problem, and the specific issue was that the SDK, services and Lua applications use the I personally think that the introduction of 3 new subdirectories (pm, swTimer and misc) with modules in them together with the extra API functions exposed in On another topic relating to this PR, the Expressif SDK internals are not well documented and the source isn't available , but it has some fundamental characteristics:
I am note sure how the Looking at the To be honest, I get lost in My Q / suggestion is that if you treated your current implementation as a prototype which included your process of discovering how this all worked, but we then wanted to strip this back to the essential functions of "checkpoint all timers" and "restore all timers offset by time that the system clock was stopped", then how would you do this? Can we just detach the ETStimer linked list from I suggest that if you removed all one the non-core stuff, then we would up with a patch less than a third of the current one. //Terry |
OK, I've discovered the overrides of Why not just walk the
Either way you can now scan the |
* Exposed forced sleep API and more Added timer suspend functionality * wifi.suspend * wifi.resume * node.sleep * tmr.suspend * tmr.suspend_all * tmr.resume * tmr.resume_all * Implement timer suspend functionality * Fix for uart TX glitch * Made some modifications to the error reporting
This PR exposes the WiFi forced sleep API, which allows the WiFi radio to be temporarily disabled to reduce power consumption or to allow the application developer to run functions that would normally cause the WiFi stack to crash.
Here is the documentation for the new functions:
wifi.suspend()
andwifi.resume()
I was going to mention this in the issue (Please document wifi.sleep function in official API docs(#1115)) but it seems to have disappeared.