Evan Thompson
Published © MIT

Lane Tech PCL - Trash Containment Unit

A trash can lid that seals the garbage from the rest of the world.

IntermediateShowcase (no instructions)7 hours68
Lane Tech PCL - Trash Containment Unit

Things used in this project

Hardware components

Argon
Particle Argon
×1
Solderless Breadboard Half Size
Solderless Breadboard Half Size
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×2
High Performance Servo
×1
5 mm LED: Red
5 mm LED: Red
×1
5 mm LED: Yellow
5 mm LED: Yellow
×2
5 mm LED: Green
5 mm LED: Green
×2

Software apps and online services

Particle Build Web IDE
Particle Build Web IDE

Story

Read more

Code

Trash Can Source Code

C/C++
The source code for the trash can's argon built using the Particle IDE.
#define entryTrigPin 2
#define entryEchoPin 3
#define fillTrigPin 7
#define fillEchoPin 6
#define greenLed1 9
#define greenLed2 10
#define yellowLed1 11
#define yellowLed2 12
#define redLed 13
#define servoData 5

#define fillLevel0 25 // The first threshold that determines when the can starts to qualify as 'filled'
#define fillLevel1 20
#define fillLevel2 15
#define fillLevel3 10
#define fillLevel4 5 // The threshold that determines the most filled the can is allowed to get

#define microsecondsPerSecond 1000000 

Servo lidServo;

bool lidOpen = false;
int fillLevel = 0; // The distance (in cm) between the contents of the trash can and the lid
bool sensorState = false; // false: idle, true: sending
uint64_t lastTime = 0; // Timekeeping variable

void setup()
{
    pinMode(entryTrigPin, OUTPUT);
    pinMode(entryEchoPin, INPUT);
    pinMode(fillTrigPin, OUTPUT);
    pinMode(fillEchoPin, INPUT);
    
    pinMode(greenLed1, OUTPUT);
    pinMode(greenLed2, OUTPUT);
    pinMode(yellowLed1, OUTPUT);
    pinMode(yellowLed2, OUTPUT);
    pinMode(redLed, OUTPUT);
    
    lidServo.attach(servoData);
}

void loop()
{
    // Get and store the current time in microseconds
    uint64_t currentTime = micros();
    
    // If the sensor state is set to idle and the time elapsed since the last sensor
    // pulse is at least one second, begin another sensor pulse
    if (!sensorState && currentTime - lastTime >= microsecondsPerSecond)
    {
        // Trigger both ultrasonic sensors
        digitalWrite(entryTrigPin, HIGH);
        digitalWrite(fillTrigPin, HIGH);
        
        // Update state
        sendingState = true;
        lastTime = currentTime;
    }
    
    // Otherwise if the sensor state is set to sending and 10 microseconds has been
    // elapsed, start listening for the returning ultrasonic waves
    else if (sensorState && currentTime - lastTime >= 10)
    {
        long duration, distance;
        
        // Stop triggering the lid sensor
        digitalWrite(entryTrigPin, LOW);
        
        // Measure the duration of the return wave
        duration = pulseIn(entryEchoPin, HIGH);
        
        // Do some math with the speed of sound to get the distance (in cm) to the detected object 
        distance = (duration / 2) / 29.1;
        
        // Open the lid if the distance is less than 11 cm
        lidOpen = distance < 11;
        
        // Stop triggering the fill sensor
        digitalWrite(fillTrigPin, LOW);
        
        // Measure the duration of the return wave
        duration = pulseIn(fillEchoPin, HIGH);
        
        // Do some math with the speed of sound to get the distance (in cm) to the can contents
        distance = (duration / 2) / 29.1;
        
        // Set the fill level to that distance
        fillLevel = distance;
        
        // Update state
        sensorState = false;
        lastTime = currentTime;
    }

    // Turn on the fill level LEDs based on the measured distance from the bottom
    // ultrasonic sensor. As the trash can fills up, the distance (in cm) will decrease.
    // Here we assign the LEDs to arbitrary fill values based on the height of my trash
    // can (about 1 ft)
    digitalWrite(greenLed1, fillLevel < fillLevel0 ? HIGH : LOW);
    digitalWrite(greenLed2, fillLevel < fillLevel1 ? HIGH : LOW);
    digitalWrite(yellowLed1, fillLevel < fillLevel2 ? HIGH : LOW);
    digitalWrite(yellowLed2, fillLevel < fillLevel3 ? HIGH : LOW);
    digitalWrite(redLed, fillLevel < fillLevel4 ? HIGH : LOW);
    
    // Rotate the servo to match the lidOpen state. The servo will only rotate open
    // if the fill level does not exceed the lowest threshold (not too full)
    lidServo.write(lidOpen && fillLevel >= fillLevel4 ? 50 : 140);
}

Credits

Evan Thompson

Evan Thompson

1 project • 0 followers

Comments

Add projectSign up / Login