The project is a Bluetooth controlled alarm clock which has a theme of an anime character "Madara Uchiha".....
What inspired me to make such a project:
I love anime and I wanted to learn a mechanism and how it works so I choose the theme of the Uchiha clan specially their Sharingan eye transformation and implement it into the Iris mechanism.
Tool chain:
What I used:
Software I used:
For designing, editing 3d parts and making the DXF files: Autodesk Fusion 360
For slicing: Ultimaker Cura
For editing the DXF files and laser cutting: LaserworkV6
Machine I used:
For 3D printing: PRUSA i3 MK2 3D
For laser cutting: MORN MT3050D
Material I used:
For 3D printing: Generic PLA
For laser cutting: 3mm Plywood
The Iris mechanism preparation:
I downloaded the iris mechanism from here.
The file contain the many files I used only four which are:
Baseplate
Door_blade
Spur gear 107th
Spur gear 12th
then I prepared them for printing in Ultimaker Cura using these parameters:
Layer height: 0.3mm
Supports (as the baseplate has some area near the servo motor place which needed the support)
no adhesion
Infill: 15%
The lab specialist showed me some tricks to speed up the time a little... so we entered the custom menu..
Speed: 65mm/s
Top/Bottom thickness = 0.8mm
Top layers: 2
Bottom layers: 2
After that I exported the g.code file and the printing process started.
Designing the enclosure:
The Enclosure consists of four main parts:
The Arduino fixing sheet (back)
The Iris mechanism plate sheet (a connecting layer between the arduino sheet and the face)
The face
links (normal and live hinge)
Here to draw the Arduino base in the right dimensions I used the Project feature to project the base of the Arduino onto the sketch..
Here I also used the projection feature to project the baseplate of the Iris mechanism to get the exact dimensions>>>
Notice:: I imported the STL file into fusion and Frist I turned it into a solid object as when imported it was a mesh and I couldn't move or edit it so I search for a way to turn mesh files into solid objects .. here is the link of the tutorial I found
These are L shape corners to fix a Neopixel matrix on the Iris mechanism plate.
Here to make the live hinge of flex wood I used an online website to generate the pattern by assigning some parameters which I discussed with my instructor until we reached the most suitable parameters.....
the link of the website is here.
This flex wood linkage joins the back with the Iris mechanism plate sheet.
To TEST them I used the Sheet Metal section to bend them and fit them right in the assembly, I followed this Tutorial to make them bend right.. and thankfully the did fit in the real life assembly..
This linkage joins the Assembly of the back and the mechanism plate and the face together..
This linkage joins the Assembly of the back and the mechanism plate and the face together.. same as the one above.
The Face of the project....
Assembly in Fusion 360:
Extracting the DXF files:
The used parameters were:
Speed: 18mm/s
Power: 68%
The design had no engraving but I used Speed cut to draw Madara's face, I showed the dxf file of the drawing to the Instructors they said it will damage the wood as it contains of lines that are near to each other.. so Instructor Amany and Shrief tried to edit it using CorelDraw and it finally worked..
Links
Iris mechanism plate sheet
The face in Assembly
Iris mechanism printing process:
After exporting the g.code files from Ultimaker Cura I uploaded them one by one to the machine and the printing started.
The Enclosure Laser cutting:
After exporting the DXF files of the sketches, I imported them to LaserWorkV6 and tried to make the most out of the bed area to include as many parts as possible:
I used this online circuit simulator Circuito to design the circuit as it had all the wanted components (There is a slight difference in the power connection and the digitalWrite pins as for the power connection here you can see the Arduino is powered USB cable and the components are powered by a 5V adaptor while I used a 9V adaptor to power the Arduino and a 5V regulator to output the power to the components and I used an ON/OFF switch to open and closed the circuit. The digitalWrite pins connection differs from the from the circuit and you can see the pins numbers in the code)
Components:
Input components:
Ultrasonic sensor
DS3231 RTC module
Output components:
LCD display with I2C module
Neopixel 8*8 matrix
SG90 Servo motor
Big buzzer
Communication component:
HC-05 Bluetooth module
Others:
3x 1kohms resistors
Jumpers
Arduino Uno R3
Breadboard
5V regulator
9V adaptor
ON/OFF switch
Big buzzer
The preparation process has three parts:
Understanding how the project works.
Hardware connections (circuit design).
Understanding how the project works:
The project in simple words is a Bluetooth controlled alarm clock...
This video explains the manual guide for the project and operates its features....
Hardware connections (circuit design):
The power connection:
The connection of the RTC module and the LCD display.
The connection of the Bluetooth module
the connection of the servo motor, buzzer and the ultra sonic sensor.
The power connection:
I connected the positive terminal of 9V adaptor to the input terminal of the 5V regulator and the negative terminal id connected in series with one terminal of the ON/OFF switch the other is connected to the ground of the 5Vregulator.
Then from the output of the 5V regulator there is a jumper connecting it to the positive rail of the breadboard and from the regulator ground there is a jumper connecting it to the graound rail of the breadboard.
from the input terminal of the regulator there is a jumper connecting it to the VIN pin of the Arduino..... we can say that the input terminal of the regulator became a node that connects the regulator, the positive terminal of the power supply and the Arduino together.
The connection of the RTC module and the LCD display:
Both of these modules have these four pins which have the same connection with the power and the Arduino pins:
SDA (A4 and that could be a node that connects the A4pin on the Arduino, SDA pin on the LCD and the SDA on the RTC module together)
SCL (A5 and that could be a node that connects the A5 pin on the Arduino, SCL pin on the LCD and the SCL on the RTC module together)
GND (ground rail on the breadboard)
VCC (5V rail on the breadboard)
The connection of the Bluetooth module:
the Bluetooth module has 6 pin, we will use 4 pins:
RXD (is connected with a terminal of one of the 1k ohms resistors and the other terminal is considered as a node and the pic here will show the details )
TXD (the orange jumper is connected to pin 0 on the Arduino)
GND (the black jumper is connected to the ground rail on the breadboard which is connected to the GND pin of the Arduino next to the 5V pin through a blue jumper)
VCC (the red jumper is connected to the 5V rail on the breadboard which is connected to the 5V pin on the Arduino through a red jumper)
The connection of the servo motor, buzzer and the ultra sonic sensor:
Servo motor:
Brown jumper (GND rail )
Red jumper (5V rail )
Yellow jumper (pin 8 on the Arduino)
Ultrasonic sensor:
GND (GND rail)
VCC (5V rail)
Trigger (pin 5)
Echo (pin 4)
Buzzer
The negative terminal is connected to the ground
The positive terminal is connected to pin 6.
As explained before I used 9V adaptor to power the Arduino and connected it to a 5V regulator to power the components.
This is the used code of the project but first here are the tutorials that helped me to write this code:
The used code in the project (You will find guidance in the comments )
///////////////Used libraries//////////////
#include <SoftwareSerial.h>
#include <SPI.h>
#include <EEPROM.h>
#include <Wire.h>
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include "RTClib.h"
#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include "RGB.h"
/////////a made library from a tutorial https://www.twilio.com/blog/2015/05/light-up-your-hackpack-with-the-adafruit-neomatrix-library.html
//////Follow the turorial to make it....
/*
* copy this in a new tab and call it with the same name before including it
struct RGB {
byte r;
byte g;
byte b;
};
// Define some colors we'll use frequently
RGB white = { 255, 255, 255 };
RGB red = { 0, 255, 0 };
RGB madarasusanoo = { 64, 37, 197 };
RGB sasukesusanoo = { 0, 155, 184 };
RGB off = { 0, 0, 0 };
*/
///////////////////////////////Neopixel matrix definetion//////////
#define PIN 11
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 8, PIN,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
NEO_MATRIX_ROWS + NEO_MATRIX_PROGRESSIVE,
NEO_RGB + NEO_KHZ800);
//////////////////////////////////RTC & Servo definetion/////////
RTC_DS3231 rtc;
Servo iris;
//////////////////////variables
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; // why ????
char input;
int w_alarm_h;
int w_alarm_m;
int s_alarm_h;
int s_alarm_m;
int current_h;
int current_m;
int bluetoothpin = 7;
int bluetoothstate = 0;
int buzzer = 6;
int closeangle = 180;
int openangle = 0;
const int trigPin = 5;
const int echoPin = 4;
// defines variables
long duration;
int distance;
boolean b_menu = false; // this means that the bluetooth menu is not activated....
boolean awake = true; // i am not sleeping
////////////////////////////// Used functions//////////////////////
///////////////////Bluetooth connection function//////
/*void Serialconnection ()
{
while (bluetoothstate == 0)
{
bluetoothstate = digitalRead (bluetoothpin);
}
if (bluetoothstate == HIGH)
{
Serial.println ("connected!");
b_menu = true;
}
}*/
///////////////Bluetooth_Receive/////////////////
void waiting_to_receive ()
{
Serial.flush();
while (!Serial.available()); // or while (Serial.available() == 0);
}
////////RTC activation function/////////
void RTC_begins ()
{
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");
// Comment out below lines once you set the date & time.
// Following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// Following line sets the RTC with an explicit date & time
// for example to set January 27 2017 at 12:56 you would call:
// rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));
delay(3000); // wait for console opening
}
}
/////////////////Inputing the alarm HOURS //////////////////// we need a return function
int alarm_hours ()
{
char firstdigit_h;
char seconddigit_h;
////taking the values
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Hours");
digitalWrite(buzzer, HIGH);
delay(10);
digitalWrite(buzzer, LOW);
Serial.println ("Enter Hours");
waiting_to_receive ();
firstdigit_h = Serial.read();
waiting_to_receive (); delay(100);
seconddigit_h = Serial.read();
/// converting the char to int as the time revceived by the RTC is in integars
int hd1 = firstdigit_h - '0'; // Hours first digit integar data type
int hd2 = seconddigit_h - '0'; //convert the char to int by subtracting 48 from it or by subtracting '0'
return (hd1 * 10) + hd2; // adding the first digit which is the tens to the units digit to get the Hours
}
////////////////Inputing the alarm MINS//////////////////
int alarm_mins ()
{
char firstdigit_m;
char seconddigit_m;
////taking the values
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Mins");
digitalWrite(buzzer, HIGH);
delay(10);
digitalWrite(buzzer, LOW);
Serial.println ("Enter Mins");
waiting_to_receive ();
firstdigit_m = Serial.read();
Serial.println(firstdigit_m);
delay(100);
waiting_to_receive ();
seconddigit_m = Serial.read();
Serial.println(seconddigit_m);
/// converting the char to int as the time revceived by the RTC is in integars
int md1 = firstdigit_m - '0';
Serial.println (md1);// Hours first digit integar data type
int md2 = seconddigit_m - '0';
Serial.println (md1); //convert the char to int by subtracting 48 from it or by subtracting '0'
return (md1 * 10) + md2; // adding the first digit which is the tens to the units digit to get the mins
}
///////////////////////LCD Activation % preparation function/////////////
void LCD_begins ()
{
lcd.begin();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
}
/////////////////// Bluetooth communication function with the user//////////////
void Bluetoothcommunication() //using this funciton the user cna control LED colour and set alarm time.
{
if (Serial.available() > 0 && b_menu == true) { //if the user has sent something
// hi_message();
Serial.println ("you entered bluettoht");
input = Serial.read(); //read and clear the stack
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Connected!!!");
digitalWrite(buzzer, HIGH);
delay(10);
digitalWrite(buzzer, LOW);
delay (2000);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("0 -> Set Alarm");
lcd.setCursor(0, 1);
lcd.print("x -> Exit");
Serial.println("0-> Set Alarm ");
Serial.println("x -> Exit Anytime"); //Display the options
waiting_to_receive ();
input = Serial.read();
if (input == '0') //if user sent 0
{
digitalWrite(buzzer, HIGH);
delay(10);
digitalWrite(buzzer, LOW);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("0-> SleepAlarm");
lcd.setCursor(0, 1);
lcd.print("1-> WakeUpAlarm");
Serial.println("Setting Alarm");
Serial.println("0-> Sleep alarm");
Serial.println("1 -> Wake up Alarm"); //give alarm options
waiting_to_receive ();
input = Serial.read();
if (input == '0')
{
digitalWrite(buzzer, HIGH);
delay(10);
digitalWrite(buzzer, LOW);
Serial.println("Go to sleep at:");
s_alarm_h = alarm_hours ();
s_alarm_m = alarm_mins ();
Serial.print("Sleep alarm set at: ");
lcd.clear();
lcd.setCursor(4, 0);
lcd.print(s_alarm_h);
Serial.print(s_alarm_h);
lcd.print(" : ");
Serial.print(" : ");
lcd.print(s_alarm_m);
Serial.println(s_alarm_m);
EEPROM.write(2, s_alarm_h);
EEPROM.write(3, s_alarm_m);
}
if (input == '1')
{
digitalWrite(buzzer, HIGH);
delay(10);
digitalWrite(buzzer, LOW);
Serial.println("Wake me at:");
w_alarm_h = alarm_hours ();
w_alarm_m = alarm_mins ();
Serial.print("Wake up alarm set at: ");
lcd.clear();
lcd.setCursor(4, 0);
lcd.print(w_alarm_h);
Serial.print(w_alarm_h);
lcd.print(" : ");
Serial.print(" : ");
lcd.print(w_alarm_m);
Serial.println(w_alarm_m);
EEPROM.write(0, w_alarm_h);
EEPROM.write(1, w_alarm_m);
}
}
if (input == 'x') //exit from Serial mode
{
digitalWrite(buzzer, HIGH);
delay(10);
digitalWrite(buzzer, LOW);
// Serial.flush();
// input = Serial.read();
input = 0;
b_menu = false;
Serial.println("Back to main");
}
if (input == 'o' || input == 'O') //exit from Serial mode
{
digitalWrite(buzzer, HIGH);
delay(10);
digitalWrite(buzzer, LOW);
// Serial.flush();
// input = Serial.read();
b_menu = false;
iris.write(openangle);
}
if (input == 'c' || input == 'C') //exit from Serial mode
{
digitalWrite(buzzer, HIGH);
delay(10);
digitalWrite(buzzer, LOW);
// Serial.flush();
// input = Serial.read();
b_menu = false;
iris.write(closeangle);
}
if (input == 'L' || input == 'l') //exit from Serial mode
{
digitalWrite(buzzer, HIGH);
delay(10);
digitalWrite(buzzer, LOW);
Serial.flush();
input = Serial.read();
b_menu = false;
}
}
}
/////////////////////////////////Showing Time function/////////////////
void showing_time_date ()
{
DateTime now = rtc.now();
lcd.clear();
// lcd.print("Current Date & Time:");
// Serial.print(now.year(), DEC);
//lcd.clear();
lcd.setCursor(1, 1);
lcd.print(now.year(), DEC);
lcd.print('/');
// Serial.print('/');
//Serial.print(now.month(), DEC);
lcd.print(now.month(), DEC);
//Serial.print('/');
lcd.print('/');
//Serial.print(now.day(), DEC);
lcd.print(now.day(), DEC);
//Serial.print("(");
lcd.print("(");
//Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
//Serial.print(")");
lcd.print(")");
// Serial.print(now.hour(), DEC);
//lcd.clear();
lcd.setCursor(4, 0);
lcd.print(now.hour(), DEC);
//Serial.print(':');
lcd.print(':');
//Serial.print(now.minute(), DEC);
lcd.print(now.minute(), DEC);
//Serial.print(':');
lcd.print(':');
//Serial.print(now.second(), DEC);
lcd.print(now.second(), DEC);
//Serial.println();
delay(1000);
}
////////////////////////////////Turn on the Iris mechanism every 6 hours /////////////
void Irisopenseach6 ()
{
DateTime now = rtc.now();
if (now.hour() == 6 || now.hour() == 12 || now.hour() == 18 || now.hour() == 0 )
{
if (now.minute() == 0)
{
///////lights on!!!
iris.write(openangle);
}
// iris mechanism open angle
}
if (now.hour() == 6 || now.hour() == 12 || now.hour() == 18 || now.hour() == 0 )
{
if (now.minute() == 1)
{
iris.write(closeangle);
/////lights off!!!
}
// iris mechanism close angle
}
}
/////////////////////////////////Activating the Ultrasonic sensor to switch the alarm////////////////
int alarm_switch ()
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration * 0.034 / 2;
// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.println(distance);
return distance;
}
/////////////////////////////////////////////////////////////////Functions concerns the Neopixel matrix (from the tutorial above)
// Fill the pixels one after the other with a color
void colorWipe(RGB color, uint8_t wait) {
for (uint16_t row = 0; row < 8; row++) {
for (uint16_t column = 0; column < 8; column++) {
matrix.drawPixel(column, row, matrix.Color(color.r, color.g, color.b));
matrix.show();
delay(wait);
}
}
}
// Fade pixel (x, y) from startColor to endColor
void fadePixel(int x, int y, RGB startColor, RGB endColor, int steps, int wait) {
for (int i = 0; i <= steps; i++)
{
int newR = startColor.r + (endColor.r - startColor.r) * i / steps;
int newG = startColor.g + (endColor.g - startColor.g) * i / steps;
int newB = startColor.b + (endColor.b - startColor.b) * i / steps;
matrix.drawPixel(x, y, matrix.Color(newR, newG, newB));
matrix.show();
delay(wait);
}
}
//////////////////////////////////Function to light the Neomatrix with the colour I want and got its ration from: https://www.color-hex.com/color-palette/16675
void Madarasusanoo() {
// This 8x8 array represents the LED matrix pixels.
// A value of 1 means we’ll fade the pixel to white
int logo[8][8] = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1}
};
for (int row = 0; row < 8; row++) {
for (int column = 0; column < 8; column++) {
if (logo[row][column] == 1) {
fadePixel(column, row, off, madarasusanoo, 1, 1);
}
}
}
}
void setup ()
{
Serial.begin(9600);
RTC_begins ();
LCD_begins ();
iris.attach(8);
iris.write(closeangle);
pinMode(buzzer, OUTPUT);
digitalWrite (buzzer, LOW);
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT);
//////////////////////////////as if the power went out for some reason the alarm would still start on the same pre-decided time
w_alarm_h = EEPROM.read(0);
w_alarm_m = EEPROM.read(1);
s_alarm_h = EEPROM.read(2);
s_alarm_m = EEPROM.read(3);
////////////////////////////////////
matrix.begin();
matrix.setBrightness(30);
matrix.setTextColor( matrix.Color(255, 255, 255) );
matrix.setTextWrap(false);
///////////////// Welcome message
lcd.print("Welcome !!");
delay(3000);
}
void loop ()
{
digitalWrite (buzzer, LOW);
// hi_message ();
b_menu = true;
DateTime now = rtc.now();
current_h = now.hour();
current_m = now.minute();
Bluetoothcommunication();
showing_time_date ();
Irisopenseach6 ();
Madarasusanoo();
if (w_alarm_h == now.hour())
{
if (w_alarm_m == now.minute())
{
lcd.clear();
alarm_switch ();
if (distance > 5 && distance < 10)
{
digitalWrite (buzzer, LOW);
lcd.setCursor(4, 0);
lcd.print("AlarmOFF!");
// lights off!!!!!!
iris.write(closeangle);
delay (3000); //clear LCD, "wake uppppp!", buzzer, servo
}
else
{
//lights on !!!!
digitalWrite (buzzer, HIGH);
iris.write(openangle);
delay(100);
digitalWrite (buzzer, LOW);
iris.write(closeangle);
delay(100);
lcd.setCursor(4, 0);
lcd.print("WakeUPPP!");
}
}
}
if (s_alarm_h == now.hour())
{
if (s_alarm_m == now.minute())
{
lcd.clear();
alarm_switch ();
if (distance > 5 && distance < 10)
{
digitalWrite (buzzer, LOW);
lcd.setCursor(4, 0);
lcd.print("AlarmOFF!");
// lights off!!!!!!
iris.write(closeangle);
delay (3000); //clear LCD, "wake uppppp!", buzzer, servo
}
else
{
//lights on !!!!
digitalWrite (buzzer, HIGH);
iris.write(openangle);
delay(100);
digitalWrite (buzzer, LOW);
iris.write(closeangle);
delay(100);
lcd.setCursor(4, 0);
lcd.print("Sleep!");
}
}
}
}
/*void hi_message ()
{
char h;
char i;
////taking the values
Serial.println ("Send ""Hi"" to activate the Serial module");
waiting_to_receive ();
h = Serial.read();
Serial.println(h);
delay(100);
waiting_to_receive ();
i = Serial.read();
Serial.println(i);
if (h == 'h' || h == 'H')
{
if (i == 'i' || i == 'I')
{
Serial.println ("connected");
Serial.println ("connected");
b_menu = true;
}
}
}*/
I started by displaying the current time on the LCD dispaly then I tried to connect the servo motor to the circuit as shown in the video......
Here I am testing the Alarming system with the Bluetooth input
Here testing the Neopixel Matrix
Here testing the Iris mechanism with the servo Motor....
Unfortunately I don't have visuals for the testing after the full assembly but I had a really hard time ....
Things I needed help with/ Things I've learnt:
Flex wood: As I said I searched for patterns of the flex wood until I came by an online generator and I asked Instructor Maha for help with the parameters
I asked Marwa Sobhi for help with the Flex wood and she suggested this tutorial.
The Iris mechanism had a problem with in it and Eman Yasser helped me by using a grinding paper to smooth the gear and to make it shorter.
I was a bit lost with the Neopixel Matrix so I asked Menna Yousri for suggestions she suggested this tutorial and it was helpful.
Challenges I faced:
As I said I downloaded the Iris mechanism parts as STL files which when impoted to Fusion 360 they become a Mesh file which can't be edited some I search a lot to find the quickest and easiest way to follow to convert a mesh file to a solid body which can be mived, edited and making projections of it....
I spent a lot of time searching for a way to enable me to send more than one value to the Arduino through the blue tooth module until I found this tutorial it contained functions I didn't know like Serial.flush() and libraries like EEPROM.
I would complete the Nice to have features and edited some flaws with the design and I would have painted the project and made it cooler.