Weird delay problem.

Status
Not open for further replies.

RMIM

Member
Dear All,

I’m new to arduinno and c – there’s this problem that's driving me nuts, I hope someone can shed some light on it.

I was building a sky remote/tv/projector that I could control on my phone using Bluetooth and a program called microcontrol(android app). It seems to work great – I then wanted to leave the prototype world and make the real thing. I bought the same atmel chip as my arduino and made a permanent circuit. Again it seem to work great except for the fact it would eat batteries.

So I wanted to use power down mode.

I felt my system would feel smoother and not laggy if I had a delay so it would remain in loop for say 15sec before going on to sleep.

My method to keep it in loop before going to sleepNow() was to

count=count-1;
if (count==0){sleepNow(); count=150;}


but for some reason it does not delay unless I leave the line Serial.print(" LLLL start of loop LLLL "); - which is weird as it really has nothing to do with anything, it was just added so I could see where it was in the program when it was running.

As soon as I remove this line the delay does not work and it goes quickly to sleep. If I include the line it delays as it should – I can even increase count and it will delay for longer as expected.

What’s going on? (thinking about it seems when Serial.print(" LLLL start of loop LLLL "); is not running causes it to jump out. what's causing the jump? the interrupt? why is running something on serial.print stopping it?)

Thanks.

Code:
/*
* IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
* An IR LED must be connected to Arduino PWM pin 3.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
*/

#include <IRremote.h>
#include <SoftwareSerial.h>  //software serial as hardware serial not working!

#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>

SoftwareSerial mySerial(2, 10); // RX, TX change to pin 2 from 9 for interrupt

IRsend irsend;
const int ledPin =  13;
unsigned long count = 150;


////////////////////////////////////////////////////////////////////
//////////////////////////start setup/////////////////////////////////

void setup()
                        {

                                  Serial.begin(9600);
                                  mySerial.begin(9600);
                          
                                  Serial.print(" QQQQ void setup QQQQ ");
                          
                                  pinMode(2,INPUT_PULLUP);
                                  pinMode(13,OUTPUT);

                        }
////////////////////////////////////////////////////////////////////
///////////////////////////end setup ////////////////////////////////


////////////////////////////////////////////////////////////////////
/////////////////////////start loop//////////////////////////////////
void loop()

                  {
                          digitalWrite(13,HIGH);
                                              
                          Serial.print(" LLLL start of loop LLLL ");// WHEN I REMOVE THIS LINE MY DELAY DOES NOT WORK
                  
                  

                      if (mySerial.available())
                                                              {
                                                                    char serr = mySerial.read();

                                                                    if(serr == 'P')    {goto jump6;}
                                                                    else if(serr == 'Q')  { goto jump7;}
                                                              }

goto start;

jump6:
            irsend.sendNEC(0xAF548B7, 32); // vol up
            Serial.print(" vol up");
            delay (50);
            goto start;

jump7:
            irsend.sendNEC(0xAF5A857, 32); // vol down
            Serial.print(" vol down");
            delay (50);
            goto start;
        


start:


count=count-1;
if (count==0){sleepNow(); count=150;} //loops 150times then jumps to sleepnow for delay

}
////////////////////////////////////end loop////////////
///////////////////start sleep///////////////////////////

void sleepNow(void)
{
Serial.print("xxxx in sleep xxxx ");
delay(100);

set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Choose our preferred sleep mode:
sleep_enable(); // Set sleep enable (SE) bit:
attachInterrupt(0, pinInterrupt, LOW);  //interrupt 0 is on pin 2

digitalWrite(13,LOW);

sleep_mode(); // Put the device to sleep:
sleep_disable(); // Upon waking up, sketch continues from this point.

}
//////////////////////end sleep///////////////////////////////////
/////////////////////stop interrupt////////////////////////////////
void pinInterrupt(void)
{
  detachInterrupt(0);
  Serial.print("--- TURN OFF INTERR ---");

}
 
Last edited:
Difficult to say because the Arduino sketch documentation is so bad. Maybe the call to serial functions enables/disables global interrupts or does something else that affects the system.
 
Difficult to say because the Arduino sketch documentation is so bad. Maybe the call to serial functions enables/disables global interrupts or does something else that affects the system.

Thanks for the reply misterT.

I had a thought last night of adding noInterrupts(); at the start of the loop, then Interrupts() to the SleepNow. - could that work?

edit - just tried it - did not help.
 
Last edited:
Difficult to say because the Arduino sketch documentation is so bad. Maybe the call to serial functions enables/disables global interrupts or does something else that affects the system.

I have stripped all the code out and left just the sleep and delay bits in. What should happen when pin 2 goes low it should keep the led on until count = 0 and then sleep.

For some reason even this is jumping out! How do I make a simple delay? Why is this method not working? Why did it work when the serialprint line was in?


Code:
#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>


const int ledPin =  13;
unsigned long count = 350;



void setup()
{
  pinMode(2,INPUT_PULLUP);
  pinMode(13,OUTPUT);
}


void loop()

{          
digitalWrite(13,HIGH);


count=count-1;
if (count==0){sleepNow(); count=350;}
}

void sleepNow(void)
{

set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Choose our preferred sleep mode:
sleep_enable(); // Set sleep enable (SE) bit:
attachInterrupt(0, pinInterrupt, LOW);  //interrupt 0 is on pin 2
 
digitalWrite(13,LOW);

sleep_mode(); // Put the device to sleep:
// Upon waking up, sketch continues from this point.
sleep_disable();
}


void pinInterrupt(void)
{
  detachInterrupt(0);
}

edit: adding the lines Serial.begin(9600); and Serial.print("hello"); in the appropriate places makes everything work. why?
 
Last edited:
ok the penny has dropped. in order to see a sizable delay count had to be 350,000 - when Serial.print was present obviously that contains many lines of assembly (which are hidden from us) so only needed count to be 350. that's my guess.
 
Last edited:
You do realise that delay(1000); is a 1 second delay
350 is 350 milliseconds and 350,000 is 350 seconds?

The loop would execute very fast 20 MHz
Use Serial,println() to make screen readable

how about
delay(2000); in the loop or something

Also
for (int count=350;count<0;count--) should save work
Edit::Typo() --I can see spending my time looking was a waste of time . I'll not bother again.
 
Last edited:
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…