The idea of my project is to create a Montessori busy box designed to engage and educate young children from 3 to 6 years. This project addresses the issue of young children being curious and often playing with dangerous items like switches, plugs, and fans and the issue of being stuck to screens and mobile phones. By providing a safe and stimulating alternative, the busy box allows children to satisfy their curiosity and learn through play which emphasize hands-on learning and exploration without the risk of injury. This busy board will include gears, buttons, lamp, buzzer, motor, and a Whack-a-Mole game, all controlled by Arduino. One of my dreams is to create my own business designing STEM kits and Montessori boxes for kids. I’m thrilled to make this first step with the Fun Factory Box and help children learn while having fun.
I used fusion 360 application to sketch the design of the box, and save the design as .dxf.
This app were used to download the components needed in the project in order to add it into fusion to the assemle the vitually to the design.
I used LaserWork V6 Application in order to prepare the .dxf prepared on fusion and save it to RLD. file.
I used UltiMaker Cura Application in order to prepare my. stl file for printing and save it as .gcode.
I started to measure the dimensions of the components needed in my project to draw it in Fusion, so as you can see in the left side for the whack -a -mole game it has the LCD Screen place, the buttons and the LED holders, on the right side you will find a rectangular frame for the x-o game, halogen lamp and switch, Dc -motor, servo motor and 2-potentiometers and the empty place is for the Gears.
i made new sketch fie creating the gears using Add in option in Fusion 360.
The bottom panel wasn't that hard like the top, just i drew the dimensions of the H-Bridge and download STEP File of the H-bridge from GrabCAD and joint it to the panel.
For the sides i decided to use the t-slots, and on the right side you can see 3-holes, 2 of them for the adapter terminals as my project needs 2-adapters and one hole for the buzzer.
PLA filament is an affordable material that can be used in 3D printers to print the desired model.
Prusa i3 MK2 printer can read g.code file and print the 3D model.
Plywood 3mm is the material used in my design on laser cutting machine.
This Laser cutter Machine used to emit a laser that can cut and engrave according to the settled power and speed.
Preparing for laser cutting:
Open LaserWork and Import the saved dxf files.
Select the parts needed to cut and make it black, while the parts needed to be scanned with Red
Adjust the power and speed of each.
Cut: Speed 40, Power 45
Scan: Speed 250, Power 30
Save file as .RLD.
Turn on the machine from the green circular button.
Open Laser work from the PC connected to the machine , and open my .rld file.
Make sure that the power and speed of cut and scan are adjusted.
Make sure that the origin of software is correctly set with the machine.
Press download, so that the file will be downloaded to the machine.
Now, from the machine, press on File button., and select my file.
Put my plywood sheet in the desired place, where the nozzel is pointing to the sheet, make sure its fixed.
Move the nozzel to the desired place on the wood, the press origin to set it as the origin that i wanted.
Adjust the focus.
Press on frame button to see the area of cutting and make sure that its okay.
Close the door, and press start.
Using Fritzing app to build my own circuit virtually, as my circuit has a huge number of wires, so that helps me to make the circuit identified and clear for me.
My circuit includes:
*The Microcontroller: Arduino Nano.
*The power: two-adaptors 5V and 9V.
Whack-A-Mole Game: For this game i used 5-push buttons, one to start the game and four for playing, also i used 4-LEDs with different colors, and a LCD I2C Module to display the timer and the score, buzzer.
Controlling a Fan with potentiometer: For this part i used Hobby gear Dc Motor, H-bridge to control the speed of the moto, potentiometer.
Lamp: I used Relay, Halogen Lamp, and switch.
Steering wheel: I used servo motor and potentiometer.
At the beginning i wanted to used 9volts battery and 4.5 volts battery instead of using adaptors but the instructors advised me to use adaptors.
Connected to the VIn of Arduino to power up Arduino.
Connected to the H-bridge, Relay and Halogen Lamp.
And common GND for all.
#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h> //including the required libraries
#define startButton 1 //defining the start button
#define Button1 6
#define Button2 7
#define Button3 8
#define Button4 9 //defining the button pins, which when pushed whack the mole
#define LED1 2
#define LED2 3
#define LED3 4
#define LED4 5 //defining the LED Pins (moles)
#define buzzer 10 //Analogpin for different tones
#define motorspeed 11 //Analogpin to change speed of rotation
#define motor 12
#define potentiometer A6 // Potentiometer connected at A6
#define LampSwitch A0 //Halogen Lamp switch
#define Relay 13 //relay controlling Halogen Lamp
#include <Servo.h>
Servo myservo; // create Servo object to control a servo
#define potentiometer2 A2
#define beebButton A1
int potvalue; // variable to read potentiometer value
int potVal = 0; // variable to store value of potentiomter
bool buttonstart = 0; //needed to read the start button
bool cButtonstate1 = 0;
bool cButtonstate2 = 0;
bool cButtonstate3 = 0;
bool cButtonstate4 = 0; //currentbuttonstates
bool pButtonstate1 = 0;
bool pButtonstate2 = 0;
bool pButtonstate3 = 0;
bool pButtonstate4 = 0; //previousbuttonstates
bool LED_1 = 0;
bool LED_2 = 0;
bool LED_3 = 0;
bool LED_4 = 0; //needed to read the LEDs
bool timereset = 0; //resets the millis every time the state goes to start
unsigned long time = 0; //stores the time, which is going by
unsigned long ptime = 0; //stores the previous time
unsigned long gtime = 0; //stores the time, which is going by until the button is pushed
unsigned long gametime = 60000; //defining the gametime (60sec)
unsigned long moleinterval = 1500; //defining the time you have to whack the mole (2sec)
unsigned long moletime = 0; //stores the time, when the random LED went HIGH
unsigned long score = 0; //stores the score
unsigned long mole = 0; //later needed for the random function
LiquidCrystal_I2C lcd(0x27, 16, 2); //defining the LCD Display
enum state {
menu,
start,
end,
};
state game = menu; //state machine for the menu and start case
void setup() {
lcd.init();
lcd.backlight(); //initialize LCD Display
pinMode(startButton, INPUT_PULLUP);
pinMode(Button1, INPUT_PULLUP);
pinMode(Button2, INPUT_PULLUP);
pinMode(Button3, INPUT_PULLUP);
pinMode(Button4, INPUT_PULLUP); //defining all Buttons as Pullups for less cables
pinMode(buzzer, OUTPUT);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT); //defining LEDs as outputs
pinMode(motorspeed, OUTPUT);
pinMode(motor, OUTPUT); //motor
pinMode(Relay, OUTPUT);
pinMode(LampSwitch, INPUT_PULLUP);
myservo.attach(A3); // attaches the servo on pin 9 to the Servo object
pinMode(potentiometer2, INPUT);
myservo.write(90);
pinMode(beebButton, INPUT_PULLUP);
}
void loop() {
// Servo and potentiometer
potvalue = analogRead(potentiometer2); // reads the value of the potentiometer (0 to 1023)
potvalue = map(potvalue, 0, 1023, 10, 170); // scale it to use it with the servo (0 to 180)
myservo.write(potvalue); // sets servo position according to the scaled value
delay(15); // waits for the servo to get there
if (digitalRead(beebButton) == 0) {
digitalWrite(buzzer, HIGH);
delay(15);
} else {
digitalWrite(buzzer, LOW);
}
//Halogen Lamp
if (digitalRead(LampSwitch) == 1) {
digitalWrite(Relay, LOW);
} else {
digitalWrite(Relay, HIGH);
}
// Fan speed Code:
digitalWrite(motor, HIGH); // Set motor to rotate in one direction.
potVal = analogRead(potentiometer);
analogWrite(motorspeed, (map(potVal, 0, 1023, 0, 190))); //controlling motor speed according to potentiometer value
//Whack-A-Mole code:
time = millis(); //storing the current time in time
buttonstart = !digitalRead(startButton);
cButtonstate1 = !digitalRead(Button1);
cButtonstate2 = !digitalRead(Button2);
cButtonstate3 = !digitalRead(Button3);
cButtonstate4 = !digitalRead(Button4); //reading all Buttons (! because they are pullups)
LED_1 = digitalRead(LED1);
LED_2 = digitalRead(LED2);
LED_3 = digitalRead(LED3);
LED_4 = digitalRead(LED4); //reading all the LEDs
switch (game) {
case menu:
{
lcd.backlight();
lcd.setCursor(2, 0);
lcd.print("Play time:"); //printing playtime on the Display
lcd.print(gametime / 1000); //printing the gametime in sec on the Display
lcd.print(" ");
lcd.setCursor(2, 1);
lcd.print("Press Start");
if (buttonstart) {
gtime = time; //sets gtime to the current time
game = start; //if the start Button is pushed the state goes to start
lcd.clear(); //clearing the Display
score = 0; //setting score to zero every restart
tone(buzzer, 200, 200); //Pin,Frequency,Duration
tone(buzzer, 500, 200); //Pin,Frequency,Duration
tone(buzzer, 1000, 200); //Pin,Frequency,Duration
}
}
break; //case menu
case start:
{
time = time - gtime; //sets time to the time going by after the button was pushed
lcd.setCursor(2, 0);
lcd.print("Play time:");
lcd.print((gametime - time) / 1000); //printing gametime on the Display
lcd.print(" ");
lcd.setCursor(2, 1);
lcd.print("Score:");
lcd.print(score); //printing the score on the Display
if (!LED_1 && !LED_2 && !LED_3 && !LED_4) //if no LED is shining
{
mole = random(2, 6); //pick a random LED Pin
digitalWrite(mole, HIGH); //turn the random LED on
moletime = time;
}
if (LED_1 && cButtonstate1 && !pButtonstate1) {
score++;
digitalWrite(LED1, LOW);
moletime = 0;
}
if (LED_2 && cButtonstate2 && !pButtonstate2) {
score++;
digitalWrite(LED2, LOW);
moletime = 0;
}
if (LED_3 && cButtonstate3 && !pButtonstate3) {
score++;
digitalWrite(LED3, LOW);
moletime = 0;
}
if (LED_4 && cButtonstate4 && !pButtonstate4) {
score++;
digitalWrite(LED4, LOW);
moletime = 0;
}
if (time - moletime > moleinterval) {
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW); //if the moletime is expired, then set all LEDs to low
}
pButtonstate1 = cButtonstate1;
pButtonstate2 = cButtonstate2;
pButtonstate3 = cButtonstate3;
pButtonstate4 = cButtonstate4; //setting all previous button states to the current button state
if (time >= gametime) {
lcd.clear();
tone(buzzer, 1800, 300); //Pin,Frequency,Duration
game = end; //if gametime is reached, then clear the Display and go to the end sate
}
}
break;
case end:
{
lcd.setCursor(2, 0);
lcd.print("Play time:0");
lcd.setCursor(2, 1);
lcd.print("Score:");
lcd.print(score);
delay(1000);
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
if (buttonstart) {
game = menu; //if the startbutton is pushed, go back in the menu state
}
}
break;
}
}
#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h> //including the required libraries
#define startButton 1 //defining the start button
#define Button1 6
#define Button2 7
#define Button3 8
#define Button4 9 //defining the button pins, which when pushed whack the mole
#define LED1 2
#define LED2 3
#define LED3 4
#define LED4 5 //defining the LED Pins (moles)
#define buzzer 10 //Analogpin for different tones
#define motorspeed 11 //Analogpin to change speed of rotation
#define motor 12
#define potentiometer A6 // Potentiometer connected at A6
#define LampSwitch A0 //Halogen Lamp switch
#define Relay 13 //relay controlling Halogen Lamp
#include <Servo.h>
Servo myservo; // create Servo object to control a servo
#define potentiometer2 A2
#define beebButton A1
int potvalue; // variable to read potentiometer value
int potVal = 0; // variable to store value of potentiomter
bool buttonstart = 0; //needed to read the start button
bool cButtonstate1 = 0;
bool cButtonstate2 = 0;
bool cButtonstate3 = 0;
bool cButtonstate4 = 0; //currentbuttonstates
bool pButtonstate1 = 0;
bool pButtonstate2 = 0;
bool pButtonstate3 = 0;
bool pButtonstate4 = 0; //previousbuttonstates
bool LED_1 = 0;
bool LED_2 = 0;
bool LED_3 = 0;
bool LED_4 = 0; //needed to read the LEDs
bool timereset = 0; //resets the millis every time the state goes to start
unsigned long time = 0; //stores the time, which is going by
unsigned long ptime = 0; //stores the previous time
unsigned long gtime = 0; //stores the time, which is going by until the button is pushed
unsigned long gametime = 60000; //defining the gametime (60sec)
unsigned long moleinterval = 1500; //defining the time you have to whack the mole (2sec)
unsigned long moletime = 0; //stores the time, when the random LED went HIGH
unsigned long score = 0; //stores the score
unsigned long mole = 0; //later needed for the random function
LiquidCrystal_I2C lcd(0x27, 16, 2); //defining the LCD Display
enum state {
menu,
start,
end,
};
state game = menu; //state machine for the menu and start case
void setup() {
lcd.init();
lcd.backlight(); //initialize LCD Display
pinMode(startButton, INPUT_PULLUP);
pinMode(Button1, INPUT_PULLUP);
pinMode(Button2, INPUT_PULLUP);
pinMode(Button3, INPUT_PULLUP);
pinMode(Button4, INPUT_PULLUP); //defining all Buttons as Pullups for less cables
pinMode(buzzer, OUTPUT);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT); //defining LEDs as outputs
pinMode(motorspeed, OUTPUT);
pinMode(motor, OUTPUT); //motor
pinMode(Relay, OUTPUT);
pinMode(LampSwitch, INPUT_PULLUP);
myservo.attach(A3); // attaches the servo on pin 9 to the Servo object
pinMode(potentiometer2, INPUT);
myservo.write(90);
pinMode(beebButton, INPUT_PULLUP);
}
void loop() {
// Servo and potentiometer
potvalue = analogRead(potentiometer2); // reads the value of the potentiometer (0 to 1023)
potvalue = map(potvalue, 0, 1023, 10, 170); // scale it to use it with the servo (0 to 180)
myservo.write(potvalue); // sets servo position according to the scaled value
delay(15); // waits for the servo to get there
if (digitalRead(beebButton) == 0) {
digitalWrite(buzzer, HIGH);
delay(15);
} else {
digitalWrite(buzzer, LOW);
}
//Halogen Lamp
if (digitalRead(LampSwitch) == 1) {
digitalWrite(Relay, LOW);
} else {
digitalWrite(Relay, HIGH);
}
// Fan speed Code:
digitalWrite(motor, HIGH); // Set motor to rotate in one direction.
potVal = analogRead(potentiometer);
analogWrite(motorspeed, (map(potVal, 0, 1023, 0, 190))); //controlling motor speed according to potentiometer value
//Whack-A-Mole code:
time = millis(); //storing the current time in time
buttonstart = !digitalRead(startButton);
cButtonstate1 = !digitalRead(Button1);
cButtonstate2 = !digitalRead(Button2);
cButtonstate3 = !digitalRead(Button3);
cButtonstate4 = !digitalRead(Button4); //reading all Buttons (! because they are pullups)
LED_1 = digitalRead(LED1);
LED_2 = digitalRead(LED2);
LED_3 = digitalRead(LED3);
LED_4 = digitalRead(LED4); //reading all the LEDs
switch (game) {
case menu:
{
lcd.backlight();
lcd.setCursor(2, 0);
lcd.print("Play time:"); //printing playtime on the Display
lcd.print(gametime / 1000); //printing the gametime in sec on the Display
lcd.print(" ");
lcd.setCursor(2, 1);
lcd.print("Press Start");
if (buttonstart) {
gtime = time; //sets gtime to the current time
game = start; //if the start Button is pushed the state goes to start
lcd.clear(); //clearing the Display
score = 0; //setting score to zero every restart
tone(buzzer, 200, 200); //Pin,Frequency,Duration
tone(buzzer, 500, 200); //Pin,Frequency,Duration
tone(buzzer, 1000, 200); //Pin,Frequency,Duration
}
}
break; //case menu
case start:
{
time = time - gtime; //sets time to the time going by after the button was pushed
lcd.setCursor(2, 0);
lcd.print("Play time:");
lcd.print((gametime - time) / 1000); //printing gametime on the Display
lcd.print(" ");
lcd.setCursor(2, 1);
lcd.print("Score:");
lcd.print(score); //printing the score on the Display
if (!LED_1 && !LED_2 && !LED_3 && !LED_4) //if no LED is shining
{
mole = random(2, 6); //pick a random LED Pin
digitalWrite(mole, HIGH); //turn the random LED on
moletime = time;
}
if (LED_1 && cButtonstate1 && !pButtonstate1) {
score++;
digitalWrite(LED1, LOW);
moletime = 0;
}
if (LED_2 && cButtonstate2 && !pButtonstate2) {
score++;
digitalWrite(LED2, LOW);
moletime = 0;
}
if (LED_3 && cButtonstate3 && !pButtonstate3) {
score++;
digitalWrite(LED3, LOW);
moletime = 0;
}
if (LED_4 && cButtonstate4 && !pButtonstate4) {
score++;
digitalWrite(LED4, LOW);
moletime = 0;
}
if (time - moletime > moleinterval) {
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW); //if the moletime is expired, then set all LEDs to low
}
pButtonstate1 = cButtonstate1;
pButtonstate2 = cButtonstate2;
pButtonstate3 = cButtonstate3;
pButtonstate4 = cButtonstate4; //setting all previous button states to the current button state
if (time >= gametime) {
lcd.clear();
tone(buzzer, 1800, 300); //Pin,Frequency,Duration
game = end; //if gametime is reached, then clear the Display and go to the end sate
}
}
break;
case end:
{
lcd.setCursor(2, 0);
lcd.print("Play time:0");
lcd.setCursor(2, 1);
lcd.print("Score:");
lcd.print(score);
delay(1000);
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
if (buttonstart) {
game = menu; //if the startbutton is pushed, go back in the menu state
}
}
break;
}
}
Flow Chart
1. Start Game
Start Button Pressed?
Yes → Start the Game
No → Wait for Start Button
2. Game Setup
Initialize LCD with "Whack-a-Mole Game!"
Set all LEDs and score to 0
Randomly select an LED when turned ON
3. Game Running
Player Button Pressed?
Correct Button?
Yes → Increment Score and Turn Off LED, Randomly Light Another LED
No → Continue Waiting for Correct Button and keep the score without increment
Time Over?
Yes → Show Final Score
No → Continue Game Loop
4. Halogen Lamp Control
Switch Pressed?
Yes → Turn Relay ON or OFF (Halogen Lamp)
5. Servo Motor Control
Read Potentiometer Value
Map Potentiometer Value to Servo Angle (10° to 170°)
Move Servo to the Corresponding Angle
6. Fan Speed Control
Read Potentiometer Value
Adjust Fan Speed Based on Potentiometer Reading
I started the project by trying the Whack-A-Mole circuit, making the circuit was simple but making the code from scratch wasn't that easy, so i searched for codes that may help me and found one suitable, so i start editing on it.
As i already tried controlling the motor speed with H-bridge and potentiometer in week 6 so i started integrating it with the Whack -a-mole circuit, after that i integrated the halogen lamp and relay as i tried them before in week 8 assignment, Finally i decided to add the steering wheel idea instead of the piano idea , as the number of pins in Arduino wasn't enough.
First i made the circuit in a simple box just to imagine the idea and make sure that everything can work together and then i redo it again in the wooden box.
Assembling and Mounting the components
Final Result
Final Project Simulation
My instructors are suggesting to use multithreading in the code, to avoid lagging or instability of actions happening, i still didn't try to search and try to do it but I'm planning to try it and see if it will make difference in my project.
Also adding the X-O Game instead of the Maze was the idea of my instructor Eman which i really loved and it makes the box more catchy for kids.
One of the challenges that i faced that some components in GrabCAD wasn't with the same dimensions that i had in real, that makes dimensions wasn't accurate, My instructor helped me be sharing some components and the other was measured by the caliper in the Lab.
Handling the wires in the box🙊, i tried as much as i can to make color code for the wires, but i wish i could learn how to make PCBs and create my own for this project 😂.
I used a propeller dxf design to be fixed on the motor but because the motor's shaft is not circular, it didn't work so i projected the shaft itself on fusion and save it as dxf and add it to the propeller instead of the circle.
Handling the powering of the servo motor, as first i connected it to the 5volts coming out of the Arduino, Instructor Abdel-Rahman asked me to try connecting it to the 5volts coming out of the H-bridge and it was really a great idea that makes the servo works better.
I would like to learn how to design a printed circuit board (PCB) as the wires problem will not exist and also this will make it an idea for real project and business to start.