5

I've got a question regarding the use of Millis() on a Leonardo Arduino. I'm currently using it to time 4 seconds elapsed while sending a serial message every second. These messages play a sound. On the fourth message the sound is different to signify that the Arduino has started an event.

I'm running into an issue where the sounds are occasionally being played sporadically without a consistent 1 second between them. I'm wondering if there is a better way of doing what I'm doing? During the timing the Arduino is doing nothing else, and the receiving computer is also generally not doing anything taxing. Is this even an issue from the Arduino side? My receiving program is written in C# using System.IO.Ports.SerialPort.

The reason this is done through Arduino is because the event started by the Arduino needs to correspond exactly to the sounds, though if this remains unresolved I will need to rework this.

Edit: Code as requested.

void setup()
{
    //Setup Code
}

void loop()
{
    //Code that handles other serial messages and various states
    if (isSpecificState == true)
        onSpecificState();
}

void onSpecificState()
{
    //Setup to handle state

    long holdStart = millis();
    long holdDuration = 0;

    boolean print1 = false;
    boolean print2 = false;
    boolean print3 = false;
    boolean print4 = false;

    while(holdDuration <= 4000)
    {               
        if (holdDuration >= 4000 && !print4)
        {
            Serial.println("tt_sound:2");
            print4 = true;
        }            
        else if (holdDuration >= 3000 && !print3)
        {
            Serial.println("tt_sound:1");
            print3 = true;
        }
        else if (holdDuration >= 2000 && !print2)
        {
            Serial.println("tt_sound:1");
            print2 = true;
        }
        else if (holdDuration >= 1000 && !print1)
        {
            Serial.println("tt_sound:1");
            print1 = true;
        }
        holdDuration = millis() - holdStart;
    }

    //Handle state
}

As I mentioned in the comments, the Arduino is doing nothing else while the timing is happening.

Karoly S
  • 281
  • 2
  • 7
  • 1
    Can you post your Arduino code so that we see if there is an issue in there? – jfpoilpret Jul 09 '14 at 19:53
  • Why the downvote? @jfpoilpret code is up, its painfully simple though. – Karoly S Jul 09 '14 at 20:42
  • Added clarification, the reason I didn't post the code initially is because 95% of the time it works flawlessly. There are however occasions caused by circumstances I haven't figured out in which the sounds are off. This is what I need help with. – Karoly S Jul 09 '14 at 20:52
  • Why not use another timer to schedule them? – Ignacio Vazquez-Abrams Jul 09 '14 at 21:42
  • Have you tried printing the value for holdDuration and see if it is consistent? – Craig Jul 09 '14 at 21:57
  • 1
    Just to clarify: I did not downvote your question. About your code, I doubt you always pass in the first `if`, typically that first `if` should be located **after** the `while` loop. Important question: what are the types of `holdDuration` and `holdStart`? – jfpoilpret Jul 09 '14 at 22:00
  • @IgnacioVazquez-Abrams Could you elaborate? I'm not sure I understand. @Craig I haven't, I've not been able to consistently reproduce the issue. @jfpoilpret Didn't mean to imply you had, was an open question :) Both `holdDuration` and `holdStart` are of type `long`, same as `millis()` return type. – Karoly S Jul 09 '14 at 22:18
  • 1
    I think `millis()` is actually `unsigned long` but that is probably not the issue unless you are running for more than 24 days. – Craig Jul 09 '14 at 22:31
  • Please post the entire code, not just the part that, I presume, is inside the `loop` function. – Gerben Jul 10 '14 at 13:53
  • All I can say is I do not understand what you mean, because you did not give a reproducible example. –  Jul 15 '14 at 16:06
  • Notice items 2 and 3 in this answer: http://electronics.stackexchange.com/a/126063/8627 You may be able to pin point if this is the issue by disabling USB communications and switching to UART combined with a UART-to-USB cable. – jippie Aug 21 '14 at 18:09

2 Answers2

1

There is only a very slight chance that you meet the holdDuration >= 4000 condition in the while loop. Only when holdDuration will be exactly 4000 the while loop will be executed AND the subsequent test in the if statement will pass.

The serial print commands can easily take long enough to have millis() jump from a number less than 4000 to a number higher than 4000 in a single pass of the while loop.

To prove this assumption, increase the while test to holdDuration <= 4100 and see if the intermittent effect goes away.

jippie
  • 2,851
  • 12
  • 23
0

Thoughs: Unfortunately I have been unable to get to the bottom of this issue. I noticed the problem tends to happen the first time the interaction starts after the computer and Arduino are idle.

Without knowing too much about how the serial communication is built I'm guessing that without traffic the connection is put to sleep, or generally inactive, and the sound delay is a result of the connection needing to re-initialize or something of that nature. I cant recall a time when the issue occurred and I had a recent correct previous interaction. Once it works any immediate retrial will also behavior correctly.

Solution: I have since moved my timing/sound playing component within my C# app. The Arduino now signals the start of the timer, and then end of the timer with an immediate start to my event.

Karoly S
  • 281
  • 2
  • 7