Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Sleep mode for Arduino #13321

Closed
catcombo opened this issue Feb 9, 2020 · 5 comments
Closed

Sleep mode for Arduino #13321

catcombo opened this issue Feb 9, 2020 · 5 comments
Assignees
Labels
Area: timers Area: timer subsystems Platform: AVR Platform: This PR/issue effects AVR-based platforms Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Type: question The issue poses a question regarding usage of RIOT

Comments

@catcombo
Copy link
Contributor

catcombo commented Feb 9, 2020

Description

xtimer_sleep doesn't wake up an Arduino from sleep mode. I think I do something wrong but can't find out what excactly. I'm trying to migrate from Arduino framework to RIOT OS so don't be too hard on me :)

Steps to reproduce the issue

#include <xtimer.h>
#include <periph/pm.h>
#include <avr/sleep.h>

void pm_set_lowest(void)
{
    // Can be any SLEEP_MODE except SLEEP_MODE_IDLE
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
    sleep_mode();
}

int main(void) {
    while (true) {
        puts("Hi");
        xtimer_sleep(10);
    }

    return 0;
}

Expected results

Wake up every 10 seconds.

Actual results

Hangs after first call to sleep_mode().

Versions

Hardware: Arduino Nano (ATmega328p).

@roberthartung
Copy link
Member

Welcome to RIOT @catcombo!

Using xtimer here is a bit tricky, as it is not 100% compatible / designed for being used in sleep modes.

ATmega328p uses the 16bit timer (Timer 1), as it is required for the resolution of xtimer. It uses the clk_I/O clock domain by default, unless we have an external clock source here? I am not sure of that though. So in case you use the internal clock from clk_I/O, you can only enter idle mode at this point, unless you either use a different timer (e.g. timer 2). In any case, you need a wake up source, e.g. an interrupt wo wake-up from sleep.

Checkout #8207 for my PR on sleep modes for the atmega CPUs.

At this point I am afraid to say, that you cannot use xtimer with sleep as it is right now.

@catcombo
Copy link
Contributor Author

@roberthartung Thank you very much for your explanations!

I thought it will be easier and more common way (thanks to RIOT) to use a sleep mode :\ I planned to create a thread and put it into a sleep every 5 minutes. If I understand correctly if I want to use deep sleep modes I need to use interrupts (or Watchdog timer? I saw some people do so in Arduino) to wake up after a certain amount of time. Is there any convenient way to use interrupts in RIOT rather than direct use of AVR libraries?

I also thought that in SLEEP_MODE_IDLE MCU will sleep until the end of xtimer interval but it seems it wake up multiple times a second. If I understand correctly there are other interrupts in the system that cause MCU to wake up and do some job. Is there a way to get the list of active interrupts to understand their purpose?

@roberthartung
Copy link
Member

@catcombo You're welcome. Using sleep modes in RIOT is in theory very easy (once the PR is merged that introduces 'native' sleep modes using pm_layered). However, using sleep modes in a fully stacked operating system is a big challenge. Therefore we created the pm_layered module, that automatically uses the deepest sleep mode available, which depends on the peripherals you use. By default you will only able to enter IDLE mode, as the uart is always enabled, as well as xtimer.
To be able to sleep, you need to disable uart and xtimer for that and enable a wake-up source. In my PR, this is realised by using the RTT.
You should never use avr libraries directly in your application code, but rather use RIOT's drivers and interfaces for it.

RIOT features the irq interface. You can use it right away to enable interfaces. Additionally, you can use the GPIO module to enable external interrupts.
Timers can be used to wake you up, e.g. the RTT or RTC modules. In any case, they have to be configured/enabled, and would then wake up your CPU.

You are mixing avr code (set_sleep_mode) and RIOT code here. In theory this should be hidden from you! A list of interrupts is not available.

For clarification: You would like to do something and then wake up every five minutes for the same task, correctly?

@catcombo
Copy link
Contributor Author

Thanks for links to documentation and for explanation! It's all a bit hard for me now but I will try to figure out and understand how everything works to not bother you too much with a newbie questions :)

For clarification: You would like to do something and then wake up every five minutes for the same task, correctly?

Yes, simple periodic task: get temperature from DS18 sensor, display it on HD44780 display, then sleep for 5 minutes to wake up and repeat the cycle.

@miri64 miri64 added Area: timers Area: timer subsystems Platform: AVR Platform: This PR/issue effects AVR-based platforms Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Type: question The issue poses a question regarding usage of RIOT labels Jul 6, 2020
@MrKevinWeiss MrKevinWeiss added this to the Release 2021.07 milestone Jun 21, 2021
@MrKevinWeiss MrKevinWeiss removed this from the Release 2021.07 milestone Jul 15, 2021
@maribu
Copy link
Member

maribu commented May 19, 2023

We now have ztimer that is compatible with low power modes. However, the AVR port has no periph_pm implementation yet. So there is no way actually use that with AVR boards.

(But given that modern 32 bit controllers are faster, cheaper, have more RAM/flash and require less power all at the same time, one might just go for one of those MCUs instead.

Anyways, I think the issue can be closed. A tracking issue for which platforms are still missing periph_pm would however be quite useful.

@maribu maribu closed this as completed May 19, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Area: timers Area: timer subsystems Platform: AVR Platform: This PR/issue effects AVR-based platforms Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Type: question The issue poses a question regarding usage of RIOT
Projects
None yet
Development

No branches or pull requests

5 participants