Fanning Away Inefficiency! (FAI)

by Sadid Mujtahid Ali in Circuits > Arduino

34 Views, 1 Favorites, 0 Comments

Fanning Away Inefficiency! (FAI)

IMG_0800.JPEG

This Project aims to promote a method of conserving both time and energy by allowing a person to turn on a fan without having to touch it using hand gestures and turn it off with hand gestures as well! This Project also measures the distance between a person and the fan and then dictates the speed of the fan based on that! This project utilizes multiple different parts with an Arduino board to truly create a project that acts as a culmination of various different lessons compiled into one project!

Supplies

Breadboard

Small Breadboard

LCD 16x2

UNO R3 Power Supply Module

Fan blade and 3- 6V Motor

Button

Arduino UNO R3

Breadboard Jumper Wire

1 Green LED Light

1 Red LED Light

Computer Webcam

Arduino Ultrasonic Distance Sensor

Clear Tape

Laptop/Monitor

Assemble the Materials!

Collect the following materials to use!

Breadboard

Small Breadboard

LCD 16x2

UNO R3 Power Supply Module

Fan blade and 3- 6V Motor

Button

Arduino UNO R3

Breadboard Jumper Wire

1 Green LED Light

1 Red LED Light

Computer Webcam

Arduino Ultrasonic Distance Sensor

Clear Tape

Laptop/Monitor

Put It All Together Like Here!

unnamed.jpg

After arranging all the parts like so, let's go over a couple of reasons as to what each part plays in the actual Project!


Breadboard - To hold all the Wires together!


Small Breadboard - To hold the Ultrasonic Distance Sensor in place on top of a Laptop/Monitor! (We will get into why later!)


LCD 16x2 - To show how fast the Fan is spinning!


UNO R3 Power Supply Module - To regulate the power going through the Breadboard.


Fan Blade and 3 - 6V Motor - To give us the cool air we need!


Button - To act as a reset button in case the project is having some technical difficulties!


Arduino UNO R3 - To serve as our little microcomputer for this project!


Breadboard Jumper Wire - To connect the many components of our project together!


1 Green LED Light - To indicate whether the Fan is On!


1 Red LED Light - To indicate whether the Fan is Off!


Computer Webcam - if a person were to point the number 1 on their hand with their index finger and show it to the camera, the AI model would tell the fan to start working! Likewise, if there are all 5 fingers on display towards the camera, the AI model would tell the fan to stop working!


Arduino Ultrasonic Distance Sensor - This is used to tell how far away you are from the fan and then dictate the speed at which you will receive air!


Clear Tape - To steady the Small Breadboard in place atop the laptop/monitor.


Laptop/Monitor - To hold the Ultrasonic distance Sensor and be used to determine the distance between a person and a screen!



Make sure to tape the small breadboard with the Ultrasonic Distance Sensor to the top of a Laptop/Monitor!

Arduino Code!

For This Specific Project, We will use 2 pieces of code! One for the Arduino Itself and One for the AI Model! This piece of code right here is for the Arduino itself!

String inputString = "";
#include <LiquidCrystal.h>
LiquidCrystal LCD(11,10,9,2,3,4,5);
#define trigPin 0
#define echoPin 1
//rs ,en d4 d5 d6 d7
int rs=10;
int e=9;
int d4=2;
int d5=3;
int d6=4;
int d7=5;

int speedPin= 6;
int directionPin1= 7;
int dirctionPin= 8;
int mSpeed;
int green=13;
int red=12;

String lastClass = "";

void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode (speedPin,OUTPUT );
pinMode (directionPin1, OUTPUT);
pinMode (dirctionPin, OUTPUT);
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
Serial.begin(9600);
LCD.begin(16,2);
}

void loop() {
long duration, distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
LCD.setCursor(0,0);
LCD.print("CURENT DISTANCE :");
LCD.setCursor(0,1);
LCD.print("");
LCD.setCursor(0,1);
LCD.print(distance);
LCD.print(" cm");
delay(250);

while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;

if (inChar == '\n') {
inputString.trim(); // Remove newline and spaces
Serial.println("Received: " + inputString); // Debug

if (inputString == "Class1") { //Start
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
digitalWrite(directionPin1, LOW);
digitalWrite(dirctionPin, HIGH);
digitalWrite(speedPin , 255);
lastClass = "Class1";
} else if (inputString == "Class2") { //Stop
digitalWrite(red, HIGH);
digitalWrite(green, LOW);
digitalWrite(directionPin1, HIGH);
digitalWrite(dirctionPin, LOW);
digitalWrite(speedPin , 0);
lastClass = "Class2";

} else if (inputString == "Class3" && lastClass == "Class1") { //Repeat
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
digitalWrite(directionPin1, LOW);
digitalWrite(dirctionPin, HIGH);
digitalWrite(speedPin , 255);

} else if (inputString == "Class3" && lastClass == "Class2") { //Repeat
digitalWrite(red, HIGH);
digitalWrite(green, LOW);
digitalWrite(directionPin1, HIGH);
digitalWrite(dirctionPin, LOW);
digitalWrite(speedPin , 0);
}
inputString = "";
}
}
LCD.clear();
}

AI Model Code!

<!DOCTYPE html>
<html>
<head>
<title>Thumbs Detection</title>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>
<script src="https://cdn.jsdelivr.net/npm/@teachablemachine/image@latest/dist/teachablemachine-image.min.js"></script>
</head>
<body>
<h2>Thumbs Gesture Detection (Offline + Arduino)</h2>
<button onclick="init()">Start</button>
<p id="status">Waiting...</p>


<!-- ✅ Your custom JS goes here -->
<script>
let model, webcam, writer;
let lastClass = "";
let lastSendTime = 0;
const sendInterval = 400; // milliseconds between predictions


async function init() {
try {
document.getElementById("status").innerText = "Loading model...";


const modelURL = "model.json";
const metadataURL = "metadata.json";
model = await tmImage.load(modelURL, metadataURL);


webcam = new tmImage.Webcam(200, 200, true);
await webcam.setup();
await webcam.play();
document.body.appendChild(webcam.canvas);


const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
const encoder = new TextEncoderStream();
encoder.readable.pipeTo(port.writable);
writer = encoder.writable.getWriter();


document.getElementById("status").innerText = "Camera + Serial Ready!";
window.requestAnimationFrame(loop);
} catch (err) {
console.error("Setup failed:", err);
document.getElementById("status").innerText = "Error: " + err;
}
}


async function loop() {
webcam.update();
const now = Date.now();


if (now - lastSendTime > sendInterval) {
await predict();
lastSendTime = now;
}


window.requestAnimationFrame(loop);
}


async function predict() {
const prediction = await model.predict(webcam.canvas);


let maxIndex = 0;
for (let i = 1; i < prediction.length; i++) {
if (prediction[i].probability > prediction[maxIndex].probability) {
maxIndex = i;
}
}
// If you have more Classes add them here. [..., "Class4", "Class5", ...], also add DisplayName#...
const classNames = ["Class1", "Class2", "Class3"];
const displayNames = ["start ", "stop", "rpeat "];


const selectedClass = classNames[maxIndex];


// Only send to Arduino if changed
if (selectedClass !== lastClass && writer) {
await writer.write(selectedClass + "\n");
lastClass = selectedClass;
}


// Show a friendly name on screen
document.getElementById("status").innerText = displayNames[maxIndex]; // You can change this text
}
</script>
</body>
</html>

Final Product!

Voila! That should be how it looks when in use!