Sensor Values + Timing

Hi all,

Currently new to Arduino, I'm currently running into problems with my current project and would like some help / advice.

Project application:

I have a sensor that will be checking if an item is in its field, if there is not for 3 seconds (time value subject to change) then it will alarm (Sending signal to a speaker + Light flash and display to lcd "Check Feed Tube". This will continue to alarm until there is an item in its field. Each alarm will reset its duration once the condition is cleared.

I have currently got the speaker + light flash along with the lcd to display text, my issue is with the time and resetting the clock. I have got it to signal every 3 seconds with millis() by making it check current millis() and then subtract it and check if it is >= 3000. However it does not seem to reset millis() back to 0 and reset the loop. it will continue to add to millis().

I currently am using a ultrasonic distance sensor as the Sensor to mimic a sensor triggering back.

Please see code below.

// C++ code
//
#include <Adafruit_LiquidCrystal.h>

float dist = 0;
unsigned long previousMillis=0;
int interval=3000;
Adafruit_LiquidCrystal lcd_1(0);

long readUltrasonicDistance(int triggerPin, int echoPin)
{
pinMode(triggerPin, OUTPUT);  // Clear the trigger
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(2);
  // Sets the trigger pin to HIGH state for 10 microseconds
 digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
 digitalWrite(triggerPin, LOW);
  pinMode(echoPin, INPUT);
  // Reads the echo pin, and returns the sound wave travel time in microseconds
 return pulseIn(echoPin, HIGH);
}

void setup()
{
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
}

void loop()
{
  unsigned long currentMillis = millis();
  lcd_1.begin(16, 2);
  lcd_1.setBacklight(1);
  lcd_1.setCursor(0, 0);
  lcd_1.print("Operational");
          lcd_1.setCursor(0, 1);
        lcd_1.print (millis());
  dist = 0.01723 * readUltrasonicDistance(1, 1);
  delay(10);
   
  
   
     if (dist < 100 && ((unsigned long)(currentMillis - previousMillis) >= interval))

  	{
    	digitalWrite(12, HIGH);
 	tone(13, 500, 250);
    		delay(200);
 	tone(13, 600, 250);
    		delay(200);
 	tone(13, 700, 250);
		digitalWrite(12, LOW);
    		delay(200);
  	tone(13, 800, 250);
    		delay(200);
       
     	lcd_1.clear();
  		lcd_1.print("Check Feed Tube");
        lcd_1.setCursor(0, 1);
        lcd_1.print(currentMillis);
  		delay (1000);
       
  
      previousMillis = currentMillis;
       
 		} 
  else 
  		{
   			digitalWrite(13, LOW);
  		}
  
}

Thanks for posting code properly on your first post!

After you have checked for interval expiration, and taken action, you need to update previousMillis as follows:

previousMillis = millis();

All those delays make currentMillis invalid.

millis() represents the time since the Arduino started (was reset). It will only return to 0 when you reset the board.

You should have interval declared as unsigned long.

You have to reset your previousMillis every time you detect something in the field of view.

// C++ code
//
#include <Adafruit_LiquidCrystal.h>

float dist = 0;
unsigned long previousMillis = 0;
const unsgined long interval = 3000;
Adafruit_LiquidCrystal lcd_1(0);

long readUltrasonicDistance(int triggerPin, int echoPin)
{
  pinMode(triggerPin, OUTPUT);  // Clear the trigger
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(2);
  // Sets the trigger pin to HIGH state for 10 microseconds
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin, LOW);
  pinMode(echoPin, INPUT);
  // Reads the echo pin, and returns the sound wave travel time in microseconds
  return pulseIn(echoPin, HIGH);
}

void setup()
{
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
}

void loop()
{
  unsigned long currentMillis = millis();
  lcd_1.begin(16, 2);
  lcd_1.setBacklight(1);
  lcd_1.setCursor(0, 0);
  lcd_1.print("Operational");
  lcd_1.setCursor(0, 1);
  lcd_1.print (millis());
  dist = 0.01723 * readUltrasonicDistance(1, 1);
  delay(10);

  if ( dist >= 100 ) {
    // item in field
    // reset the timer
    previousMillis = currentMillis;
  }
  else {
    // item not in field
    // if it has been absent long enough, signal alarm
    if (currentMillis - previousMillis >= interval) {
      // alarm
      digitalWrite(12, HIGH);
      tone(13, 500, 250);
      delay(200);
      tone(13, 600, 250);
      delay(200);
      tone(13, 700, 250);
      digitalWrite(12, LOW);
      delay(200);
      tone(13, 800, 250);
      delay(200);

      lcd_1.clear();
      lcd_1.print("Check Feed Tube");
      lcd_1.setCursor(0, 1);
      lcd_1.print(currentMillis);
      delay (1000);
      previousMillis = currentMillis;
    }
    else {
      // item not in field, but keep waiting
      digitalWrite(13, LOW);
    }
  }
}

Oh i understand now, thank you very much everyone!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.