Interactions with interval powered by ultrasonic sensor

Hello everyone,

For a school project I’m working on a waste bin that wil detect garbage going in. To detect the pieces I’m using an ultrasonic sensor which is working very well.

The thing is, I want led strips to respond to garbage falling in the bin, but not all at once. At the moment there are 3 LED lights linked, and when something is passing the sensor withing 55cm they will light up.

I’d really like to have the LED’s light up one by one, each time something is thrown in. It’s probably necessary to turn off the sensor temporarily after something is detected because there will be too many readings from one object falling in.

The code i have right now is:

#define ECHOPIN 13        // Pin to receive echo pulse 
#define TRIGPIN 12        // Pin to send trigger pulse
#define LEDGREEN 3        // Pin to power green led
#define LEDRED 4          // Pin to power red led
#define LEDYELLOW 5       // Pin to power yellow led

float distance=0;

void setup() 
{ 
  Serial.begin(9600); 
  pinMode(ECHOPIN, INPUT); 
  pinMode(TRIGPIN, OUTPUT); 
  pinMode(LEDGREEN, OUTPUT);
  pinMode(LEDRED, OUTPUT);
  pinMode(LEDYELLOW, OUTPUT);
}
void loop() 
{ 
 
  // Start Ranging -Generating a trigger of 10us burst 
  digitalWrite(TRIGPIN, LOW); 
  delayMicroseconds(2); 
  digitalWrite(TRIGPIN, HIGH); 
  delayMicroseconds(10); 
  digitalWrite(TRIGPIN, LOW);
  // Distance Calculation
  
  distance = pulseIn(ECHOPIN, HIGH); 
  distance= distance/58; 

  Serial.print(distance); 
  Serial.println(" cm");
  delay(20); 

   if (distance <= 55) {
  digitalWrite(LEDGREEN, HIGH);
  digitalWrite(LEDRED, HIGH);
  digitalWrite(LEDYELLOW, HIGH);
 }
}

Is there anyone who can assist me, or guide me to the right direction?

Thanks in advance,

Maarten

Maartenrad:
I’d really like to have the LED’s light up one by one, each time something is thrown in. It’s probably necessary to turn off the sensor temporarily after something is detected because there will be too many readings from one object falling in.

could you be a little clearer?

“I’d really like to have the LED’s light up one by one,…”

what do you mean by by that? do you want them to light up is sequence every time for example? if so what pattern/timing you looking for between each LED operation?

Ofcourse, no problem. I see now that my question is a bit vague.

What I would like to happen, is that every time something is being thrown in a new light lights up whilst the other one/ones that are already on, stay on.

So a scenario would be:

  • All lights off
  • Somebody throws in trash
  • LED1 turns on (stays on)
  • Somebody throws in trash
  • LED 2 turns on (Now both LED1 and LED2 are on)
  • Somebody throws in trash
  • LED 3 turns on (Now all LEDS are on)
  • All leds turn off after 60 seconds

Does that make more sense?

Does that make more sense?

Some. But, what happens after 60 seconds? Someone throws trash in. How many lights should be turned on? Suppose that 8 lights were on, and were turned off after 60 seconds. The next piece of trash triggers one light or nine?

You are measuring distance, but it is not clear what the distance is to. If it is the distance to the piece of trash, then the distance decreases as the piece of trash gets closer, and then increases again as the piece of trash moves away.

You need to determine when the state changes (the distance stops decreasing and starts increasing), rather than what the actual value is. Count the state changes. Light LEDs as appropriate.

Maartenrad:
Ofcourse, no problem. I see now that my question is a bit vague.

What I would like to happen, is that every time something is being thrown in a new light lights up whilst the other one/ones that are already on, stay on.

So a scenario would be:

  • All lights off
  • Somebody throws in trash
  • LED1 turns on (stays on)
  • Somebody throws in trash
  • LED 2 turns on (Now both LED1 and LED2 are on)
  • Somebody throws in trash
  • LED 3 turns on (Now all LEDS are on)
  • All leds turn off after 60 seconds

Does that make more sense?

though is does make sense in some way, it does not really!

so following your sequence, the LEDs reset every 3 throws! is there really a point to doing that I wonder....

Following on what PaulS suggested, to me, a more practical aspect of using those LEDs would be for them to light up as the bin filled up.

but in any case what your sequence is NOT impossible to achieve.

If I may ask again, please let us know if that is indeed the sequence you wish to implement

After 60 seconds I would like the whole program to reset. So start back from 0. The point with the 3 leds is an interaction that needs to be showed when somebody correctly disposes of litter. Not to show how full the trashcan is. The current code is:

#define ECHOPIN 13        // Pin to receive echo pulse 
#define TRIGPIN 12        // Pin to send trigger pulse


float distance=0;

int leds[]= {3,4,5};

void setup() 
{ 
  Serial.begin(9600); 
  pinMode(ECHOPIN, INPUT); 
  pinMode(TRIGPIN, OUTPUT); 
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
}
void loop() 
{ 
  for(int a = 0 ; a < 3; a++){
 
  // Start Ranging -Generating a trigger of 10us burst 
  digitalWrite(TRIGPIN, LOW); 
  delayMicroseconds(2); 
  digitalWrite(TRIGPIN, HIGH); 
  delayMicroseconds(10); 
  digitalWrite(TRIGPIN, LOW);
  // Distance Calculation
  
  distance = pulseIn(ECHOPIN, HIGH); 
  distance= distance/58; 
/* The speed of sound is 340 m/s or 29 us per cm.The Ultrasonic burst travels out & back.So to find the distance of object we divide by 58  */
  Serial.print(distance); 
  Serial.println(" cm");
  delay(20); 
  
   if (distance <= 30) {
    digitalWrite(leds[a], HIGH);
    delay(1000);
    }
 }
}

The leds somehow turn on, and stay on, one after another when the sensor is exposed to multiple readings. This is the point, but I would like the LEDs to turn on in the order I want them to. So 3, 4, 5. Is there any way to get this to work?

Also, we’ve noticed that the for(int a = 0 ; a < 3; a++) makes the whole loop change one by one and lets different LEDs light up depending on the time that has passed because of the delay. That’s currently the issue we’d like to solve. That the lights turn on in the order we want them to.

  for(int a = 0 ; a < 3; a++){

What is the point of the for loop? You need to count how many times the sensor registers a “valid” value.

what about something like this (untested!):

#define ECHOPIN 13        // Pin to receive echo pulse 
#define TRIGPIN 12        // Pin to send trigger pulse


float distance=0;
uint8_t leds[] = {3,4,5};
uint8_t a = 0;
unsigned long oldtime;

void setup() 
{ 
  Serial.begin(9600); 
  pinMode(ECHOPIN, INPUT); 
  pinMode(TRIGPIN, OUTPUT); 
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  
  oldtime = millis();
}
void loop() 
{  
  // Start Ranging -Generating a trigger of 10us burst 
  digitalWrite(TRIGPIN, LOW); 
  delayMicroseconds(2); 
  digitalWrite(TRIGPIN, HIGH); 
  delayMicroseconds(10); 
  digitalWrite(TRIGPIN, LOW);
  // Distance Calculation
  
  distance = pulseIn(ECHOPIN, HIGH); 
  distance = distance/58; 
  
   if (distance <= 30) {
     oldtime = millis();
    digitalWrite(leds[a++], HIGH);
    /* The speed of sound is 340 m/s or 29 us per cm.The Ultrasonic burst travels out & back.So to 
find the distance of object we divide by 58  */
    Serial.print(distance); 
    Serial.println(" cm");
 
    if(a == 3) a = 0;
  }
  
  if(millis() - oldtime > 60000){ //reset LEDs after 60s
    digitalWrite(leds[0], LOW);
    digitalWrite(leds[1], LOW);
    digitalWrite(leds[2], LOW);
  }
}

Thanks a lot! This totally works! There's only one problem now. The Sensor we're using "senses" every 10 milliseconds because of fast objects falling in front of it. This way, only one object could trigger all 3 of the LEDs with one passing. Is there anywhere in the code where we could build in some kind of a delay so the sensor would not read for 1 or 2 seconds to avoid "false" readings?

EDIT:

We've put a delay behind the digitalWrite(leds[a++], HIGH); and it seems to work as intended. You're a lifesaver.

so the sensor would not read for 1 or 2 seconds to avoid "false" readings?

You can't make the sensor not read. What you can do is to not make the sensor send pulses, so that there are no echoes to read. But, that is the wrong approach. You need to re-read reply #3. You need to determine when the distance changes, so you count an object only once, when the distance decreases (as the trash gets closer) and then increases (as the trash gets farther away).