IOT-2020-Efrei-M1-Clock
My goal for this project was to make a connected alarm clock.
For those of us who still use traditional clock radios, we know how impractical it can be to only be able to settle one alarm at a time. (maybe two if we chose a good one)
Every night, we have to check if the settled alarm is right for the next day, the risk being to forget and not to wake up in time.
For those who are not morning persons, putting several alarms is not really an option, and increasing or decreasing the time by pushing two buttons to settle our alarm is not the fastest method, we may loose a lot of time if we have to change our wake-up time often.
My project was to make an alarm clock that could solve all these inconveniences.
Slides & Videos
Members
Name | Contribution |
---|---|
Jade Morin | Because of COVID-19, I could not come on the school's campus and was not allowed to have a partner on this project. I had to do the whole project by myself. It may not seem as evolved as some of my classmates projects, but it is fully operational, it meets all the expectations I wanted to fulfill with my project, and I had to do it all alone and from a far. |
State of the Art
Business Aspect
Assistant vocal Amazon Echo Show 8 Anthracite
When we search “connected alarm clock” on Internet, the first result is an article that compares 10 connected alarm clock to help us chosse the best one.
According to the article, the best one on the market, and the one with the best price/performance ratio is the “Assistant vocal Amazon Echo Show 8 Anthracite”. But when we take a closer look at the main features that all these products offer, we realize that they have a completely different purpose, and just happen to also give time. Most of them are voice assistant and are used as a communication interface with connected objects such as Alexa, or Google Home. They may be really usefull, but their technology level impact their prices. As an example, the Assistant vocal Amazon Echo Show 8 Anthracite is sold for 130euros, when my connected alarm clock has a “production cost” of approximately 50 euros.
When we look closer, we can see that nothing in the business field has actually the same purpose than the project I made, for the same price.
Technical Aspect
When we search “Arduino connected alarm clock” on Internet, there are a few interesting results. The first one is an article explaining how to make your own alarm clock using Arduino. The ones that follows are often by the same person, and they are all very interesting, but when we take a closer look and read them all, we realize that none of them is actually connected.
It would seem that the project I wanted to make has not been made often, or if so, that the people who made it did not share their experience yet.
Project Description
Problem Definition
So I decided to make my own connected alarm clock that would solve all these inconvenience.
Challenges &Β Motivation
Also, I had to build a whole website as an interface to settle all the alarms the user could want, and being able to activate them or not.
My motivations were that this object is an object that is usefull everyday, but nothing on the market proposes something like what I imagined.
Real and Complete Usecases
Example of Use Case :
-The user sets all the alarms he wants on the website.
-With several WiFi libraries, the computer collects all the alarms that are activated (because if the user does not want an alarm to ring he can deactivate it)
-The computer reads and stores the time that he must ring to
-When it is time, the connected alarm clock rings
-The user push the button and it stops the alarm
Technical Description
In terms of connections, the system is relatively simple. Here is the schematic of the project. I used the Arduino Uno WiFi Rev2 so i did not have to buy a WiFi module to add on my breadboard. With the module RTC and the Wifi module, I connect to a server which gives me the number of seconds since the 1st January of 1900 and converts it in Unix time. Since I get the UTC time, i add 3600 seconds to get the local time.
With an HTTP GET, I recuperate all the alarms that the user has activated as a String. (For example, if there are two alarms activated, 12:00 and 13:32, I recuperate “12:0013:32”) Then I parse it for the system to be able to “read” it. When the hour is the same that the alarms the computer stores, the alarm rings.
The Arduino system is not too complex, but it was not easy to build a whole website, and to connect to it to only get the alarms.
Here are 2 images, one of the website, and one of the output I get when I run my code.
Β
Hardware
Materials
Image | Name | Part Number | Price | Count | Link |
---|---|---|---|---|---|
Arduino UNO WiFi Rev2 | 1 | 38.90 euros | 1 | π | |
Breadboard | 2 | 5.67 euros | 1 | π | |
Arduino LCD 1602 | 3 | 4.50 euros | 1 | π | |
RTC DS3231 | 4 | 4.99 euros | 1 | π | |
Potentiometer | 5 | 0.89 euros | 1 | π | |
Push Button | 6 | 0.35 euros | 1 | π | |
Resistor 220 OHM | 7 | 0.05 euros | 2 | π | |
Active Buzzer | 8 | 0.70 euros | 1 | π | |
Fils connecteurs | 9 | 2.57 euros | About 30 | π |
Schematic
Software
Arduino Code
#include#include #include #include #include #include #include #include "LiquidCrystal.h" #include "arduino_secrets.h" char ssid[] = SECRET_SSID; char pass[] = SECRET_PASS; int status = WL_IDLE_STATUS; unsigned int localPort = 2390; IPAddress timeServer(129, 6, 15, 28); const int NTP_PACKET_SIZE = 48; byte packetBuffer[ NTP_PACKET_SIZE]; byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0xA5, 0x7E }; IPAddress ip(192,168,0,143); WiFiClient client; WiFiUDP Udp; DS3231 Clock; LiquidCrystal lcd(12, 11, 5, 4, 3, 2); time_t present; const int broBuzzer = 9; volatile int alarm = 0; String current_alarm=""; void setup() { pinMode(broBuzzer, OUTPUT); attachInterrupt (13, stopAlarm, CHANGE); Serial.begin(57600); lcd.begin(16,2); while (!Serial) { } if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); while (true); } String fv = WiFi.firmwareVersion(); if (fv < WIFI_FIRMWARE_LATEST_VERSION) { Serial.println("Please upgrade the firmware"); } while (status != WL_CONNECTED) { Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid); status = WiFi.begin(ssid, pass); delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); Serial.println("\nStarting connection to server..."); Udp.begin(localPort); sendNTPpacket(timeServer); delay(1000); if (Udp.parsePacket()) { Serial.println("packet received"); Udp.read(packetBuffer, NTP_PACKET_SIZE); unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); unsigned long secsSince1900 = highWord << 16 | lowWord; Serial.print("Seconds since Jan 1 1900 = "); Serial.println(secsSince1900); Serial.print("Unix time = "); const unsigned long seventyYears = 2208988800UL; unsigned long epoch = secsSince1900 - seventyYears + 3600L; Serial.println(epoch); Serial.print("The local time is "); Serial.print((epoch % 86400L) / 3600); Serial.print(':'); if (((epoch % 3600) / 60) < 10) { Serial.print('0'); } Serial.print((epoch % 3600) / 60); Serial.print(':'); if ((epoch % 60) < 10) { Serial.print('0'); } Serial.println(epoch % 60); setTime(epoch); } } void loop() { int x=0; char body_start='['; char body_end=']'; String HTTPoutputString = ""; int HTTP_PORT = 80; String HTTP_METHOD = "GET"; char HOST_NAME[] = "alarmes.jademorin.fr"; String PATH_NAME = "/alarms.json"; if(client.connect(HOST_NAME, HTTP_PORT)) { Serial.println("Connected to server"); client.println(HTTP_METHOD + " " + PATH_NAME + " HTTP/1.1"); client.println("Host: " + String(HOST_NAME)); client.println("Connection: close"); client.println(); while(client.connected()) { if(client.available()){ char c = client.read(); if (c==body_start) x=(x+1); if (x==1 && c!=body_start && c!=body_end && c!='"' && c!=',') HTTPoutputString += c; if (c==body_end) x=(x+1); } } Serial.println(HTTPoutputString); int stockage_len = HTTPoutputString.length()/5; String stockage[stockage_len]; for(int i=0 ; HTTPoutputString[i] != '\0'; i=i+5) { String time=""; for(int j=0 ; j<5; j++) { time = time + char(HTTPoutputString[i+j]); } stockage[i/5]= time; } String current_time = time_format(hour()) + ":" + time_format(minute()); for (int i = 0; i < stockage_len; i++) { Serial.println(stockage[i]); if (current_time == stockage[i] && stockage[i]!=current_alarm) { current_alarm=stockage[i]; alarm = 1; } } sonnerAlarme(); if(!client.connected()) { Serial.println("disconnected"); client.stop(); } } else { Serial.println("connection failed"); } time_t tm; tm = now(); if (tm) { Serial.print("Ok, Time = "); print2digits(hour()); Serial.write(':'); print2digits(minute()); Serial.write(':'); print2digits(second()); Serial.print(", Date (D/M/Y) = "); Serial.print(day()); Serial.write('/'); Serial.print(month()); Serial.write('/'); Serial.print(year()); Serial.println(); } delay(500); present = now(); reafficher(); } void printWifiData() { IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); Serial.println(ip); byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void printCurrentNet() { Serial.print("SSID: "); Serial.println(WiFi.SSID()); byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 5; i >= 0; i--) { if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); if (i > 0) { Serial.print(":"); } } Serial.println(); } unsigned long sendNTPpacket(IPAddress& address) { memset(packetBuffer, 0, NTP_PACKET_SIZE); packetBuffer[0] = 0b11100011; packetBuffer[1] = 0; packetBuffer[2] = 6; packetBuffer[3] = 0xEC; packetBuffer[12] = 49; packetBuffer[13] = 0x4E; packetBuffer[14] = 49; packetBuffer[15] = 52; Udp.beginPacket(address, 123); Udp.write(packetBuffer, NTP_PACKET_SIZE); Udp.endPacket(); } void print2digits(int number) { if (number >= 0 && number < 10) { Serial.write('0'); } Serial.print(number); } String time_format(int number) { String number_format = ""; if (number >= 0 && number < 10) { number_format = "0"+String(number); } else { number_format = String(number); } return number_format; } void reafficher(){ int h = hour(); int m = minute(); int s = second(); lcd.setCursor(2, 0); lcd.print("Horloge Jade"); lcd.setCursor(4, 1); if (h<10){ lcd.print(0); } lcd.print(h); lcd.setCursor(6, 1); lcd.print(":"); lcd.setCursor(7, 1); if (m<10){ lcd.print(0); } lcd.print(m); lcd.setCursor(9, 1); lcd.print(":"); lcd.setCursor(10, 1); if (s<10){ lcd.print(0); } lcd.print(s); } void sonnerAlarme() { float frequenceAL=1400; float periodeAL = (1.0 / frequenceAL) * 1000000; long dureeBip = 50000; long tempsPasse = 0; while (tempsPasse < dureeBip && alarm == 1) { digitalWrite(broBuzzer,HIGH); delayMicroseconds(periodeAL / 2); digitalWrite(broBuzzer, LOW); delayMicroseconds(periodeAL / 2); tempsPasse += (periodeAL); } delayMicroseconds(dureeBip); } void stopAlarm() { Serial.println("Interruption en cours"); alarm = 0; }
External Services
I built an entire website for the user to settle every alarm he wants.
He can either activate or deactivate them, depending on if he wants them to ring or not, and he can put as many alarms as he wants.
He can put an alarm whenever he wants, from wherever he wants, for whenever he wants.
To see the website, you can go to alarmes.jademorin.fr