Skip to content
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

Serial not working after wakeup #7

Open
tatulea opened this issue Sep 24, 2018 · 30 comments
Open

Serial not working after wakeup #7

tatulea opened this issue Sep 24, 2018 · 30 comments
Assignees

Comments

@tatulea
Copy link

@tatulea tatulea commented Sep 24, 2018

Hi,

I am using a button to put Arduino in sleep mode and wake it up, but the Serial is not working anymore after it is waking up. What should I do?

#include "ArduinoLowPower.h"

volatile bool just_wakeup = true;

// Pin used to trigger a wakeup
const int pin = 0;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(pin, INPUT_PULLUP);
}

void loop() {
  if (just_wakeup) {
    just_wakeup = false;
    delay(3000);
    Serial.begin(115200);
  }
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
  Serial.println("test");

  if (digitalRead(pin) == LOW) {
    Serial.end();
    delay(500);
    LowPower.attachInterruptWakeup(pin, wakeup_handler, FALLING );
    LowPower.deepSleep();
  }
}

void wakeup_handler() {
  just_wakeup = true;
  detachInterrupt(pin);
}
@facchinm

This comment has been minimized.

Copy link
Contributor

@facchinm facchinm commented Sep 24, 2018

Hi @tatulea, wakeup/standby with the USB connected is super tricky since it depends on the operating system/USB controller the board is connected to.
Would you mind sharing your PC or Mac configuration (both software and hardware) so I can try reproducing it? Thanks

@tatulea

This comment has been minimized.

Copy link
Author

@tatulea tatulea commented Sep 24, 2018

Hi,

I am using Windows 10 and Arduino IDE.
The PC is a HP EliteDesk 800 with intel I5-6500.

@grezco

This comment has been minimized.

Copy link

@grezco grezco commented Sep 29, 2018

Hello,

I have the same problem with MKR WiFi1010 (and MKR1000) - Win10

@durasno

This comment has been minimized.

Copy link

@durasno durasno commented Sep 29, 2018

Hello,

I also have the same problem with the Arduino WiFi MKR 1010 and MacBook Pro running OS X Yosemite.

@facchinm facchinm self-assigned this Oct 1, 2018
@facchinm facchinm changed the title Serial not wotking after wakeup Serial not working after wakeup Oct 1, 2018
@facchinm

This comment has been minimized.

Copy link
Contributor

@facchinm facchinm commented Oct 1, 2018

@tatulea @grezco @durasno can you take a look at #8 ? Let me know if the proposed behaviour could work for you.

@grezco

This comment has been minimized.

Copy link

@grezco grezco commented Oct 1, 2018

Hi @facchinm,

For me, it's the same problem.
At the wake up, the com port is present but even after closed serial monitors and reopened after a successful resume, I don't have serial print event.

@facchinm

This comment has been minimized.

Copy link
Contributor

@facchinm facchinm commented Oct 1, 2018

@grezco which operating system/PC are you using?

@grezco

This comment has been minimized.

Copy link

@grezco grezco commented Oct 1, 2018

Windows 7 and Windows 10

@durasno

This comment has been minimized.

Copy link

@durasno durasno commented Oct 6, 2018

@tatulea @grezco @durasno can you take a look at #8 ? Let me know if the proposed behaviour could work for you.

Hi @facchinm,

The below script (based on the TimedWakeup example) seems to be working relatively well (after brief testing with Arduino WiFi MKR 1010, MacBook Pro + OS X Yosemite) with the changes from #8. The added delay is from a LowPowerLab/LowPower SAMD21 example sketch.


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  // Uncomment this function if you wish to attach function dummy when RTC wakes up the chip
  LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, dummy, CHANGE);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
  
  while(!SerialUSB);
  delay(1000); 
  SerialUSB.println("Just woke up!");
  
  // Triggers a 2000 ms sleep (the device will be woken up only by the registered wakeup sources and by internal RTC)
  // The power consumption of the chip will drop consistently
  LowPower.sleep(2000);
}

void dummy() {
  // This function will be called once on device wakeup
  // You can do some little operations here (like changing variables which will be used in the loop)
  // Remember to avoid calling delay() and long running functions since this functions executes in interrupt context
}

@grezco

This comment has been minimized.

Copy link

@grezco grezco commented Oct 6, 2018

Hi @durasno,

The same script testing with WiFi MKR 1010 and Windows10 with the changes from #8 Don't work for me.

@durasno

This comment has been minimized.

Copy link

@durasno durasno commented Oct 6, 2018

Hi @grezco,

If it helps I wait for the led to flash and then repeatedly try to open the serial monitor until text displays. Past that I unfortunately don't have much advice to offer.

@grezco

This comment has been minimized.

Copy link

@grezco grezco commented Oct 13, 2018

Hi @facchinm
With the script above, with arduino/ArduinoCore-samd#361 if I send a char by serial monitor, I freeze IDE (Wndows 10).

@polygamma

This comment has been minimized.

Copy link

@polygamma polygamma commented Oct 13, 2018

You may want to take a look at this: #9

@grezco

This comment has been minimized.

Copy link

@grezco grezco commented Oct 14, 2018

Hi @polygamma,
Nothing better with #9 for me.
After wake up, in all case, I need to unplug / reconnected USB of MKR WiFi1010 device to be abble to see the serial message.

@polygamma

This comment has been minimized.

Copy link

@polygamma polygamma commented Oct 14, 2018

@grezco with the following example, you never see the second message?

#include "ArduinoLowPower.h" // https://www.arduino.cc/en/Reference/ArduinoLowPower
#include "RTCZero.h" // https://www.arduino.cc/en/Reference/RTC

/*
 * initial setup, will be run once at the start of the whole routine
 */
void setup() {
  // init serial connection
  Serial.begin(9600);
  while (!Serial) {}
  RTCZero().begin(false);
}

/*
 * will be run forever, after initial setup() call
 */
void loop() {
  Serial.println("I am being printed, because the device has not been sleeping, yet");
  
  // deep sleep of 5 seconds
  LowPower.sleep(1000 * 5);
  
  Serial.println("I am never being printed, because of a deadlock");
}

Notice the RTCZero().begin(false); call, if you want to avoid that one, install the latest RTCZero version from the master branch, found here including this commit.

Running that snippet, having my commits included, yields the wanted output of:

I am being printed, because the device has not been sleeping, yet
I am never being printed, because of a deadlock
I am being printed, because the device has not been sleeping, yet
I am never being printed, because of a deadlock
...

at least for me...

@grezco

This comment has been minimized.

Copy link

@grezco grezco commented Oct 14, 2018

@polygamma,
No I never see the second message.

@polygamma

This comment has been minimized.

Copy link

@polygamma polygamma commented Oct 14, 2018

Since you wrote in #7 (comment) that you are using Windows 10, I tried the snippet with my fixes on Win10, too.
Sorry, have to confirm, that my changes do not help, if you are using Win 10.
Anyway: When using Arch Linux, and probably any Linux distribution, it does indeed fix the problems.

@grezco

This comment has been minimized.

Copy link

@grezco grezco commented Oct 14, 2018

@polygamma, thanks for the time spent trying to solve my problem.

Until I find a solution, I use

  USBDevice.detach();
  LowPower.sleep(1000 * 5);
  USBDevice.attach();

and reopen the serial monitor when the port appear.

@facchinm

This comment has been minimized.

Copy link
Contributor

@facchinm facchinm commented Oct 15, 2018

@grezco @polygamma @durasno thank you all for testing on different platforms; being able to reproduce the behaviour is crucial to get a solution.
@grezco are you testing with #8 applied? Because it implements (almost) the same solution you are using; I'd hate to insert OS-specific code based on the machine you are working with (these kind of solution never work in the real world)

@grezco

This comment has been minimized.

Copy link

@grezco grezco commented Oct 15, 2018

Hi @facchinm
As previously said, #8 don't work (for me) with Windows10 and MKR1000.
With Arduino SAMD core - Pull Request #361, the serial port don't disappear in the device manager of Windows 10. But after wake up, in all case, I'm not abble to see the serial message (unless I unplugged / reconnects USB).

@facchinm

This comment has been minimized.

Copy link
Contributor

@facchinm facchinm commented Oct 15, 2018

@grezco so what did you mean with

Until I find a solution, I use ...

if you are unable to see the serial message? Does adding the extra lines change the behaviour over #8 or not?

@grezco

This comment has been minimized.

Copy link

@grezco grezco commented Oct 15, 2018

@facchinm, #8 don't change the behaviour when I use (or not) USBDevice.detach();
With, or without #8, I need to unplug / reconnected USB of MKR WiFi1010 device or use USBDevice.detach to be able to see the serial message after the wake up.

#include ArduinoLowPower.h" // https://www.arduino.cc/en/Reference/ArduinoLowPower
#include "RTCZero.h" // https://www.arduino.cc/en/Reference/RTC

void setup() {
  // init serial connection
  Serial.begin(9600);
  while (!Serial) {}
  RTCZero().begin(false);
}

void loop() { 
  Serial.println("I am being printed, because the device has not been sleeping, yet");
  delay(10);
  USBDevice.detach();
  LowPower.sleep(1000 * 5); 
  USBDevice.attach();
  delay(5000);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
  Serial.println("Wake up MCU");
}
@fabik111

This comment has been minimized.

Copy link

@fabik111 fabik111 commented Jan 10, 2019

Hi guys, I had the same problem with MKR1000 and I've solved using the library version on GitHub (the version on Library Manager not works) and adding these lines of code on your project:
USBDevice.detach(); LowPower.deepSleep(); USBDevice.attach();

@pchatill

This comment has been minimized.

Copy link

@pchatill pchatill commented Mar 20, 2019

Hi.
Same problem for me: Serial not working after wakeup .
"USBDevice.detach(); LowPower.sleep(); USBDevice.attach();" helped me a lot,
But I need to close the sérial monitor and re-open (IDE 1.8.8 , windows 10).
And I miss some informations on serial port if I don't do that quickly enough
Is there a way do to that automatically?
And is that planned to modify the library?
Thanks a lot for answers.
Patrick

@facchinm

This comment has been minimized.

Copy link
Contributor

@facchinm facchinm commented Mar 21, 2019

Hi @pchatill , it was proposed for inclusion in the IDE (arduino/Arduino#8046). That PR is already included in Beta builds of the IDE but has some problems with non arduino boards (esp8266 and similar) so we decided to postopone the merge in master.
Testing it would greatly speedup merge ;)

@pchatill

This comment has been minimized.

Copy link

@pchatill pchatill commented Mar 21, 2019

Thanks for your response facchinm.
I tried with IDE beta 1.8.9.
It seems not necessary with this version to add :USBDevice.detach(); USBDevice.attach();
But it's always necessary to close serial monitor and reopen it.
The difference is that the serial monitor output is cleared when Arduino sleep.
The other difference is that the serial monitor looks active again when arduino wake-up (Autoscroll function active for example) but no data displayed ...

@facchinm

This comment has been minimized.

Copy link
Contributor

@facchinm facchinm commented Mar 21, 2019

The beta should be numbered 1.9.0 , please double check if you are using that one 😉
Beside that, are you on Windows?

@pchatill

This comment has been minimized.

Copy link

@pchatill pchatill commented Mar 21, 2019

Sorry for the mistake: Yes I tried with Arduino 1.9.0-beta.
Yes windows 10

@pchatill

This comment has been minimized.

Copy link

@pchatill pchatill commented Jun 9, 2019

Hi facchim.
Do you have any news about the problem?
Thanks a lot...

@netless-ww

This comment has been minimized.

Copy link

@netless-ww netless-ww commented Jan 1, 2020

I have found the following code using the Arduino low power library is a partial solution - at least it gives you a delay to close & reopen the USB serial port, after the SAMD wakes up.

I'm using a 16x2 LCD to see what is happening while the serial port is unavailable - remove if you wish. Also the code is a bit messy with commented out sections where I have been trying other low power libraries.

The method uses the USBDevice.detach() -- LowPower.deepSleep() -- USBDevice.attach() combination, together with a delay while(!Serial) {} to give you time to close & reopen the Serial port.

Note: delay(1000); after restarting the USBDevice is very important. The value of Serial is initially returned as 1, and will drop straight through the while delay - after the one second delay however, the value of Serial changes back to 0 and is captured in the while loop until a new Serial window is opened and the value of Serial changes back to 1.

Still not an ideal solution, but at least you get a working Serial window back without losing any output.

Incidentally, the LowPower.deepSleep(); library command also does a USBDevice.detach() -- USBDevice.attach() internally - without the external USBDevice.detach() -- USBDevice.attach() sequence, this will keep your existing Serial communication open (no need to restart) and can receive commands, but will not display any output to the serial monitor. Perhaps this is because there is no 1 second delay & the serial port not being closed and reopened.

There are lots of funny timing issues going on here - I would appreciate it if anyone can shed more light on this.

// **** INCLUDES *****
#include "ArduinoLowPower.h"
#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>

LiquidCrystal_PCF8574 lcd(0x27); // set the LCD address to 0x27 for a 16 chars and 2 line display

// External interrupt on pin 0 (use pin 0 to 24, except pin 4 on Arduino Zero)
const int pin = 12;
unsigned char count = 3;

void setup()
{
// Wait for serial USB port to open
Serial.begin(9600);
delay(2000);
Serial.println("***** ATSAMD21 Standby Mode Example *****");

lcd.begin(16, 2); // initialize the lcd
lcd.setBacklight(HIGH);
printMessages(1, 0, 0); //print Found LCD
delay(2000); //small delay before the screen is cleared
lcd.home(); lcd.clear();

// ***** IMPORTANT *****
// Delay is required to allow the USB interface to be active during
// sketch upload process
Serial.println("Entering standby mode in:");
for (count; count > 0; count--)
{
  Serial.print(count);	
  Serial.println(" s");
  delay(1000);

}
// ********************
// External interrupt on pin (example: press of an active low button)
// A pullup resistor is used to hold the signal high when no button press
pinMode(pin, INPUT_PULLUP);
LowPower.attachInterruptWakeup(pin, blink, LOW);
}

void loop()
{
Serial.println("Entering standby mode.");
Serial.println("Apply low signal to wake the processor.");
Serial.println("Zzzz...");
Serial.print("SCB_SCR_SLEEPDEEP_Msk ");
Serial.println(SCB_SCR_SLEEPDEEP_Msk, BIN);
Serial.print("~SCB_SCR_SLEEPDEEP_Msk ");
Serial.println(~SCB_SCR_SLEEPDEEP_Msk, BIN);
//Serial.println(GCLK->CLKCTRL.reg, BIN);
printMessages(0, 0, 0);
printMessages(0, 0, 1);

// Detach USB interface
   USBDevice.detach();

// Enter standby mode
// LowPower.standby();
/* This is all LowPower.standby() does
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__DSB();
__WFI();
*/
LowPower.deepSleep(5000);
//LowPower.idle(IDLE_2);

lcd.setCursor(0, 0); lcd.print(F("Awake"));

// Attach USB interface
USBDevice.attach();
// It appears the Serial is returned as 1 after the attach command
// However it also appears to revert to 0 after 1 sec of inactivity
// Thus being trapped in the following while statement until the new
// serial monitor is opened. If the following delay is omitted the
// following while loop will pass straight through, without waiting for
// the new serial monitor to open!!

 delay(1000); 

// Force delay until the old serial monitor is closed and a new one
// is opened, changing Serial from 0 back to 1
int s = Serial;
lcd.setCursor(8, 0); lcd.print(s);

while(!Serial) {lcd.setCursor(10, 0); lcd.print(s);s++;} //Close OLD & open NEW Serial connection
//during this delay

lcd.setCursor(8, 1); lcd.print(Serial);
lcd.setCursor(0, 1); lcd.print(F("Serial"));

Serial.println("Awake!");
Serial.println("Serial Communication Restored!");
Serial.println("Send any character to enter standby mode again");

// Wait for user response
// Serial.available is 0 while there are no characters in the USB pipline,
// causing the while to loop indefinitely.
// As soon as a character is typed, Serial.available changes to 1 and
// characters are read from the USB pipline until it is empty and
// Serial.available returns to 0 and the second while loop terminates.
while(!Serial.available());
while(Serial.available() > 0)
{
Serial.read();
}

}

void blink(void)
{

}
/***************************************************************************/
//Print messages to the LCD

void printMessages(uint8_t messNo, uint8_t messCol, uint8_t messRow ) {
lcd.setCursor(messCol, messRow); //set up cursor possition

if (messNo == 0) lcd.print(F(" "));
if (messNo == 1) lcd.print(F("Found LCD "));
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants
You can’t perform that action at this time.