Hi all,
I want to put my Arduino pro Micro (Atmega32U4) to deep sleep mode and wake up every 1 minute checking some alarms, sending a short message and then going back to sleep again using a loop for extending my watchdog timer.
I read about it in the following link:
https://forum.arduino.cc/index.php?topic=173850.0
I used Nick Gammon's code for this purpose.
My problem is, it sometimes does not enter sleep mode. Keeps sending messages for about a minute (this time varies every time it goes crazy) and then it goes to sleep normally. This bug occurs at least 5 times in an hour and I don't know what's wrong.
I'd be really grateful if anyone could help me out.
/******************************************************************************
* Include files
******************************************************************************/
#include <arduino.h>
#include "HopeDuino_LoRa.h"
#include <avr/sleep.h>
#include "ArduinoUniqueID.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <EEPROM.h>
#include <avr/wdt.h>
#include <avr/power.h>
/******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
#define RX_MODE 1
#define TX_MODE (!RX_MODE)
#define LEN 32
const int buttonPin0 = 0; // the number of the pushbutton pin
const int buttonPin1 = 1;
const int buttonPin2 = 2;
const int buttonPin3 = 3;
const int buttonPin4 = 7;
// variables will change:
volatile int stud0,stud1,stud2,stud3,stud4= 0; // variable for reading the pushbutton status
#define LED_PIN 6
#define LED_PORT() pinMode(LED_PIN,OUTPUT)
#define LED_HIGH() digitalWrite(LED_PIN,HIGH)
#define LED_LOW() digitalWrite(LED_PIN,LOW)
byte str[LEN]={'H','o','p','e','R','F',' ','R','F','M',' ','C','O','B','R','F','M','9','5','W','A','+','+','+'};
//byte mac[]={UniqueID8};
byte str0[]= "stud11";
byte str1[]= "stud21";
byte str2[]= "stud31";
byte str3[]= "stud41";
byte str4[]= "stud51";
byte str5[]={"batt"};
byte getstr[LEN];
byte mode = RX_MODE;
const byte app_syncword[] = { 0x2D, 0xD4, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 } ;
void setup(void)
{
LED_PORT();
Modulation = LORA; ///Was FSK
COB = RFM95; // Was RFM95
Frequency = 915000; // was 866000
OutputPower = 3; //17dBm OutputPower
PreambleLength = 8; //8Byte preamble
FixedPktLength = true; //explicit header mode for LoRa
PayloadLength = 21;
CrcDisable = true ;
//for LORA parameter
SFSel = SF9;
BWSel = BW125K;
CRSel = CR4_5;
// initialize the pushbutton pin as an input:
pinMode(buttonPin0, INPUT);
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
pinMode(buttonPin4, INPUT);
// Attach an interrupt to the ISR vector
attachInterrupt(digitalPinToInterrupt(buttonPin0|buttonPin1|buttonPin2|buttonPin3|buttonPin4), pin_ISR, HIGH);
vInitialize();
bSendMessage(UniqueID8,9);
}
void loop(void)
{
power_Down(); //Low-Power mode
vGoSleep();
static byte last_mode=RX_MODE;
pin_ISR();
stud0 = digitalRead(buttonPin0);
stud1 = digitalRead(buttonPin1);
stud2 = digitalRead(buttonPin2);
stud3 = digitalRead(buttonPin3);
stud4 = digitalRead(buttonPin4);
if (stud0==1){ //It takes a long time to start the initial blink
//vReset();
vInitialize();
_delay_ms(10);
mode = TX_MODE;
LED_HIGH();
_delay_ms(25);
bSendMessage(str0,8);
_delay_ms(50);
bSendMessage(UniqueID8,9);
LED_LOW();
}
else if (stud1==1){ //It takes a long time to start the initial blink
//vReset();
vInitialize();
_delay_ms(10);
mode = TX_MODE;
LED_HIGH();
_delay_ms(25);
bSendMessage(str1,8);
_delay_ms(50);
bSendMessage(UniqueID8,9);
LED_LOW();
_delay_ms(100);
}
else if (stud2==1){ //It takes a long time to start the initial blink
//vReset();
vInitialize();
_delay_ms(10);
mode = TX_MODE;
LED_HIGH();
_delay_ms(25);
bSendMessage(str2,8);
_delay_ms(50);
bSendMessage(UniqueID8,9);
LED_LOW();
_delay_ms(100);
}
else if (stud3==1){ //It takes a long time to start the initial blink
//vReset();
vInitialize();
_delay_ms(10);
mode = TX_MODE;
LED_HIGH();
_delay_ms(25);
bSendMessage(str3,8);
_delay_ms(50);
bSendMessage(UniqueID8,9);
LED_LOW();
_delay_ms(100);
}
else if (stud4==1){ //It takes a long time to start the initial blink
vInitialize();
_delay_ms(10);
mode = TX_MODE;
LED_HIGH();
_delay_ms(25);
bSendMessage(str4,8);
_delay_ms(50);
bSendMessage(UniqueID8,9);
LED_LOW();
_delay_ms(100);
}
else{
/*
* Watchdog timer
*/
myWatchdogEnable (0b100001); // 8 seconds
myWatchdogEnable (0b000111); // 2 seconds
myWatchdogEnable (0b100001); // 8 seconds
myWatchdogEnable (0b000111); // 2 seconds
myWatchdogEnable (0b100001); // 8 seconds
myWatchdogEnable (0b000111); // 2 seconds
myWatchdogEnable (0b100001); // 8 seconds
myWatchdogEnable (0b000111); // 2 seconds
myWatchdogEnable (0b100001); // 8 seconds
myWatchdogEnable (0b000111); // 2 seconds
myWatchdogEnable (0b100001); // 8 seconds
myWatchdogEnable (0b000111); // 2 seconds
vInitialize(); //Turn on RFM95
_delay_ms(50);
bSendMessage(UniqueID8,9); // after every 1 minute send a message
}}
void pin_ISR() {
stud0 = digitalRead(buttonPin0);
stud1 = digitalRead(buttonPin1);
stud2 = digitalRead(buttonPin2);
stud3 = digitalRead(buttonPin3);
stud4 = digitalRead(buttonPin4);
digitalWrite(LED_PIN, stud0);
digitalWrite(LED_PIN, stud1);
digitalWrite(LED_PIN, stud2);
digitalWrite(LED_PIN, stud3);
digitalWrite(LED_PIN, stud4);
}
ISR(WDT_vect)
{
wdt_disable(); // disable watchdog
}
void myWatchdogEnable(const byte interval)
{
MCUSR = 0; // reset various flags
WDTCSR |= 0b00011000; // see docs, set WDCE, WDE
WDTCSR = 0b01000000 | interval; // set WDIE, and appropriate delay
MCUCR |= (1<<JTD);
MCUCR |= (1<<JTD); // Disable JTAG
vGoSleep(); // turn off RFM95
DDRF = 0x00; //Disable portF
PORTF = 0x00;
MCUCR = 1;
wdt_reset();
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_mode(); // now goes to Sleep and waits for the interrupt
}
void power_Down()
{
vGoSleep(); // turn off RFM95
ADCSRA = 0;
delay(1); //IMPORTANT!!! Allow time for changing firmware, or otherwise if we disable the USB too soon we are stuck and only a re-flash of the bootloader may help
power_adc_disable();
delay(1);
power_usart0_disable();
delay(1);
power_spi_disable();
delay(1);
power_twi_disable();
delay(1);
power_timer1_disable();
delay(1);
power_timer2_disable();
delay(1);
power_timer3_disable();
delay(1);
power_usart1_disable();
delay(1);
power_usb_disable();
delay(1);
USBCON |= (1 << FRZCLK); // Freeze the USB Clock
PLLCSR &= ~(1 << PLLE); // Disable the USB Clock (PPL)
USBCON &= ~(1 << USBE ); // Disable the USB
delay(1);
// Switch to RC Clock
UDINT &= ~(1 << SUSPI); // UDINT.SUSPI = 0; Usb_ack_suspend
USBCON |= ( 1 <<FRZCLK); // USBCON.FRZCLK = 1; Usb_freeze_clock
PLLCSR &= ~(1 << PLLE); // PLLCSR.PLLE = 0; Disable_pll
CLKSEL0 |= (1 << RCE); // CLKSEL0.RCE = 1; Enable_RC_clock()
while ( (CLKSTA & (1 << RCON)) == 0){} // while (CLKSTA.RCON != 1); while (!RC_clock_ready())
CLKSEL0 &= ~(1 << CLKS); // CLKSEL0.CLKS = 0; Select_RC_clock()
CLKSEL0 &= ~(1 << EXTE); // CLKSEL0.EXTE = 0; Disable_external_clock
delay(1);
}