Trash Monitoring System
by yohanes tulangow in Circuits > Microcontrollers
257 Views, 1 Favorites, 0 Comments
Trash Monitoring System
Group members:
- Dhil Khairan Dadjiser - 2440089251
- Bintang R.S.K Radja Pono - 2440030065
- Yohanes Tulangow - 2440097902
Description:
Trash Monitoring System is a device that can monitors the capacity and location of trash cans through an app.
This device can solve some problems:
- waste time, user need to check the fill levels bin periodically.
- Overflowing bins significantly pollute the environment.
- Garbage collectors don't know the effective routes and the areas in which bins are.
So, to overcome the problems we build a device called Trash Monitoring System that can monitor the capacity, location, and status of the bins through the smartphone.
The advantages of our device are:
- Time saving,
- Sustainability,
- Improved efficiency,
- Transparency, and
- Data analystics.
Theory of main components and software:
Ultrasonic Sensor (HC-SR04)
Is a sensor that can calculate the distance of an object by emitting ultrasonic sound waves which will be reflected by the object and then the waves return to the sensor. It's ideal to calculate the distance from device to the bottom of the bins. If the distance between device and the bottom of bin are as far as the height of the bin, the capacity of bin considered empty. And if the distance between device and bin's bottom are further close, then the capacity of bin is increasing.
GPS Module (Neo 6m)
The NEO 6M GPS module is a GPS module with the ability to identify locations with the help of satellites. We use GPS to monitor and know where the bins are.
Microcontroller (Esp 32 Dev KIT Doit)
ESP32 is the brain of this tool, which features Analog and Digital input/output, PWM, SPI, I2C, etc. ESP32 controls all components and software are used to.
Firebase (Realtime Database)
The Firebase Realtime Database is a cloud-hosted NoSQL database that let us store and sync data between users in real time. We use this cloud database to receive data from the devices and store the data to app.
Flutter
Flutter is Google's open-source framework for building beautiful, natively compiled, multi-platform applications from a single code base. We use flutter to make an app to received data from the firebase that is gotten by the hardware device.
Supplies
Components are:
- 1 microcontroller (ESP32)
- 1 GPS Module (Neo 6m)
- 1 ultrasonic sensor (HC-SR04)
- 1 step up module (MT3608)
- 1 charging module
- 1 battery socket
- 2 battery li-ion
- PCB
- Jumper
- Screw
- Trash bin
PCB Making
PCB:
Determine the circuit you want and make a schematic on easyeda. When the schematic is finished convert it to PCB using easyeda than determine the arrangement of the components on the PCB and make the paths.
Component Soldering
solder all components according to the schematic that has been made. It is highly recommended to try the circuit first on the breadboard before soldering it.
3D Design and Printing
3D design:
The design is divided into three main parts, namely the main body, cover and docking. The design that is made is expected to achieve the following things:
- Can put main board and battery properly.
- Provides inlet and battery cover to allow users to change batteries.
- Provides holes for ultrasonic sensors, charging ports, and switch placement.
- Allows the device to be removed from the trash can.
3D Printing:
After the design has been made, the next step is to print the design. In this project the design will be printed using a 3d printer so the design file must be exported to a ".stl" file first. When printing, you need to pay attention to several things, such as room conditions and printer settings in order to get maximum results.
Setup Hardware Source Code With Platformio
In this project we are coding the esp32 using platformio in visual studio code. The goal is to calculate the distance from the device to the bottom of the trash can using an ultrasonic sensor, send device position (longitude & latitude) using the gps module, and connect the esp32 to the internet. The code is given bellow:
#include <Arduino.h>
#include <TinyGPSPlus.h>
#include <Wire.h>
#include <math.h>
#include <WiFiManager.h>
TinyGPSPlus gps;
const int trigPin = 4;
const int echoPin = 2;
//define sound speed in cm/uS
#define SOUND_SPEED 0.0343
long duration;
float distance;
String latitude;
String longitude;
bool gpsconection;
const char* ssid;
const char* pass;
void WifiConnect();
void WifiConnect()
{
WiFi.mode(WIFI_STA);
WiFiManager wm;
wm.resetSettings();
bool res;
res = wm.autoConnect("SPE_Kelompok_4","password");
if(!res) {
Serial.println("Failed to connect");
// ESP.restart();
}
else {
//if you get here you have connected to the WiFi
Serial.println("Sucses to connect");
}
ssid = WiFi.SSID().c_str();
pass = WiFi.psk().c_str();
}
void GPSInfo()
{
Serial.print(F("Location: "));
float la= (gps.location.lat());
float lo= (gps.location.lng());
latitude = String(la, 6);
longitude = String (lo, 6);
if (gps.location.isValid()){
gpsconection = true;
Serial.print("Lat: ");
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print("Lng: ");
Serial.print(gps.location.lng(), 6);
Serial.println();
}
else
{
gpsconection = false;
Serial.println(F("INVALID"));
latitude = "-6.200234";
longitude = "106.785496";
}
}
void updateSerial()
{
delay(500);
while (Serial.available())
{
Serial2.write(Serial.read());//Forward what Serial received to Software Serial Port
}
while (Serial2.available())
{
Serial.write(Serial2.read());//Forward what Software Serial received to Serial Port
}
}
void distanceCalculator()
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculate the distance
distance = duration * SOUND_SPEED/2;
distance = floor( distance);
// Prints the distance in the Serial Monitor
Serial.print("Distance (cm): ");
Serial.println(distance);
Serial.println();
}
Setup Firebase
In this project all data is stored in Firebase. In other words, the firabse becomes the link between the device and the app. The firebase used in this project is a firebase real time database. Here is the guide link for setting up firebase:
https://www.youtube.com/watch?v=pP7quzFmWBY
https://firebase.google.com/docs/database/flutter/start?hl=en
Flutter Coding [Device Details Page]
The following code shows how to parse the data from firebase. The data that is parsed here are distanceData, latitudeData, and longitudeData. Then, the latitudeData and longitudeData is displayed using normal text in a container. For the distanceData, it will be inputted to the percent widget to show the percentage. Lastly, the the slider in the page is for determining the height of the trashbin.
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:final_trashbin/widgets/percentWidget.dart';
import 'package:final_trashbin/buttons/trackButton_detailsPage.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:percent_indicator/circular_percent_indicator.dart';
class deviceDetailsPage extends StatefulWidget {
const deviceDetailsPage({Key? key}) : super(key: key);
@override
State<deviceDetailsPage> createState() => _deviceDetailsPageState();
}
class _deviceDetailsPageState extends State<deviceDetailsPage> {
late DatabaseReference _dbref;
String distanceData = '';
String latitudeData = '';
String longitudeData = '';
final TextEditingController heightController = TextEditingController();
late var distance = (double.parse(distanceData)).roundToDouble();
late var latitude = double.parse(latitudeData);
late var longitude = double.parse(longitudeData);
late var trashbinHeight = int.parse(heightController.text);
double _value = 30;
late double percentVariable = ((_value - distance) / _value);
late var percentText = (percentVariable * 100);
_getDistance() {
_dbref
.child("EC:62:60:A1:A1:6C")
.child("Distance(CM)")
.onValue
.listen((DatabaseEvent databaseEvent) {
setState(() {
distanceData = databaseEvent.snapshot.value.toString();
print(databaseEvent.snapshot.value.toString());
});
});
}
_getLat() {
_dbref
.child("EC:62:60:A1:A1:6C")
.child("Location")
.child("Lat")
.onValue
.listen((DatabaseEvent databaseEvent) {
setState(() {
latitudeData = databaseEvent.snapshot.value.toString();
print(databaseEvent.snapshot.value.toString());
});
});
}
_getLong() {
_dbref
.child("EC:62:60:A1:A1:6C")
.child("Location")
.child("Lng")
.onValue
.listen((DatabaseEvent databaseEvent) {
setState(() {
longitudeData = databaseEvent.snapshot.value.toString();
print(databaseEvent.snapshot.value.toString());
});
});
}
@override
void initState() {
super.initState();
_dbref = FirebaseDatabase.instance.ref();
_getDistance();
_getLat();
_getLong();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
children: [
Text(
"Device 1",
style: GoogleFonts.manrope(
fontSize: 40,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 42, 97, 68)),
),
Container(
margin: EdgeInsets.only(top: 25, bottom: 30),
child: CircularPercentIndicator(
animation: true,
animationDuration: 1000,
radius: 300,
lineWidth: 28,
percent: distance > _value
? percentVariable = 0.0
: percentVariable = percentVariable,
progressColor: Colors.greenAccent,
backgroundColor: Color.fromARGB(255, 155, 251, 183),
circularStrokeCap: CircularStrokeCap.round,
center: distance > _value
? Text(
'Error',
style: GoogleFonts.manrope(
fontSize: 58,
fontWeight: FontWeight.w500,
),
)
: Text(
'$percentText%',
style: GoogleFonts.manrope(
fontSize: 58,
fontWeight: FontWeight.w500,
),
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Container(
height: 100,
width: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(28),
),
color: Colors.greenAccent,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Latitude: $latitude",
style: GoogleFonts.manrope(
color: Colors.white,
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
Text(
'Longitude: $longitude',
style: GoogleFonts.manrope(
color: Colors.white,
fontSize: 25,
fontWeight: FontWeight.bold,
),
)
],
),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Container(
height: 50,
width: 300,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(28),
),
color: Color(0xff279152),
),
child: Center(
child: Slider(
min: 20,
max: 200,
value: _value,
onChanged: (value) {
setState(() {
_value = value;
});
},
),
),
),
),
trackWidget(context),
],
),
),
),
);
}
}
Flutter Coding [Tracking]
The following code is for parsing the latitudeData and longitudeData from database. Then the data will be inputted into the Google Maps widget to show the location of the device.
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cupertino_icons/cupertino_icons.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:firebase_database/firebase_database.dart';
class googleMaps extends StatefulWidget {
const googleMaps({Key? key}) : super(key: key);
@override
State<googleMaps> createState() => googleMapsState();
}
class googleMapsState extends State<googleMaps> {
late DatabaseReference _dbref;
double rawLatitudeData = 1;
double rawLongitudeData = 1;
late var latitudeLongitude = LatLng(rawLatitudeData, rawLongitudeData);
late CameraPosition _deviceLoc = CameraPosition(
bearing: 192.8334901395799,
target: latitudeLongitude,
zoom: 18,
);
final Completer<GoogleMapController> _controller =
Completer<GoogleMapController>();
_getLat() async {
_dbref
.child("EC:62:60:A1:A1:6C")
.child("Location")
.child("Lat")
.onValue
.listen((DatabaseEvent databaseEvent) {
setState(() {
rawLatitudeData = double.parse(databaseEvent.snapshot.value.toString());
latitudeLongitude = LatLng(rawLatitudeData, rawLongitudeData);
_deviceLoc = CameraPosition(
bearing: 192.8334901395799,
target: latitudeLongitude,
zoom: 18,
);
print(rawLatitudeData);
});
});
}
_getLong() async {
_dbref
.child("EC:62:60:A1:A1:6C")
.child("Location")
.child("Lng")
.onValue
.listen((DatabaseEvent databaseEvent) {
setState(() {
rawLongitudeData =
double.parse(databaseEvent.snapshot.value.toString());
latitudeLongitude = LatLng(rawLatitudeData, rawLongitudeData);
_deviceLoc = CameraPosition(
bearing: 192.8334901395799,
target: latitudeLongitude,
zoom: 18,
);
print(rawLongitudeData);
});
});
}
@override
void initState() {
_dbref = FirebaseDatabase.instance.ref();
// _getLatLong();
_getLat();
_getLong();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: GoogleMap(
mapType: MapType.terrain,
initialCameraPosition: _deviceLoc,
myLocationButtonEnabled: false,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
markers: {
Marker(
markerId: MarkerId("device 1"),
position: LatLng(-6.200234, 106.785496),
),
},
),
floatingActionButton: FloatingActionButton.extended(
onPressed: _trackDevice,
label: const Text('Your Device'),
icon: const Icon(CupertinoIcons.delete_simple),
backgroundColor: Colors.green,
),
);
}
Future<void> _trackDevice() async {
final GoogleMapController controller = await _controller.future;
controller.animateCamera(CameraUpdate.newCameraPosition(
CameraPosition(
bearing: 190, target: LatLng(-6.200234, 106.785496), zoom: 18),
));
}
}
Conclusions
Trash Monitoring System is a device that can monitors the capacity and location of trash cans through an app with firebase realtime database to be cloud database.
Video link: https://drive.google.com/drive/folders/1k-UrukZeDg19jihxviHTuHRXoyp4jbKc?usp=sharing
Note: this instructable does not provide the entire code, but only the main function code