Our clock project

Dependencies:   SPI_TFT_ILI9341 TFT_fonts Adafruit_RTCLib RTC-DS1307 TSI

IoT Clock

We have been given a task to design a clock with internet features, the 'Internet Clock'. First of all, we identified what features we want:

Display: Split into 4 parts:

  • Analogue clock - the good ol' fashioned circle display, complete with minute, hour and second hands.
  • Digital clock - equipped with date for the modern human.
  • Weather display - for those who cannot be bothered to look out of the window.
  • Alarm - just what you need when you have to get up or be somewhere.

Wifi module:

  • For collecting data for weather, alarm times and so it can be an 'Internet Clock'.

Speaker:

  • To make the annoying sound to let you know your alarm is going off.

Range finder:

  • To wave your hand in front of to turn the alarm off, because pressing a button is too last centurary.

The roles:

  • Soroush's first task was to get the LCD screen to work. Meanwhile Adam sorted out the speaker system.
  • When these were done, Adam worked on the screen to display a clock face and date/year. Soroush then connected the wifi module to extract data for weather, location and date. /media/uploads/amilner1/img_0285.jpg Connecting the wifi module.
  • The next part was to get the range-finder hooked up and responding to a hand passing, and switch the alarm off.
  • Finally, it was time for assembly.

Difficulties: There were many issues faced throughout the project. First of all, Adam's coding knowledge was a lot less than Soroush's which slowed down some completion of tasks. Although, this did help us sort out the roles. Next was the wifi connectivity which caused several problems during the project, and we couldn't get the connection or fetch data, which further slowed the process. Another difficulty was finding the range-finder's set-up page for mbed. However, when we got past these set backs we managed to put everything together quickly, /media/uploads/amilner1/img_0294.jpg All the hardware wired in.

Outcome:

  • Our LCD screen has 2 displays:
  1. 1 An analogue clock filling the screen.

/media/uploads/amilner1/img_0304.jpg

  1. 2 An analogue clock, date and year, weather and location, and alarm time.

/media/uploads/amilner1/img_0305.jpg

This is changed by holding (not passing quickly) your hand in front of the range-finder.

  • An RTC to keep track of the time rather than collecting the information from then internet. However, we have had a lot of problems setting this up, and it doesn't seem to respond.
  • Wifi is also not connected, so we have the default date, time, weather and location.
  • You are able to change the alarm time by swiping the touch pad on the back.

Perhaps given more time we'd be able to fix these problems. But a key point is that we have got all the other features working, except the correct time. /media/uploads/amilner1/img_0303.jpg

Files at this revision

API Documentation at this revision

Comitter:
sfaghihi
Date:
Thu May 25 21:56:06 2017 +0000
Parent:
18:2afeed90c051
Child:
20:e8ff6955c24e
Child:
21:fe1769d5a01c
Commit message:
safety

Changed in this revision

Adafruit_RTCLib.lib Show annotated file Show diff for this revision Revisions of this file
Display.cpp Show annotated file Show diff for this revision Revisions of this file
Display.h Show annotated file Show diff for this revision Revisions of this file
SPI_TFT_ILI9341.lib Show annotated file Show diff for this revision Revisions of this file
TSI.lib Show annotated file Show diff for this revision Revisions of this file
Wifi.cpp Show annotated file Show diff for this revision Revisions of this file
Wifi.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
utility.cpp Show annotated file Show diff for this revision Revisions of this file
utility.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_RTCLib.lib	Thu May 25 21:56:06 2017 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/nkhorman/code/Adafruit_RTCLib/#2c4e81ecda67
--- a/Display.cpp	Thu May 25 03:30:05 2017 +0000
+++ b/Display.cpp	Thu May 25 21:56:06 2017 +0000
@@ -727,7 +727,10 @@
 void Display::drawAlarm(TimeClass *alarmTime)
 {
     myTFT.fillrect(160, 165, myTFT.width(), myTFT.height(), Black);
-    myTFT.foreground(Red);
+    if (alarmTime->second < 0)
+        myTFT.foreground(Green);
+    else
+        myTFT.foreground(Red);
     myTFT.set_font((unsigned char*)Arial24x23);
     myTFT.locate(160,200);
     //LOG("OUTDATE\r\n");
@@ -738,6 +741,28 @@
     myTFT.foreground(White);
 }
 
+void Display::flashAlarmSet(TimeClass *alarmTime, int set_alarm_state)
+{
+    if (alarmTime->second < 0)
+        myTFT.foreground(Green);
+    else
+        myTFT.foreground(Red);
+    myTFT.set_font((unsigned char*)Arial24x23);
+    if (set_alarm_state == 1)
+        myTFT.fillrect(155, 195, 175, myTFT.height(), Black);
+    else if (set_alarm_state == 2)
+         myTFT.fillrect(175, 195, 195, myTFT.height(), Black);
+    else if (set_alarm_state == 3)
+        myTFT.fillrect(195, 195, 230, myTFT.height(), Black);
+    wait(1);
+    char buf[15];
+    sprintf(buf, "%02d:%02d %s\n", alarmTime->hour == 12 ? 12 : alarmTime->hour%12, alarmTime->minute, alarmTime->hour>=12 ? "p.m." : "a.m.");
+    myTFT.locate(160,200);
+    text(160, 200, buf);
+    myTFT.set_font((unsigned char*)Arial12x12);
+    myTFT.foreground(White);
+}
+
 void Display::drawAll(StateClass *state, bool doCls)
 {
     if (doCls)
--- a/Display.h	Thu May 25 03:30:05 2017 +0000
+++ b/Display.h	Thu May 25 21:56:06 2017 +0000
@@ -6,12 +6,12 @@
 //#include "font_big.h"
 
 // The connection configuration for FRDM-KL25Z
-#define DISPLAY_MOSI_PIN PTD2
-#define DISPLAY_MISO_PIN PTD3
-#define DISPLAY_SCLK_PIN PTD1
-#define DISPLAY_CS_PIN PTC7
-#define DISPLAY_RST_PIN PTC0
-#define DISPLAY_DC_PIN PTC3 // dc is WR not
+#define DISPLAY_MOSI_PIN PTD6
+#define DISPLAY_MISO_PIN PTD7
+#define DISPLAY_SCLK_PIN PTD5
+#define DISPLAY_CS_PIN PTD3
+#define DISPLAY_RST_PIN PTA4
+#define DISPLAY_DC_PIN PTA12 // dc is WR not
 
 //graphics
 
@@ -28,5 +28,6 @@
         void drawAlarm(TimeClass *alarmTime);
         void drawDate(DateClass *date);
         void drawAll(StateClass *state, bool doCls);
+        void flashAlarmSet(TimeClass *alarmTime, int set_alarm_state);
         void cls();
 };
\ No newline at end of file
--- a/SPI_TFT_ILI9341.lib	Thu May 25 03:30:05 2017 +0000
+++ b/SPI_TFT_ILI9341.lib	Thu May 25 21:56:06 2017 +0000
@@ -1,1 +1,1 @@
-https://developer.mbed.org/teams/Pinky-and-the-Brain/code/SPI_TFT_ILI9341/#8b57440bd937
+https://developer.mbed.org/teams/Pinky-and-the-Brain/code/SPI_TFT_ILI9341/#46591934ec48
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TSI.lib	Thu May 25 21:56:06 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/emilmont/code/TSI/#507b1f67804b
--- a/Wifi.cpp	Thu May 25 03:30:05 2017 +0000
+++ b/Wifi.cpp	Thu May 25 21:56:06 2017 +0000
@@ -28,11 +28,15 @@
 
 char *Wifi::getTimeDate()
 {
+    LOG("IN HERE\r\n");
     socket.open(&esp);
+    LOG("Socket opened\r\n");
     socket.connect(TD_HOST, TD_PORT);
+    LOG("Socket connected\r\n");
     socket.send("time\r\n", 6);
-    char *data = (char *)calloc(22, 1);
+    char *data = (char *)calloc(23, 1);
     socket.recv(data, 22);
+    LOG("Data: %s\r\n", data);
     socket.close();
     return data;
 }
\ No newline at end of file
--- a/Wifi.h	Thu May 25 03:30:05 2017 +0000
+++ b/Wifi.h	Thu May 25 21:56:06 2017 +0000
@@ -4,7 +4,7 @@
 #define BUFF_SIZE 100
 #define ESP_TX PTE22
 #define ESP_RX PTE23
-#define ESP_RST PTC5
+#define ESP_RST PTC16
 #define TD_HOST "67.205.147.133"
 #define TD_PORT 5005
 
--- a/main.cpp	Thu May 25 03:30:05 2017 +0000
+++ b/main.cpp	Thu May 25 21:56:06 2017 +0000
@@ -1,13 +1,19 @@
 #include "utility.h"
 #include "Display.h"
 #include "Wifi.h"
+#include "TSISensor.h"
+#include "DS1307.h"
 
 // Hardware abstractions
-//RawSerial pc_io(USBTX, USBRX);
+RawSerial pc_io(USBTX, USBRX, 115200);
 Display screen;
 Wifi wifi(WIFI_SSID, WIFI_PASS);
+TSISensor tsi;
 bool wifi_con = false;
 bool alarm_dup = false;
+int set_alarm_state = 0;
+int held_hand_time = 0;
+bool dist_dup = false;
 
 // The main program global states
 StateClass *programState = NULL;
@@ -26,14 +32,14 @@
 void init_state_hw()
 {
     //pc_io.baud(115200);
-    /*if (wifi.connect())
+    if (wifi.connect())
         wifi_con = true;
     else
-        LOG("NO");*/
+        LOG("NO");
     programTime = new TimeClass(11, 0, 0);
     programPrevTime = new TimeClass(11, 0, 0);
     programDate = new DateClass(11, 11, 1918, 1);
-    programAlarm = new TimeClass(9, 0, 0);
+    programAlarm = new TimeClass(9, 0, -1);
     programWeather = new WeatherClass(sunny, 18, true, (char *)WEATHER_PLACE);
     //LOG("MOK");
     programState = new StateClass(programTime, programPrevTime, programWeather, programDate, programAlarm);
@@ -41,6 +47,31 @@
     programState->duringAlarm = true;
 }
 
+#define MIN_CAL 62.0
+#define HOUR_CAL 12.0
+
+void setAlarmTime()
+{
+    while (set_alarm_state != 0)
+    {
+        if (tsi.readPercentage()>0)
+        {
+            float tsp = tsi.readPercentage();
+            if (set_alarm_state == 1)
+                programAlarm->hour = programAlarm->hour < 12 ? tsp*HOUR_CAL : (12 + tsp*HOUR_CAL);
+            else if (set_alarm_state == 2)
+                programAlarm->minute = MIN_CAL*tsp;
+            else if (set_alarm_state == 3)
+                if (tsp > 0.5 && programAlarm->hour < 12)
+                    programAlarm->hour += 12;
+                else if (tsp < 0.5 && programAlarm->hour > 12)
+                    programAlarm->hour -= 12;
+        }
+        screen.flashAlarmSet(programAlarm, set_alarm_state);
+        wait(0.2);
+    }
+}
+
 void refresh_and_inc()
 {
     //led1 = !led1;
@@ -52,7 +83,7 @@
     else if (programState->screenState == 1)
         screen.drawClockBig(programTime, false, programPrevTime);
     
-    if (programTime->hour == programAlarm->hour && programTime->minute == programAlarm->minute) {
+    if (programTime->hour == programAlarm->hour && programTime->minute == programAlarm->minute && programAlarm->second >= 0) {
         if (!alarm_dup) {
             alarm_dup = true;
             programState->duringAlarm = true;
@@ -65,9 +96,22 @@
         if (programState->duringAlarm)
             programState->duringAlarm = false;
         else {
+            held_hand_time ++;
+            if (!dist_dup && held_hand_time >= CHANGE_SET_ALARM_TIME) {
+                dist_dup = true;
+                set_alarm_state = (set_alarm_state + 1)%4;
+                if (set_alarm_state == 1)
+                    setAlarmTime();
+            }
+        }
+    } else {
+        dist_dup = false;
+        if (held_hand_time >= CHANGE_SCREEN_TIME && held_hand_time < CHANGE_SET_ALARM_TIME && set_alarm_state == 0 && programState->screenState==0) {
+            set_alarm_state = 0;
             programState->screenState = 1 - programState->screenState;
             screen.drawAll(programState, true);
         }
+        held_hand_time = 0;
     }
             
     //printf("HAH");
@@ -84,11 +128,15 @@
 
 void fetch_data()
 {
-    //LOG("Fetch happening\r\n");
+    LOG("Fetch happening\r\n");
     // NB Use the wifi module at some point
     if (!wifi_con)
         return;
-    char *data = NULL;//wifi.getTimeDate();
+    LOG ("GOT DATA!!!\r\n");
+    char *data = NULL;
+    data = wifi.getTimeDate();
+    if (!data)
+        return;
     int s, m, h, d, mo, y, dow, t;
     sscanf(data, "%d,%d,%d,%d,%d,%d,%d,%d", &s, &m, &h, &d, &mo, &y, &dow, &t);
     free(data);
@@ -149,6 +197,8 @@
 int main() 
 {
     init_state_hw();
+    read_rtc(programState);
+    fetch_data();
     //LOG("AFTER\r\n");
     //printf("OI OI");
     
@@ -159,9 +209,9 @@
     
     clockTimer.attach(&refresh_and_inc, REFRESH_PERIOD);
     fetchTimer.attach(&fetch_data, FETCH_PERIOD);
-    alarmTimer.attach(&stopAlarm, 40);
+    //alarmTimer.attach(&stopAlarm, 40);
     
-    playAlarmSound(programState);
+    //playAlarmSound(programState);
     //LOG("YAY\r\n");
     // Infinite loop
     while (true) {
--- a/utility.cpp	Thu May 25 03:30:05 2017 +0000
+++ b/utility.cpp	Thu May 25 21:56:06 2017 +0000
@@ -45,8 +45,8 @@
     }
 }
 
-AnalogIn ain(PTB0);
-DigitalOut cs(PTD0, 0);
+AnalogIn ain(RANGE_AN);
+DigitalOut cs(RANGE_CS, 0);
 
 bool getDistance()
 {
@@ -54,7 +54,35 @@
     cs = 1;
     wait_us(30);
     adc = ain.read();           // read analog as a float
-    volts = adc * 3.3;          // convert to volts
-    inches = volts / 0.0064;
+    volts = adc * 4.5;          // convert to volts
+    inches = volts / 0.0095;
+    cs = 0;
     return inches <= RANGE_THRESHOLD;
+}
+
+I2C master(RTC_SDA, RTC_SCL);
+RtcDs1307 rtc(master);
+void read_rtc(StateClass *ps)
+{
+    LOG("IN RTC\r\n");
+    DateTime data = rtc.now();
+    LOG("%d:%d:%d", data.hour(), data.minute(), data.second());
+    if (!rtc.isRunning())
+        return;
+    ps->time->hour = data.hour();
+    ps->prevTime->hour = data.hour();
+    ps->time->minute = data.minute();
+    ps->prevTime->minute = data.minute();
+    ps->time->second = data.second();
+    ps->prevTime->second = data.second();
+    ps->date->year = data.year();
+    ps->date->day = data.day();
+    ps->date->month = data.month();
+    ps->date->dow = data.dayOfWeek();
+}
+
+void update_rtc(StateClass *ps)
+{
+    DateTime data(ps->date->year, ps->date->month, ps->date->day, ps->time->hour, ps->time->minute, ps->time->second);
+    rtc.adjust(data);
 }
\ No newline at end of file
--- a/utility.h	Thu May 25 03:30:05 2017 +0000
+++ b/utility.h	Thu May 25 21:56:06 2017 +0000
@@ -7,15 +7,25 @@
 #include "math.h"
 #include "string"
 #include "string.h"
+#include "DS1307.h"
 
 // Some macros
 extern RawSerial pc_io;
-#define LOG(...) //pc_io.printf(__VA_ARGS__)
+#define LOG(...) pc_io.printf(__VA_ARGS__)
 #define M_PI  3.14159265358979323846  /* pi */
 #define REFRESH_PERIOD 1  // (s)
 #define FETCH_PERIOD 3600
-#define ALARM_PIN PTE21
 #define RANGE_THRESHOLD 9.0 // (inches)
+#define CHANGE_SCREEN_TIME 1
+#define CHANGE_SET_ALARM_TIME 3
+
+// THe pin macros
+#define ALARM_PIN PTD4
+#define RTC_SDA PTC11 //PTC2
+#define RTC_SCL PTC10 //PTC1
+#define RANGE_AN PTB1
+#define RANGE_CS PTA5
+
 static const char *WEATHER_PLACE = "Oxford";
 static const char *WIFI_SSID = "VM1688183";
 static const char *WIFI_PASS = "brk3msjzKvCj";
@@ -66,5 +76,7 @@
 
 void playAlarmSound(StateClass *ps);
 bool getDistance();
+void read_rtc(StateClass *ps);
+void update_rtc(StateClass *ps);
 
 #endif
\ No newline at end of file