328P wakeup with USART PCINT2-Interrupt - wakeup works, interrupt doesnt

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi there,

 

i have a BT module that is used to wake up the 328P. The wakeupo actually works, but the interrupt is not executed.

Anyone has an idea why?

 

#include "arduino.h"
#include <DS3231_Simple.h>
#include "wire.h"

#include <avr/wdt.h>
#include "EEPROM.h"

#include <avr/sleep.h>

/*
 * Turn on voltagesource for bluetooth, RTC and relais
 */
void extOn(){
	// set back to output and pull low to make mosfet conductive
	DDRB  |=  (1 << PB3);
	PORTB &= ~(1 << PB3);

}


volatile bool BTWakeupRequest = false;
byte oldADCSRA = 0;


void gotoSleep(){
	oldADCSRA = ADCSRA;
	ADCSRA = 0;

	sei();	// IMPORTANTE: Interrupts must be enabled in ordedr to wake up the Microcontrolller via interrupt!


	//TODO: change back to 0
	byte sleepCount = 3;

	// every 8s wakeup is still to often, so we count and go straight back to sleep almost imediately
	// When ignition is changed, we want to get out of the sleep loop! The device might should run then.
	// when ignition is changed to not waste time - and get a potential error beep right away when ignition is turned on (ignitionChanged)
	while(sleepCount < 6 && BTWakeupRequest == false){

		PORTB &= ~(1 << PB5);

		sleep_cpu();

		PORTB |= (1 << PB5);	//Signal on state on pin 13 (LED)

		sleepCount++;

		// for readout with uno
		delay(10);

	}
	//for debugging purposes
	//delay(3000);

	ADCSRA = oldADCSRA;
}




void gotoSleepHandleSerial(){

	Serial.println("Going to sleep");
	Serial.flush();
	//causes copy error in the serial monitor (you cannot copy the text)
	Serial.end();

	gotoSleep();
	extOn();

	delay(5);

	Serial.begin(57600);
	delay(3000);
	Serial.println("woke up");
}





ISR(PCINT2_vect){
	BTWakeupRequest = true;
}


void setup() {
	DDRB  |= (1 << PB5);	//Testpin
	PORTB |= (1 << PB5);	//Signal on state on pin 13 (LED) - needs 2mA more at 12V side of regulator


	PCICR |= (1 << PCIE2); 		//Interrupt for RXD wakeup
	PCMSK2 |= (1 << PCINT16);


	pinMode(6, OUTPUT); 	//Piezo
	pinMode(11, OUTPUT);	//Bluetooth Mosfet


	extOn();

	//enable power down sleep mode
	SMCR |= (1 << SM1);
	SMCR |= (1 << SE);


	tone(6, 3000, 200);
	Serial.begin(57600);
	delay(600);


	delay(100);
	Serial.print(F("\n\n\n# Programversion: "));

	Serial.print(__TIME__);
	Serial.print(" ");
	Serial.println(__DATE__);


	Serial.println(F("Setup finished"));
}









void loop() {

	if(millis() > 5000 && BTWakeupRequest == false){
		gotoSleepHandleSerial();
		if(BTWakeupRequest == true){
			Serial.println("in if");
		}
		Serial.println("out if");
		Serial.println(BTWakeupRequest);
	}
}

 

 

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

Last Edited: Thu. May 9, 2019 - 03:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Add volatile to the definition of:

 

volatile bool BTWakeupRequest = false;

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:

Add volatile to the definition of:

 

volatile bool BTWakeupRequest = false;

 

--Mike

 

 

Hi Mike,

 

in the original code, this is what i already did. I messed this up again! When i tought of this mistake i was like "omfg of course" and was happy because i thought i found the mistake. Well after this i spent hours trying....

 

 

I edited the code. When i now do a serial input when the device is not in sleep, the interrupt is executed.

 

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The interrupt was already getting executed, but

because the flag was not specified as volatile,

the interrupt routine was not modifying it.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:

The interrupt was already getting executed, but

because the flag was not specified as volatile,

the interrupt routine was not modifying it.

 

--Mike

 

I changed this already, and it didnt work. A casual read in the manual brought this to me:

Note: If a level triggered interrupt is used for wake-up from Power-down, the required level must be held
long enough for the MCU to complete the wake-up to trigger the level interrupt. If the level disappears
before the end of the Start-up Time, the MCU will still wake up, but no interrupt will be generated. The
start-up time is defined by the SUT and CKSEL Fuses.

So i tested it, and found out, that the use of a baudrate of 9600 works to wake up the mcu and execute the interrupt.

 

BUT problems still existed:

The interrupt is not executed right after the sleepmode. The part in my normal code has a standby variable for checking if in sleepmode or not. The interrupt is executed a few (!) lines after sleep_cpu();. I remember having simliar trouble doing stuff right after the sleepmode...

 

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tobey wrote:

I remember having simliar trouble doing stuff right after the sleepmode...

 

For this, I drink a lot of coffee!  :-)

 

Your code indicates you are using a pin-change interrupt

and not an external interrupt, so the comment you quoted

about level-triggered external interrupts doesn't apply.

 

The Arduino UNO pinout shows that PCINT16 corresponds

to digital pin 0 which is the RX pin, so that looks fine.  The

Arduino only defines one ISR that I recall (TIMER0_OVF)

so it's probably not messing with yours.  Not sure what

else to recommend except to try using IDLE sleep mode as

a test to see if the interrupt is executed when waking up

from a not-deep sleep mode.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HEres an idea to test if your interrupt is actually firing.

 

Put an LED(with series resistor of course) on an unused pin on your UNO - or whatever Arduino board you are using.

 

Then

 

In the Questionable ISR, activate the pin, and then go into a WHILE(1) loop, which hold the AVR forever.  Even if the ISR fires for a microsecond, the WHILE(1) will prevent the AVR from going ant further and the LED being lit tells you that the ISR did indeed fire.

 

If this works you can then see what is wrong in other code spots.

 

Just thinking out loud....

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user