Library cano64/ArduinoSleep

Hi, I'm used to use the sdelay(); in my projects. I haven'T been working with ArduinoIDE for nearly a year right now, but as I wanted to use the lib, I get this issue:

https://github.com/cano64/ArduinoSleep/issues/6

Any ideas on this?

Any ideas on this?

You have some code you didn't post that uses a library that you did not provide a link to. And, you want us to tell you what the problem and solution are? Not a chance.

Library and problem are on the github url.
But finally (after some days) I fixed the issue myself. Double-included the library :facepalm:

But now as the sdelay.h works, again, I got another issue.
When I use the lib my AtMega2560 restarts as soon as it wakes up from sdelay(); .
First I thought it would be my circuit, but as I disabled everything else I’m sure the library faults a restart.

As mentioned in the pullrequest, I removed the .cpp file from the library’s folder.

#include <Wire.h> 
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROMex.h>
#include <Time.h>
/*#include <DS1307RTC.h>*/
#include <SPI.h>
#include <SD.h>
#include <sdelay.h>

LiquidCrystal_I2C lcd(0x27,20,4);

void setup()
{
    lcd.begin();
    lcd.clear();
    lcd.display();
    lcd.clear();
    lcd.backlight();
}

void loop()
{
    for (int i=0; i<5000000; i++)
    {
        lcd.setCursor(1,1);
        lcd.print(i);
        sdelay(500);
    }
}

This forces permanent reset and I’m only getting a zero on my display - when I use delay(); everything works fine.

When I use the lib my AtMega2560 restarts as soon as it wakes up from sdelay(); .

Did you read the header file?

That is a crappy library. The cpp file is useless. All the code is, incorrectly, implemented in the header file.

That aside, the header file contains:

void sleepWithWDT(uint8_t wdt_period) {
  wdt_enable(wdt_period);
  wdt_reset();
  #if defined(__AVR_ATtiny85__) 
    WDTCR |= _BV(WDIE); //wake up interrupt when time is up
  #else //ATTiny84, ATMega328
    WDTCSR |= _BV(WDIE); //wake up interrupt when time is up
  #endif 
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_mode();
  wdt_disable();
  #if defined(__AVR_ATtiny85__) 
    WDTCR &= ~_BV(WDIE);
  #else //ATTiny84, ATMega328
    WDTCSR &= ~_BV(WDIE);
  #endif 
}

Pay particular attention to the boards that are supported (and, by extension, those that are not).

@cysign, have you considered using the narcoleptic library?

Sounds interesting. I'll give it a shot!

Well...and I figured out it's not working properly out of the box:

arduino-1.8.1\libraries\narcoleptic-master\Narcoleptic.cpp:256:3: error: 'PRR' was not declared in this scope

PRR |= _BV(PRTWI);

As I've been using the sdelay.h a year ago without forcing my µC to reboot, I wonder what has changed. Did the library and big changes or the compiler?

//Edit: Well, I've read there should be incompatibilities with the WDT on some bootloader. I use the bootloader (stk500boot_v2_mega2560) that comes with the ArduinoIDE 1.8.0.

cysign: //Edit: Well, I've read there should be incompatibilities with the WDT on some bootloader. I use the bootloader (stk500boot_v2_mega2560) that comes with the ArduinoIDE 1.8.0.

I believe the bug you're referring to is the endless reset loop after WDT reset. That issue doesn't occur with the 2560 bootloader and I don't think it would apply to the ArduinoSleep library anyway because it shouldn't do a watchdog reset. It's the bootloader on Nano, Pro Mini, and similar boards that has the endless reset loop bug.

Were you using the current version of the library, after the author made some changes a few days ago?

Yes, library is the newest one. Changes are made after I opened a case for not compiling properly on ArduinoIDE 1.8.1 ;)

Confusing. What else to check? Could anyone confirm this bug on Arduino Mega2560? Onw year ago everything worked fine...

Try this: https://github.com/cano64/ArduinoSleep/pull/9

Well, finally I found a working library:

I had to delete two lines (see issues on the github project - lines 440 and 475 for uart3) on the .cpp file to make it work. But so far it looks like it’s working :wink:

@pert: Regarding your github issue: How can I test this?
How do I create an empty ISR for sdelay?

Tell me what to do and I’ll test it on the AtMega2560.

If you want you can just download and install the branch of my fork for that PR:
https://github.com/per1234/ArduinoSleep/archive/uncomment-ISR.zip
Or you can just open your ArduinoSleep/src/sdelay.cpp file in a text editor, make the changes shown in the diff of my commit:
https://github.com/cano64/ArduinoSleep/pull/9/commits/b5be767bd6e43b1d92acedf4fb83758bc9ba0ceb
save the file, then upload your sketch to the Arduino, which will now use the modified library.

Here’s the test sketch I used:

#include "sdelay.h"

#define LED_PIN 13
#define BLINK_DELAY 1000

void setup() {
  pinMode(LED_PIN, OUTPUT);
  for (byte x = 0; x < 20; ++x) {
    digitalWrite(LED_PIN, HIGH);
    delay(100);
    digitalWrite(LED_PIN, LOW);
    delay(100);
  }
}


void loop() {
  digitalWrite(LED_PIN, HIGH);
  sdelay(BLINK_DELAY);
  digitalWrite(LED_PIN, LOW);
  sdelay(BLINK_DELAY);
}

This blinks @ 5Hz 20 times on startup and then blinks at 0.5 Hz after that so you can clearly see if any resets occur. I tested on Uno and Mega and both have the reset issue with the current stock library version and the issue is fixed with the ISR uncommented.

All right. Your fix works well on Arduino Mega2560. Thanks!

Wish I would have your skill ;)

Glad to hear! You might still want to consider using the rocketscream library or Narcoleptic. I've never used any of these beyond a couple quick tests of ArduinoSleep for my PRs but I have heard good things about the rocketscream one. I've always just written my own sleep code because usually it's only a few lines but it can be a bit confusing trying to get down to the absolute minimum power usage so it's good there are some libraries available to make it easier.