1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Weird delay problem.

Discussion in 'Arduino' started by RMIM, Nov 29, 2013.

  1. RMIM

    RMIM Member

    Joined:
    Jul 17, 2006
    Messages:
    154
    Likes:
    0
    Location:
    (London) Epsom Surrey. England.
    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 (text):
    /*
    * 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: Nov 30, 2013
  2. misterT

    misterT Well-Known Member Most Helpful Member

    Joined:
    Apr 19, 2010
    Messages:
    2,697
    Likes:
    368
    Location:
    Finland
    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.
     
  3. RMIM

    RMIM Member

    Joined:
    Jul 17, 2006
    Messages:
    154
    Likes:
    0
    Location:
    (London) Epsom Surrey. England.
    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: Nov 30, 2013
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. RMIM

    RMIM Member

    Joined:
    Jul 17, 2006
    Messages:
    154
    Likes:
    0
    Location:
    (London) Epsom Surrey. England.

    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 (text):
    #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: Dec 1, 2013
  6. RMIM

    RMIM Member

    Joined:
    Jul 17, 2006
    Messages:
    154
    Likes:
    0
    Location:
    (London) Epsom Surrey. England.
    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: Dec 2, 2013
  7. april

    april Member

    Joined:
    Mar 12, 2012
    Messages:
    250
    Likes:
    20
    Location:
    Cairns Great Barrier Reef -QLD-Australia
    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: Dec 31, 2013
  8. jpanhalt

    jpanhalt Well-Known Member Most Helpful Member

    Joined:
    Jun 21, 2006
    Messages:
    6,056
    Likes:
    519
    Location:
    Cleveland, OH, USA
    I don't understand that math. Isn't delay() a delay in milliseconds? (http://arduino.cc/en/Reference/delay)

    Happy New Year.

    John
     
  9. RMIM

    RMIM Member

    Joined:
    Jul 17, 2006
    Messages:
    154
    Likes:
    0
    Location:
    (London) Epsom Surrey. England.
     

Share This Page