Software
Programming of GARB
Sensing
We opted to use an Ultrasonic sensor to determine when GARB was full. The detection was done by finding the average fullness across one second (20 samples) and comparing it to the threshold that we set. Alternatively, it would also exit the loop if the lid button is pressed.
Code
# Trash can Dimensions
bin_height = 76 # Height from Lid to Bottom of Trash (cm)
trigger_height = 61 # Height from Bottom of Trash to Trigger Point (cm)
# Ultrasonic Sensor Settings
close_enuf = bin_height - trigger_height # Calibrate
avg_distance = 76
# Fullness Detection Loop
print("Detecting Height and Button Press")
while avg_distance >= close_enuf:
distances = []
d_sum = 0
for k in range(20):
# open_close = lid_button.value()
open_close = 1
time.sleep(0.05)
if open_close == 1:
distance = sensor.distance_cm()
else:
distance = bin_height
if distance > bin_height:
distance = bin_height
distances.append(distance)
d_sum += distances[k]
avg_distance = round(d_sum/20, 1)
print(avg_distance)
status = user_button.value()
if status == 1:
avg_distance = close_enuf - 1Actuation and Communication
Once the sensors determined that GARB was full, we would move on to the sealing procedure.
Actuation
GARB has two main actuation operations: Tightening and Releasing. Both of these involve the use of the servo.
Communication
Upon the tightening finishing up on GARB, it sends a text to the owner via MQTT. Although MQTT is slow and not as secure as other communication methods, it is more than enough for a product like GARB. Other communication methods like Bluetooth also require the owner to be nearby.
Code
# Servo Tightening Procedure
print("Begin Twisting Procedure")
S.duty(counter_clockwise)
# Can ramp the duty between the time frames to get a more smooth rotation
time.sleep(5) # Let the Servo Fully Twist
S.duty(rest) # Stop Servo
# Completion
# mqtt.publish(feedName_done, sendDone)
print("Waiting for Button Press")
status = user_button.value()
while status == 0:
status = user_button.value()
print("Button has Been Pressed")
# Reverse Servo
S.duty(clockwise)
time.sleep(5) # Need to calibrate
S.duty(rest)
status = 0
avg_distance = 76Full Code
Code
import network
import time
from mqttclient import MQTTClient
from hcsr04 import HCSR04
from machine import Pin, PWM
from network import WLAN, STA_IF, mDNS
from board import SDA, SCL
# Connect to WiFi
'''
wlan = WLAN(STA_IF)
wlan.active(True)
wlan.connect('ME100-2.4G', '122Hesse', 5000)
while not wlan.isconnected():
print("Waiting for wlan connection")
time.sleep(1)
if wlan.isconnected():
print("WiFi connected at", wlan.ifconfig()[0])
else:
print("Unable to connect to WiFi")
# Advertise as 'hostname'
try:
hostname = "GARBO_ESP32"
mdns = mDNS(wlan)
# mdns.start(hostname, "MicroPython REPL")
# mdns.addService('_repl', '_tcp', 23, hostname)
mdns.start(hostname,"MicroPython with mDNS")
_ = mdns.addService('_ftp', '_tcp', 21, "MicroPython", {"board": "ESP32", "service": "my_hostname FTP File transfer", "passive": "True"})
_ = mdns.addService('_telnet', '_tcp', 23, "MicroPython", {"board": "ESP32", "service": "my_hostname Telnet REPL"})
_ = mdns.addService('_http', '_tcp', 80, "MicroPython", {"board": "ESP32", "service": "my_hostname Web server"})
print("Advertised locally as {}.local".format(hostname))
except OSError:
print("Failed starting mDNS server - already started?")
# start telnet server for remote login
from network import telnet
print("start telnet server")
telnet.start(user='GARBO_esp32', password='astm')
# fetch NTP time
from machine import RTC
print("inquire RTC time")
rtc = RTC()
rtc.ntp_sync(server="pool.ntp.org")
timeout = 10
while True:
if rtc.synced():
break
print("Waiting for rtc time")
time.sleep(1)
if rtc.synced():
print(time.strftime("%c", time.localtime()))
else:
print("could not get NTP time")
'''
# Set up Adafruit connection
adafruitIoUrl = 'io.adafruit.com'
adafruitUsername = 'chrisx'
adafruitAioKey = 'aio_KtmR98ivJWkH9FizfmF2fu0Pesxz'
'''
# Connect to Adafruit server
print("Connecting to Adafruit")
mqtt = MQTTClient(adafruitIoUrl, port='1883', user=adafruitUsername, password=adafruitAioKey)
time.sleep(0.5)
print("Connected!")
# Adafruit Feed
feedName_done = "chrisx/feeds/done-cooking"
sendDone = "done"
'''
# Trash can Dimensions
bin_height = 76 # Height from Lid to Bottom of Trash (cm)
trigger_height = 61 # Height from Bottom of Trash to Trigger Point (cm)
# Servo Settings
rest = 1.5/20 * 100 # [1.5ms pulsewidth / 20ms]
clockwise = 2/20 * 100 # [2ms pulsewidth / 20ms]
counter_clockwise = 1/20 * 100 # [1 ms pulsewidth / 20ms]
# Ultrasonic Sensor Settings
close_enuf = bin_height - trigger_height # Calibrate
avg_distance = 76
# Initialize Objects
sensor = HCSR04(trigger_pin=22, echo_pin=23,echo_timeout_us=1000000) # Ultrasonic Sensor
user_button = Pin(15, mode=Pin.IN) # User Button
lid_button = Pin(14, mode=Pin.IN) # Lid Sensor Button
S = PWM(Pin(27), freq=50, duty=rest) # Servo
while True:
# Fullness Detection Loop
print("Detecting Height and Button Press")
while avg_distance >= close_enuf:
distances = []
d_sum = 0
for k in range(20):
# open_close = lid_button.value()
open_close = 1
time.sleep(0.05)
if open_close == 1:
distance = sensor.distance_cm()
else:
distance = bin_height
if distance > bin_height:
distance = bin_height
distances.append(distance)
d_sum += distances[k]
avg_distance = round(d_sum/20, 1)
print(avg_distance)
status = user_button.value()
if status == 1:
avg_distance = close_enuf - 1
# Servo Tightening Procedure
print("Begin Twisting Procedure")
S.duty(counter_clockwise)
# Can ramp the duty between the time frames to get a more smooth rotation
time.sleep(5) # Let the Servo Fully Twist
S.duty(rest) # Stop Servo
# Completion
# mqtt.publish(feedName_done, sendDone)
print("Waiting for Button Press")
status = user_button.value()
while status == 0:
status = user_button.value()
print("Button has Been Pressed")
# Reverse Servo
S.duty(clockwise)
time.sleep(5) # Need to calibrate
S.duty(rest)
status = 0
avg_distance = 76Last updated