Google Teachable Machine https://teachablemachine.withgoogle.com/
Use Arduino IDE
p5.js Code https://editor.p5js.org/yining/sketches/eHYnYa5BR
P5 App https://github.com/p5-serial/p5.serialcontrol/releases
開啟 C:\BlocklyduinoF2\arduino-1.8.19\arduino.exe 這個檔案
Next Step(After finish traning model..)
click "Export Model", then click "Upload my model"
copy your shareable linl: click "copy"
download open.bat,then double click the file.
First you have to install ur Linkit 7697 in ur PC.
The computer will open "Arduino IDE".
check your development board and com port
upload(burn) ur code
#include <Servo.h>
Servo myservo;
int servoPin = 9;
int yellowPin = 5;
int redPin = 2;
int greenPin = 3;
int bluePin = 4;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(yellowPin, OUTPUT);
myservo.attach(servoPin);
myservo.write(0); // set servo to mid-point
// start serial port at 9600 bps:
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) { // if there's serial data available
int inByte = Serial.read(); // read it
Serial.println(inByte);
if (inByte == 1) {
myservo.write(10);
// Light red LED
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 2) {
myservo.write(50);
// Light green LED
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 3) {
myservo.write(90);
// Light BLUE LED
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, LOW);
} else if (inByte == 4) {
myservo.write(140);
// Light BLUE LED
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, HIGH);
}
else {
myservo.write(0);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, HIGH);
}
// Wait for 1 second
delay(500);
}
}
Download this app https://github.com/p5-serial/p5.serialcontrol/releases/download/0.1.2/p5.serialcontrol-win32-x64.zip
then unzip!
double click "p5.serialcontrol.exe"
Open "P5 SERIAL CONTROL"
click 'open'
open p5.js https://editor.p5js.org/yining/sketches/Ob8Zkf_FZ
delete all code
then copy my code(below) and paste
Modify the 1 and 5 line
const myImageModelURL = 'your teachable machine link';
let portName = 'COM5';// fill in your serial port name here
clic play play
const myImageModelURL = '修改成自己的';
let myImageModel;
let resultDiv;
let serial;// variable to hold an instance of the serialport library
let portName = '修改成自己的';// fill in your serial port name here
let outByte = 0;// for outgoing data
let video;
function preload() {
video = createCapture(VIDEO);
myImageModel = ml5.imageClassifier(myImageModelURL+ 'model.json');
}
function setup() {
resultDiv = createElement('h1', '...');
serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on('error', serialError); // callback for errors
serial.open(portName); // open a serial port
myImageModel.classify(video, gotResults);
}
function serialError(err) {
console.log('Something went wrong with the serial port. ' + err);
}
function gotResults(err, results) {
if (err) console.log(err);
if (results) {
console.log(results);
// Wait for 0.5 second before classifying again
setTimeout(() => myImageModel.classify(video, gotResults), 500);
if (results[0].confidence < 0.7) return;
resultDiv.html('Result is: ' + results[0].label);
console.log(results[0].label);
if (results[0].label === 'paper') {
outByte = 1;
} else if (results[0].label === 'rock') {
outByte = 2;
} else if (results[0].label === 'sicssors') {
outByte = 3;
} else if (results[0].label === 'other') {
outByte = 4;
} else {
outByte = 0;
}
// send it out the serial port:
console.log('outByte: ', outByte)
serial.write(outByte);
}
}
rock greenPin=3
paper resPin=2
sicssors bluePin=4
other yellowPin=5
You can try recognizing sounds or pose....(follow my materials)
Image Recognization
Google Teachable machine
觀察測試,用左右手都測試
發現左手效果不好,就補拍照片
影響因素:不同背景、不同燈光都會影響辨識度
匯出:先點 Export Model -> Download My Model
複製連結,然後按ESC
三條線 -> Save project to Drive
下次使用的時候需要再重新訓練
燒錄Arduino IDE
紅綠藍黃(2,3,4,5)
修改第一行跟第五行
第一行const myImageModelURL = '改成你的';
第五行let portName = 'COM5';// fill in your serial port name here
然後按play做測試
click "Export Model",Download my model
Don't close teachable machine
// https://teachablemachine.withgoogle.com/models/hFUsMix1m/
const mySoundModelURL = '修改成自己的';
let mySoundModel;
let resultDiv;
let serial;// variable to hold an instance of the serialport library
let portName = '修改成自己的';// fill in your serial port name here
let outByte = 0;// for.usbming data
function preload() {
mySoundModel = ml5.soundClassifier(mySoundModelURL+ 'model.json');
}
function setup() {
resultDiv = createElement('h1', '...');
serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on('error', serialError); // callback for errors
serial.open(portName); // open a serial port
mySoundModel.classify(gotResults);
}
function serialError(err) {
console.log('Something went wrong with the serial port. ' + err);
}
function gotResults(err, results) {
if (err) console.log(err);
if (results) {
// console.log(results);
if (results[0].confidence < 0.7) return;
resultDiv.html('Result is: ' + results[0].label);
if (results[0].label === 'RED') {
outByte = 1;
} else if (results[0].label === 'GREEN') {
outByte = 2;
} else if (results[0].label === 'BLUE') {
outByte = 3;
} else if (results[0].label === 'YELLOW') {
outByte = 4;
} else {
outByte = 0;
}
// send it out the serial port:
// console.log('outByte: ', outByte)
serial.write(outByte);
}
}
//int servoPin = 9;
int yellowPin = 5;
int redPin = 2;
int greenPin = 3;
int bluePin = 4;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(yellowPin, OUTPUT);
Serial.begin(9600); // initialize serial communications
}
void loop() {
if (Serial.available() > 0) { // if there's serial data available
int inByte = Serial.read(); // read it
if (inByte == 1) {
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 2) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 3) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, LOW);
} else if (inByte == 4) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, HIGH);
}
else {
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, HIGH);
}
delay(100); // waits
}
}
// Update this following link to your own model link
const poseModelUrl = '修改成自己的';
let serial;// variable to hold an instance of the serialport library
let portName = '修改成自己的';// fill in your serial port name here
// the json file (model topology) has a reference to the bin file (model weights)
const checkpointURL = poseModelUrl + "model.json";
// the metatadata json file contains the text labels of your model and additional information
const metadataURL = poseModelUrl + "metadata.json";
const size = 300;
let webcam;
let model;
let totalClasses;
let myCanvas;
let ctx;
let outByte = 0;// for outgoing data
// A function that loads the model from the checkpoint
async function load() {
model = await tmPose.load(checkpointURL, metadataURL);
totalClasses = model.getTotalClasses();
console.log("Number of classes, ", totalClasses);
}
async function loadWebcam() {
webcam = new tmPose.Webcam(size, size, true); // can change width and height
await webcam.setup(); // request access to the webcam
await webcam.play();
}
async function setup() {
serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on('error', serialError); // callback for errors
serial.open(portName); // open a serial port
myCanvas = createCanvas(size, size);
ctx = myCanvas.elt.getContext("2d");
// Call the load function, wait until it finishes loading
await load();
await loadWebcam();
predictVideo(webcam.canvas);
}
function serialError(err) {
console.log('Something went wrong with the serial port. ' + err);
}
async function predictVideo() {
webcam.update();
// Prediction #1: run input through posenet
// predictPosenet can take in an image, video or canvas html element
const flipHorizontal = false;
const { pose, posenetOutput } = await model.estimatePose(webcam.canvas);
// Prediction 2: run input through teachable machine assification model
const prediction = await model.predict(posenetOutput);
console.log('prediction', prediction);
// Find the class with the highest probability
const maxClass = prediction.reduce((prev, current) => (prev.probability > current.probability) ? prev : current)
// Show the result
const res = select('#res'); // select <span id="res">
res.html(maxClass.className);
// Show the probability
const prob = select('#prob'); // select <span id="prob">
prob.html(maxClass.probability.toFixed(2));
// draw the keypoints and skeleton
if (pose) {
const minPartConfidence = 0.5;
ctx.drawImage(webcam.canvas, 0, 0);
tmPose.drawKeypoints(pose.keypoints, minPartConfidence, ctx);
tmPose.drawSkeleton(pose.keypoints, minPartConfidence, ctx);
}
if (maxClass.className === 'left tilt') {
outByte = 1;
} else if (maxClass.className === 'no tilt') {
outByte = 2;
} else if (maxClass.className === 'right tilt') {
outByte = 3;
} else {
outByte = 0;
}
// send it out the serial port:
console.log('outByte: ', outByte)
serial.write(outByte);
// Wait for 0.2 second before classifying again
setTimeout(() => predictVideo(), 200);
}
int yellowPin = 5;
int redPin = 2;
int greenPin = 3;
int bluePin = 4;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(yellowPin, OUTPUT);
Serial.begin(9600); // initialize serial communications
}
void loop() {
if (Serial.available() > 0) { // if there's serial data available
int inByte = Serial.read(); // read it
if (inByte == 1) {
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 2) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 3) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, LOW);
} else {
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, HIGH);
}
delay(300); // waits
}
}