Serial.println producing garbled characters after waking from Power Down mode

Hi folks,

I'm using a Pro Mini with a 3.3V ATMega328 and I'm trying to merge two pieces of code. Each of the two pieces of code works perfectly when executed independently.

The first part uses the Low Power library to put the ATMega328 into Power Down mode for 8 seconds - or multiples of 8 seconds (from http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/)

The second part is the secret voltmeter to measure the voltage of Vcc (from Google Code Archive - Long-term storage for Google Code Project Hosting.). This code measures Vcc and then outputs it to the serial monitor.

So, I'm trying to combine the two to periodically measure Vcc, and sleep between measurements for a fixed period.

However, when the two pieces of code are combined, the serial monitor shows garbled/erroneous characters. I've put in a line of code that returns three characters ("ABC") but these are garbled too.

Does something happen to the serial port during Power Down or wake-up that will cause it to malfunction... does it have to be reinitialised after wake-up?

The code is below.

I'd appreciate any help to get this working.

Thanks,

Andy.

// **** INCLUDES *****
#include "LowPower.h"
// Declare Global Variables Here
int Counter = 1; // to count multiples of 8sec power down period

long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}

void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
}

void loop()
{
// Enter power down state for 8 s with ADC and BOD module disabled
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

if (Counter >= 1) // check if counter is at required number
{
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
Serial.println( readVcc(), DEC ); // send the measured value of Vcc to serial monitor
Serial.println( "abc" );
Counter = 1; // reset counter to 1
}
else
{
Counter++; // increment counter
}
}

Flush before you sleep.

Serial is slow, so the output is buffered. When you print, it loads the characters into an array, and interrupts take care of pushing them out while the rest of the code runs. What's happening is that your controller is going to sleep before everything gets transmitted, so it's probably sleeping in the middle of a transmit. It'll then wake up in the middle of a transmit and finish the rest of the array, giving you garbage.

The fix is to put Serial.flush() before you powerDown.

That worked a treat!

Many thanks Jiggy-Ninja :wink: