// HTML+ JS+ CSS
<!DOCTYPE html>
<html>
<head>
<title>Teachable Machine + Arduino</title>
</head>
<body>
<h2>Teachable Machine Image Model + Arduino Uno</h2>
<button type="button" onclick="init()">Start Camera & Model</button>
<button type="button" onclick="connectToArduino()">Connect to Arduino</button>
<div id="webcam-container"></div>
<div id="label-container"></div>
<!-- TensorFlow.js and Teachable Machine image library -->
<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 type="text/javascript">
const URL = "https://teachablemachine.withgoogle.com/models/KSwCJGldG/";
let model, webcam, labelContainer, maxPredictions;
let port, writer;
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; // whether to flip the webcam
webcam = new tmImage.Webcam(200, 200, flip);
try {
await webcam.setup(); // request camera access
console.log("Webcam object after setup:", webcam);
await webcam.play();
window.requestAnimationFrame(loop);
document.getElementById("webcam-container").appendChild(webcam.canvas);
} catch (err) {
console.error("Webcam setup failed:", err);
return; // stop if webcam can't start
}
labelContainer = document.getElementById("label-container");
for (let i = 0; i < maxPredictions; i++) {
labelContainer.appendChild(document.createElement("div"));
}
}
async function loop() {
if (webcam && webcam.canvas) {
webcam.update();
await predict();
}
window.requestAnimationFrame(loop);
}
async function predict() {
if (!webcam || !webcam.canvas) {
console.warn("Webcam not ready yet.");
return;
}
const prediction = await model.predict(webcam.canvas);
let detectedClass = "";
for (let i = 0; i < maxPredictions; i++) {
const classPrediction = prediction[i].className + ": " + prediction[i].probability.toFixed(2);
labelContainer.childNodes[i].innerHTML = classPrediction;
if (prediction[i].probability > 0.8) {
detectedClass = prediction[i].className;
}
}
if (detectedClass) {
console.log("Detected:", detectedClass);
if (writer) {
await writer.write(new TextEncoder().encode(detectedClass + "\n"));
}
}
}
async function connectToArduino() {
try {
console.log("Requesting Arduino port...");
port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
writer = port.writable.getWriter();
console.log("Connected to Arduino successfully.");
alert("Connected to Arduino!");
} catch (err) {
console.error("ERROR: Could not connect to Arduino!", err);
}
}
</script>
</body>
</html>
// ARDUINO CODE
void setup() {
Serial.begin(9600);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
}
void loop() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n'); // Reads until newline
command.trim(); // Remove spaces/newlines
Serial.println("Received: " + command); // Debug
if (command.equalsIgnoreCase("Me")) {
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
}
else if (command.equalsIgnoreCase("Phone")) {
digitalWrite(9, HIGH);
digitalWrite(8, LOW);
}
else {
digitalWrite(8, LOW);
digitalWrite(9, LOW);
}
}
}
No comments:
Post a Comment