Smart underground garbage container prototype for Arduino UNO Q. This repo combines:
- MCU firmware in
sketch/for sensor sampling, fill estimation, flame detection, and status LEDs - A Linux-side Python runtime in
python/that talks to the MCU throughBridge, runs camera inference, and syncs with a backend API - A backend payload contract in
smart_garbage_container_api_spec.md
The current app uses the video_objectdetection brick to detect the trash class, merges that with physical sensor data, and reports telemetry and events such as GARBAGE_DETECTED and GARBAGE_CLEARED.
- Reads temperature and humidity from a Modulino Thermo
- Reads a simulated load value
- Reads distance from an ultrasonic sensor to estimate fill level
- Reads a KY-026 flame sensor on
A2 - Fuses ultrasonic + weight inputs into a fill percentage and fill state
- Drives an RGB status LED based on fill state, flame state, and faults
- Polls the MCU from Linux using
Arduino_RouterBridge - Runs vision inference with
VideoObjectDetection - Queues telemetry, heartbeat, config acknowledgements, and events for backend upload
- Persists identity/config and an offline outbox locally
Sensors + LED <-> Arduino UNO Q firmware <-> Bridge <-> Python runtime
|
+-> VideoObjectDetection
|
+-> REST backend API
The firmware in sketch/sketch.ino samples sensors, computes fill state, tracks health, and exposes bridge methods such as:
get_sensor_sample()get_health()set_fill_calibration(...)set_flame_threshold_pct(...)set_simulated_mode(...)set_rgb_state(...)
More wiring and firmware details are in sketch/README.md.
The runtime in python/main.py is responsible for:
- bootstrapping the device with the backend using a claim code
- polling the MCU every 500 ms for compact sensor snapshots
- batching telemetry and queueing heartbeats
- pulling remote config revisions
- detecting stationary trash in camera frames
- creating
GARBAGE_DETECTEDandGARBAGE_CLEAREDevents - uploading event images when enabled
- retrying failed uploads from a persistent outbox
Persistent local files:
python/device_state.json: saved identity, token, config revision, and configpython/device_outbox.json: queued messages for offline retry
Required hardware for the current prototype:
- Arduino UNO Q
- Modulino Thermo
- Modulino Light
- Ultrasonic sensor
- KY-026 flame sensor
- Potentiometer on
A0for load simulation - RGB LED
- USB camera for vision inference
Key wiring from the firmware docs:
| Component | Pin |
|---|---|
Flame sensor AO |
A1 |
Ultrasonic TRIG |
D2 |
Ultrasonic ECHO |
D7 |
| RGB LED red | D3 |
| RGB LED green | D5 |
| RGB LED blue | D6 |
| Modulino devices | Wire1 / Modulino bus |
app.yaml Arduino App Lab app definition
python/main.py Linux-side runtime and backend sync
sketch/sketch.ino MCU firmware entrypoint
sketch/bridge/ Bridge API exposed by the MCU
sketch/sensors/ Sensor drivers
sketch/logic/ Fill estimation, health, calibration
sketch/output/ RGB LED behavior
smart_garbage_container_api_spec.md
- Open the project in Arduino App Lab.
- Target Arduino UNO Q.
- Keep
sketch/sketch.yamlas the active sketch profile. - Make sure the USB camera is available to the Linux-side app runtime.
- Run the app.
The sketch profile currently depends on:
Arduino_RouterBridgeArduino_Modulino
The Python runtime loads environment variables from .env if present.
Minimum useful variables:
SMART_WASTE_API_BASE_URL=http://your-backend-host:8080
SMART_WASTE_CLAIM_CODE=YOUR-CLAIM-CODEUseful optional variables:
SMART_WASTE_MODEL_IDSMART_WASTE_LINUX_APP_VERSIONSMART_WASTE_MCU_VERSIONSMART_WASTE_CAMERA_FAULT_TIMEOUT_SECSMART_WASTE_SAVE_MCU_CALIBRATIONSMART_WASTE_GARBAGE_STALE_CLEAR_SEC
If SMART_WASTE_API_BASE_URL or SMART_WASTE_CLAIM_CODE is missing, the app still runs locally but skips backend bootstrap and sync.
On startup, the Python runtime can:
POST /api/v1/device/bootstrap- persist the returned
device_id,container_id, token, and config - queue periodic telemetry to
/api/v1/device/telemetry - queue heartbeats to
/api/v1/device/heartbeat - poll
/api/v1/device/config - post events to
/api/v1/device/events - upload event media to
/api/v1/device/events/{event_id}/media
The full contract lives in smart_garbage_container_api_spec.md.
The camera side does more than simple one-frame detection:
- it looks for the
trashclass - keeps a rolling window of detections
- requires a configurable number of positive frames
- checks whether the detected object is stationary
- clears stale detections when the scene returns to normal
This helps reduce false positives from brief motion near the container.
light_raw_adcis kept in payloads for compatibility even though the source is the Modulino light reading.- Event image upload is optional and controlled by config.