2

I am using an infrared sensor and a flex sensor to read values from the serial monitor in arduino, however after maybe ten seconds or so it seems the serial monitor breaks and the printed values start to print out rapidly. Does anyone have any suggestions on why this might occurring. Any information would be highly appreciated.

Thanks.

int previousMillis = 0;

long interval1 = 300;
long interval2 = 350;

void setup() {

    Serial.begin(9600);
}

void loop() {

    unsigned long currentMillis = millis();

    if ( currentMillis - previousMillis >= interval1 ) {
        previousMillis = currentMillis;

        Serial.println( "TIMER IS DONE!" );

        int val1 = analogRead(0);
        Serial.print("Sensor Value 1 is ");
        Serial.println(val1);
        delay(5);
    }
    if ( currentMillis - previousMillis >= interval2 ) {
        previousMillis = currentMillis;

        int val2 = analogRead(1);

        Serial.print("Sensor Value 2 is ");
        Serial.println(val2);
    }
    delay(10);
}
  • why the two separate intervals? – Madivad Jul 10 '16 at 23:50
  • Two separate intervals are for different sensors, photocell and infrared. – Joshua Garcia Jul 11 '16 at 0:05
  • If it's a case you're simply wanting to test sensor 1 precisely every 300ms and sensor 2 at precisely every 350ms, then you'll have to monitor two previousMillis values. I've taken it to mean you wanted to test sensor 2 50ms after sensor 1 as per my code below. Alternatively you could use real timers and interrupts! That's a nice little exploration for you (but unnecessary unless you just want to have a little fun) :) – Madivad Jul 11 '16 at 2:00
  • I'm not completely sure what is going wrong, but you're having two intervals using the same interval variable. So, make a previousMillis1 and previousMillis2, one for each interval. – Len Jul 11 '16 at 7:31
1

I hate to start with "I hate delays", but I hate delays :)

Why have you included them? If you want your outputs to be slower, increase your intervals.

Use a state machine instead:

unsigned long previousMillis = 0;
unsigned long currentMillis = 0;

unsigned long interval1 = 300;
unsigned long interval2 = 350;

#define LEDPIN  13

int state = 0;
// 0 = waiting for sensor one interval
// 1 = another 50ms for sensor two

void setup() {
    currentMillis=millis();
    previousMillis=currentMillis;
    Serial.begin(9600);
    pinMode(LEDPIN, OUTPUT);
    digitalWrite(A0, HIGH); // internal pullups
    digitalWrite(A1, HIGH); // internal pullups

}

void loop() {
    currentMillis = millis();
    if ( state == 0 ) 
    {
        if ( currentMillis - previousMillis >= interval1) 
        {
            int val1 = analogRead(0);
            Serial.print( currentMillis );
            Serial.print(" Sensor Value 1 is ");
            Serial.println(val1);
            digitalWrite(LEDPIN, HIGH);
            state = 1;
        }
    }
    else
    {
        if ( currentMillis - previousMillis >= interval2) 
        {
            int val2 = analogRead(1);
            Serial.print( currentMillis );
            Serial.print(" Sensor Value 2 is ");
            Serial.println(val2);
            digitalWrite(LEDPIN, LOW);   
            state = 0;         
            previousMillis = currentMillis; 
        }
    }
}

This way, test 2 will only be conducted 50ms after test 1 and then previous millis is reset

edit: I fixed the interval test regarding overflow (which you had correctly in the first place)

edit2: (I'm having too much fun with this) assuming you want each test conducted at specifically the interval requested (ie sensor 1 every 300ms and sensor 2 every 350ms), I have come up with v2 (and removed the state machine, since it's just not needed)

unsigned long previous1 = 0;
unsigned long previous2 = 0;
unsigned long currentMillis = 0;

unsigned long interval1 = 300;
unsigned long interval2 = 350;

const int LEDPIN = 13;

void setup() {
    currentMillis=millis();
    previous1=currentMillis;
    previous2=currentMillis;
    Serial.begin(9600);
    pinMode(LEDPIN, OUTPUT);
    digitalWrite(A0, HIGH);
    digitalWrite(A1, HIGH);
}

void loop() {

    currentMillis = millis();
    if ( currentMillis - previous1 >= interval1) 
    {
        previous1 = currentMillis;

        int val1 = analogRead(0);
        Serial.print(currentMillis);
        Serial.print(" Sensor Value 1 is ");
        Serial.println(val1);
        digitalWrite(LEDPIN, HIGH);
    }
    if ( currentMillis - previous2 >= interval2) 
    {
        int val2 = analogRead(1);

        Serial.print(currentMillis);
        Serial.print(" Sensor Value 2 is ");
        Serial.println(val2);
        previous2 = currentMillis; 
        digitalWrite(LEDPIN, LOW);            
    }
}

edit: including some sample output to indicate a working state:

188609 Sensor Value 1 is 15
188659 Sensor Value 2 is 14
188959 Sensor Value 1 is 14
189009 Sensor Value 2 is 15
189309 Sensor Value 1 is 15
189359 Sensor Value 2 is 14
189659 Sensor Value 1 is 14
189709 Sensor Value 2 is 1017
190009 Sensor Value 1 is 15
190059 Sensor Value 2 is 1002
190359 Sensor Value 1 is 14
190409 Sensor Value 2 is 1013
190709 Sensor Value 1 is 14
190759 Sensor Value 2 is 1019
191059 Sensor Value 1 is 15
191109 Sensor Value 2 is 1004
191409 Sensor Value 1 is 14
191459 Sensor Value 2 is 1019
191759 Sensor Value 1 is 15
191809 Sensor Value 2 is 15
192109 Sensor Value 1 is 14
192159 Sensor Value 2 is 15
192459 Sensor Value 1 is 14
192509 Sensor Value 2 is 14
192809 Sensor Value 1 is 15
192859 Sensor Value 2 is 15
193159 Sensor Value 1 is 14
193209 Sensor Value 2 is 16
193509 Sensor Value 1 is 14
193559 Sensor Value 2 is 15
193859 Sensor Value 1 is 1005
193909 Sensor Value 2 is 1021
194209 Sensor Value 1 is 1021
194259 Sensor Value 2 is 1003
194560 Sensor Value 1 is 1004
194609 Sensor Value 2 is 1020
194909 Sensor Value 1 is 1020
194959 Sensor Value 2 is 1004
195259 Sensor Value 1 is 15
195309 Sensor Value 2 is 1001
195609 Sensor Value 1 is 14
195659 Sensor Value 2 is 1022
195959 Sensor Value 1 is 15
196009 Sensor Value 2 is 998
196310 Sensor Value 1 is 15
196359 Sensor Value 2 is 1019
196659 Sensor Value 1 is 15
196709 Sensor Value 2 is 1002
197009 Sensor Value 1 is 14
197059 Sensor Value 2 is 15
197359 Sensor Value 1 is 14
197409 Sensor Value 2 is 15
197709 Sensor Value 1 is 15
197760 Sensor Value 2 is 13
198060 Sensor Value 1 is 14
198110 Sensor Value 2 is 15
198410 Sensor Value 1 is 15
198460 Sensor Value 2 is 14
  • this is assuming you want test2 50ms after test1 – Madivad Jul 11 '16 at 0:17
  • Thanks for an additional solution, however, I am still getting the issue where only one sensor value displays. Also, the value doesn't get reset over a certain duration, it's static. – Joshua Garcia Jul 11 '16 at 0:29
  • Do you mean you're only getting data for sensor 1 and never sensor 2? can you give a sample output of what you are getting? possibly include state and millis values to further diagnose. – Madivad Jul 11 '16 at 0:55
  • You're enabling my procrastination here... I'm setting up a board for a "quick" (LOL) test... – Madivad Jul 11 '16 at 1:00
  • my appologies, I had several bugs in that code. I was hand coding without an ide... try the edited code above, should be better :) – Madivad Jul 11 '16 at 1:19
1

You are doing math with 2 different types. One is long and the other is an int. So, eventually the long will always be lager than the int and the test will always be true. (A 32 bit long can count up to over 2 billion. A 16 bit int can only count up to about 32 thousand.)

Also, the method millis() is of type "unsigned long". So change all your variables to match this type.

Also note that when the millis() timer overflows and start over your program may perform unexpectedly. Since this rarely happens it may not concern you.

  • Thank you! This works however, now the monitor won't print both values at the same time. Instead it prints sensor val1 until I stop the program. If I comment out the first if statement with the sensor 1 value and keep the sensor 2 statement the monitor will print val2. – Joshua Garcia Jul 10 '16 at 23:40
  • 1
    Because it's always the first test that is executed first and previous millis is reset within it – Madivad Jul 10 '16 at 23:56
  • If the types are right, and the test is performed correctly (it is), then the millis() overflow will cause no issue. In fact, in this kind of situation I may use unsigned int rather of unsigned long just to save some memory. – Edgar Bonet Jul 11 '16 at 8:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.