Ultrasonic Sensor Trigger When Blocked for a Duration

I’m working on a project which has falling objects non stop into a tray. The goal of my project is to detect when the tray is full and ready to be emptied. When it is full an alarm will sound which indicates the operator. I decided to use a sonar sensor to detect that, however I am running into an issue. When the objects are passing by the sensor they are tripping it and turning on the alarm too quickly. I want it to only detect when the pile reaches the desired height of the sensor. My thoughts were to use a delay or millis to test the inchdistance <= 6 twice. However, when I implement either of those methods the sonar sensor stops reading and on the second condition test it just reads the previous value. Any help or suggestions would be greatly appreciated.

#define trigPin 6 // Connect trigpin to D6 on Arduino
#define echoPin 5 // Connect echopin to D5 on Arduino
#define ledPin A3
#define btnPin 7

// defines variables

long duration; // It's a variable for the duration of sound wave travel
int inchdistance; // It's a variable for measurement of distance in inches
int cmdistance; // It's a variable for measurement of distance in centimeters
int btnState = 0; // Reading status of button
int var = 0;
int varTray = 0;
int trayFull = 0;
int interval;
unsigned long currentMillis = 0;

void setup() {
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an OUTPUT
  pinMode(echoPin, INPUT); // Sets the echoPin as an INPUT
  pinMode(ledPin, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  Serial.begin(9600); // // For Serial Communication
}

void loop() {
  
  digitalWrite(trigPin, LOW); // Clears the trigPin condition
  delayMicroseconds(2); 
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  duration = pulseIn(echoPin, HIGH); // Reads the echoPin, returns the sound wave travel time in microseconds

  // Calculating the distance
  
  inchdistance = duration * 0.0133858 / 2; // To calculate the distance in inch
  cmdistance = duration * 0.034 / 2; // To calculate the distance in cm
  
  // Displays the distance on the Serial Monitor
  
  Serial.print("Distance: ");
  Serial.print(inchdistance);
  Serial.println(" inch");
  Serial.print(cmdistance);
  Serial.println(" cm");

  btnState = digitalRead(btnPin);

//  if(inchdistance <= 6){
//    currentMillis = millis();
//    interval = currentMillis + 2000;
//    while(currentMillis < interval){
//      currentMillis = millis();
//    }
//    varTray = 1;
//  }

  if(inchdistance <= 6){
    delay(5000);
    if(inchdistance <= 6){
    trayFull = 1;      
    }

  }

  if(trayFull == 1 & var == 0){
    var = 1;
    digitalWrite(ledPin, HIGH); 
  }
  else if(btnState == LOW & var == 1){
    digitalWrite(ledPin, LOW);
    var = 0;
    trayFull = 0;
    varTray = 0;
    delay(5000);
  }


  digitalWrite(13, digitalRead(btnPin));
} 

if(trayFull == 1 && var == 0){

Did you want & or && ?
. . .
else if(btnState == LOW && var == 1){

I appreciate the response. I guess && but I don't think that has to do with my problem at hand.

How fast are the objects arriving, how big are they ?


Read the distance 3 or 4 times in a row.

If the same value is read all 3 or 4 times, the tray is full.


A weight value might be better to use :thinking: .

Approx. 2 every second. How would I go about reading the distance multiple times in a row. It seems in the serial monitor that when the <= 6 condition is met the sonar stops reading. Also the tray sits on a gravity conveyor so implementing a scale would be very difficult.

The tray is also approx 300 lbs when full.

I forgot to mention the size ranges from 0.5"x0.5" square sheets to 3"x2" sheets

I'd start by getting a new reading and using that to determine full.

Preferable would be to use millis() timing so the code in non-blocking.

if distance >= 6 reset millis() timer
if distance < 6 stop resetting millis() timer - this allows timer to accumulate
if millis() timer exceeds X milliseconds set full flag

Can these sheets slide down a slide ?

If so, a photo cell could count them as they go by.

When the count reaches a certain value the tray is full. :thinking: .


Or for your present sensor.

Every time the distance is measured, if this distance is different than the last, reset a counter.

If the distance is the same as the last distance, increment the counter.

If the counter ever reaches a predetermined value i.e. 3 or 4, the tray is full.

It's easier to fix something you know about than something unknown. There is some chance that the known thing is the same as the unknown thing. So we always fix the known problems first.

I really like your idea of using the millis() timer. However I am having a little trouble converting your pseudocode into something that will work. Would you mind typing a skeleton code of this idea.

Have you researched non-blocking code yet? You need to look at some examples and tutorials, there are some links in the forum guides.

You are giving up before you even try. It's easier than you believe. For example:

if distance >= 6 reset millis() timer
// becomes
if (distance >= 6) timer = millis();

It's not impossible or really difficult to learn C. We all had to do it.

You're right :man_facepalming:

I got it working. Thank you all for your help.