ARDUINO CODE:
#include <Servo.h>
Servo servoBio; // Servo for biodegradable bin
Servo servoNonBio; // Servo for non-biodegradable bin
String inputString = "";
unsigned long lastActionTime = 0; // cooldown timer
const unsigned long cooldown = 1500; // 1.5 sec between actions
void setup() {
Serial.begin(9600);
servoBio.attach(9); // Biodegradable servo
servoNonBio.attach(10); // Non-biodegradable servo
servoBio.write(0);
servoNonBio.write(0);
Serial.println("Arduino ready");
}
void loop() {
if (Serial.available() > 0) {
inputString = Serial.readStringUntil('\n');
inputString.trim(); // Remove spaces and newlines
Serial.print("Received: ");
Serial.println(inputString);
// Enforce cooldown — ignore new command if last action too recent
if (millis() - lastActionTime < cooldown) {
return;
}
if (inputString.equalsIgnoreCase("BIO")) {
servoNonBio.write(0); // Make sure non-bio stays closed
servoBio.write(120); // Open bio bin
delay(800);
servoBio.write(0); // Close bio bin
lastActionTime = millis();
}
else if (inputString.equalsIgnoreCase("NONBIO")) {
servoBio.write(0); // Make sure bio stays closed
servoNonBio.write(120); // Open non-bio bin
delay(800);
servoNonBio.write(0); // Close non-bio bin
lastActionTime = millis();
}
else if (inputString.equalsIgnoreCase("NONE")) {
servoBio.write(0);
servoNonBio.write(0);
}
}
}
VS JAVA CODE
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Smart Waste Sorter</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background: #f4f4f4;
margin: 0;
padding: 20px;
}
#webcam-container { margin-top: 20px; }
#label-container div { padding: 5px; font-size: 16px; }
#command-log { margin-top: 20px; font-weight: bold; color: blue; }
button {
padding: 10px 20px;
margin: 5px;
font-size: 16px;
border: none;
border-radius: 5px;
background: #007bff;
color: white;
cursor: pointer;
}
button:hover { background: #0056b3; }
</style>
</head>
<body>
<h1>Teachable Machine Image Model</h1>
<button onclick="init()">Start Detection</button>
<button onclick="initSerial()">Connect Arduino</button>
<div id="webcam-container"></div>
<div id="label-container"></div>
<div id="command-log">Command to Arduino: (not sent yet)</div>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@teachablemachine/image@latest/dist/teachablemachine-image.min.js"></script>
<script>
const URL = "https://teachablemachine.withgoogle.com/models/AY_02yWWo/";
let model, webcam, labelContainer, maxPredictions;
let port, writer;
let lastCmd = "";
let lastSendTime = 0;
const sendCooldown = 1000; // 1 second between sends
// Auto reconnect
navigator.serial.addEventListener("disconnect", async () => {
document.getElementById("command-log").innerHTML =
"Arduino disconnected. Trying to reconnect...";
console.warn("Arduino disconnected. Reconnecting...");
try { await initSerial(); }
catch (err) { console.error("Auto-reconnect failed:", err); }
});
async function initSerial() {
try {
if (!port) {
port = await navigator.serial.requestPort();
}
await port.open({ baudRate: 9600 });
writer = port.writable.getWriter();
document.getElementById("command-log").innerHTML = "Serial connected to Arduino!";
console.log("Serial connected to Arduino!");
} catch (err) {
console.error("Serial connection failed:", err);
document.getElementById("command-log").innerHTML = "Serial connection failed!";
}
}
async function sendCommand(cmd) {
const now = Date.now();
if (cmd === lastCmd || now - lastSendTime < sendCooldown) {
return; // ignore duplicate or too fast commands
}
lastCmd = cmd;
lastSendTime = now;
if (writer) {
const data = new TextEncoder().encode(cmd + "\n");
await writer.write(data);
console.log("Sent to Arduino:", cmd);
document.getElementById("command-log").innerHTML = "Command to Arduino: " + cmd;
} else {
console.warn("Command not sent — Arduino not connected:", cmd);
document.getElementById("command-log").innerHTML =
"Arduino not connected. Last command: " + cmd;
}
}
async function init() {
const modelURL = URL + "model.json";
const metadataURL = URL + "metadata.json";
model = await tmImage.load(modelURL, metadataURL);
maxPredictions = model.getTotalClasses();
const flip = true;
webcam = new tmImage.Webcam(200, 200, flip);
await webcam.setup();
await webcam.play();
window.requestAnimationFrame(loop);
document.getElementById("webcam-container").appendChild(webcam.canvas);
labelContainer = document.getElementById("label-container");
for (let i = 0; i < maxPredictions; i++) {
labelContainer.appendChild(document.createElement("div"));
}
}
async function loop() {
webcam.update();
await predict();
window.requestAnimationFrame(loop);
}
async function predict() {
const prediction = await model.predict(webcam.canvas);
for (let i = 0; i < maxPredictions; i++) {
labelContainer.childNodes[i].innerHTML =
prediction[i].className + ": " + prediction[i].probability.toFixed(2);
}
// Find highest probability
let maxIndex = 0;
for (let i = 1; i < prediction.length; i++) {
if (prediction[i].probability > prediction[maxIndex].probability) {
maxIndex = i;
}
}
const detectedClass = prediction[maxIndex].className.toLowerCase();
if (detectedClass.includes("bio") && !detectedClass.includes("non")) {
sendCommand("BIO");
} else if (detectedClass.includes("non")) {
sendCommand("NONBIO");
} else {
sendCommand("NONE");
}
}
</script>
</body>
</html>
SOME ERROR STILL EXIST
No comments:
Post a Comment