Project in progress

MultiFunctional Clock

Do you oversleep often, or can’t you get out of your bed? Our MultiFunctional Clock solves this problem.

  • 7,834 views
  • 2 comments
  • 13 respects

Components and supplies

A000066 iso both
Arduino UNO & Genuino UNO
We do not recommend using the Arduino UNO! It has insufficient onboard storage. We planned on using the Arduino 101 instead, but it is incompatible with the Sparkfun Color LCD Shield we use.
×1
Ard wifi101
Arduino Wifi Shield 101
We used an older version of this shield, not the 101.
×1
TP-LINK M5250 3G Mobile Wi-Fi
×1
Iotopia box rs
AllThingsTalk IOTOPIA Rapid Development kit
Grove Air Quality Sensor, Grove Buzzer, Grove Base Shield
×1
Sparkfun Color LCD Shield
×1
Sparkfun Real Time Clock Module
×1

Necessary tools and machines

Apps and online services

About this project


Hier kan je alles terugvinden in het Nederlands.

Introduction

We’ve all had this happen before: You go to a party, stay up late… and forget to set your alarm. It’s raining, or it’s freezing and snowing the next morning and you end up being late at work or school… again.

These are the sort of situations we want to prevent. We mainly designed the MultiFunctional Clock to do just that.

The alarm checks your digital calendar, the weather and the traffic in your region. By doing so, it determines when you should wake up by itself. Every day when you wake up, it will also suggest when you should go to bed. The MFC will also determine the optimal means of transport.

In addition, the MFC also checks the air quality in your room. You don't want to wake up feeling sick, do you?

Introductional Video

What we want to Do

As you can imagine, and have read, there are a lot of things that can interact with the MFC. 

Here you have a diagram:

Example situation:

   -   It's raining heavily, winds from the North.

   -   Today you have to work at 9:30 AM, tomorrow at 9:00 AM.

   -   You prefer going by bicycle, and you live more than 10 km away.

   -   In general, you take 40 minutes to prepare yourself.

It's raining, more people will go to their jobs and school by bus, train and car. If  you yourself are still going by bicycle or on foot, this won't affect you very much, but the opposite is true because of the wind... You'll probably get slowed down a lot either way!

Let's say that you have to be woken up 10 minutes earlier than normal: 8:20 AM

How we do It

Here you can see how to configure the MFC. (Sorry for the bad quality!)

Currently, you don't see the completed version of the code in the video. That is because we ran into difficulties quite a lot while making it.

The Arduino UNO we were using did not have sufficient PROGMEM and RAM for the code. If you try to reproduce, we recommend you use any board with the same size as the UNO, but with more storage. Also use a more modern LCD TFT Shield than we did.

The program will ask you the following things:

   -   How long do you usually take to get ready? (In minutes)

   -   What means of transport do you use? (Walk / Bicycle / Car)

Examples of questions that could be added in the future are:

   -   What's the name of your google calendar?

   -   Where do you live? 

   -   Where do you work?

   -   Do you want to use the snooze function? How long in between? (In minutes)

   -   Leave the screen on at all times?

The list goes on and on!

The answers could be saved in the EEPROM of the Arduino, so you don't need to answer them twice!

When you answered the questions successfully, it will authenticate with google. Go to the link (provided in the serial monitor)  with your favorite browser. Click on 'Allow'. Now the MFC is connected to your google account, which allows it you check your calendar.

We expect that the first event in your calendar is 'going to work or school'. You will be woken up with time to completely prepare yourself in the morning, and be on time, of course. Your calendar gets checked every 5 minutes, so don't you worry about missing a newly made appointment.

Air Quality

In the images below, you can see the air qualities (top left of the screen). It can detect 4 grades.

"Goed" / "Good": No worries, you'll sleep well.

"Aanvaardbaar" / "Acceptable": Could be better...

"Slecht" / "Bad": You should open your window...

"Leef je nog?!" / "How are you still alive?!": No explanation needed...

An alarm goes off when the grade gets worse than "Aanvaardbaar" / "Acceptable". The sound gets louder when the quality degrades.


Custom parts and enclosures

3D - Design
Our 3D model in .STP format.
3D-ontwerp.stp
3D - Design
A picture of our 3D model.
Mfc voorbeeld

Schematics

Scheme
Schema%20jpg
Scheme
Schema%20zijkant

Code

MFC - Air qualityArduino
This code gives a representation of how the air quality and time can be displayed. This code in combination with 'MFC- Alarm' code is our finished program.
//-----------------RTC----------------------------//
#include <Wire.h>
#include "RTClib.h"

#if defined(ARDUINO_ARCH_SAMD)      // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
   #define Serial SerialUSB
#endif

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag"};
char daysOfTheWeekShort[7][3] =  {"Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za"};

enum Dagen {
  
  Zondag,
  Maandag,
  Dinsdag,
  Woensdag,
  Donderdag,
  Vrijdag,
  Zaterdag
};

char scherm_bitbuffer[133];

//-----------------LCD----------------------------//

#include <SparkFunColorLCDShield.h>
#define BACKGROUND  WHITE           // Achtergrond
#define COLOR BLACK                 // This is the color of the clock face, and digital clock
#define COLOR_2 BLUE

LCDShield lcd;

char Uur[3];
char Minuten[3];
char Seconden[3];
char Dag[3];
char Maand[3];
char Jaar[3];

char Tijd_Nu[9];
char Tijd_alarm[6];

//-----------------AirQuality---------------------//

#include"AirQuality.h"
#include"Arduino.h"
AirQuality airqualitysensor;
int current_quality =-1;
//-------------------------------------------------------------------------------------//

void setup () {

  pinMode(3, OUTPUT);
  analogWrite(3, 0);
  
//-----------------instellingen scherm -----------//
  lcd.init(PHILIPS);
  lcd.contrast(50);
  lcd.clear(BACKGROUND);
//-----------------instellingen airquality -------//

Serial.begin(9600);
    airqualitysensor.init(14);
//-----------------RTC----------------------------//
#ifndef ESP8266
  while (!Serial);
#endif

  Serial.begin(9600);
  if (! rtc.begin()) {
     Serial.println("Couldn't find RTC ");
     lcd.setStr("Couldn't find RTC ", 20, 10, COLOR, BACKGROUND);
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
     lcd.setStr("RTC werkt niet! ", 20, 10, COLOR_2, BACKGROUND);
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}
//-------------------------------------------------------------------------------------//
void loop () {


    DateTime now = rtc.now();

//-----------------RTC- LCD shield----------------//

//tijd.

  

  lcd.setStr(itoa(now.hour(), Uur, 10), 45, 10, COLOR, BACKGROUND);
  lcd.setStr(":", 44, 26, COLOR, BACKGROUND);
  lcd.setStr(itoa(now.minute(), Minuten, 10), 45, 33, COLOR, BACKGROUND);
  lcd.setStr(":", 44, 49, COLOR, BACKGROUND);
  lcd.setStr(itoa(now.second(), Seconden, 10), 45, 56, COLOR, BACKGROUND);

//weekdag.
  lcd.setStr(daysOfTheWeek[now.dayOfTheWeek()], 70, 10, COLOR, BACKGROUND);

//datum.
  lcd.setStr(itoa(now.day(), Dag, 10), 103, 10, COLOR, BACKGROUND);
  lcd.setStr("/", 101 , 28, COLOR, BACKGROUND);
  lcd.setStr(itoa(now.month(), Maand, 10), 103, 37, COLOR, BACKGROUND);
  lcd.setStr("/", 101, 55, COLOR, BACKGROUND);
  lcd.setStr(itoa(now.year(), Jaar, 10), 103, 61, COLOR, BACKGROUND);


delay(500);  

//-----------------airquality---------------------//    
    current_quality=airqualitysensor.slope();
    if (current_quality >= 0)                                 // if a valid data returned.
    {
        if (current_quality==0) {
                  lcd.setStr("Leef je nog?! ", 5, 5, COLOR, BACKGROUND);
                  analogWrite(3, 20);
        }
        else if (current_quality==1) {
                  lcd.setStr("Slecht        ", 5, 5, COLOR, BACKGROUND);
                  analogWrite(3, 20);
        }
        else if (current_quality==2) {
                  lcd.setStr("Aanvaardbaar  ", 5, 5, COLOR, BACKGROUND);
                  analogWrite(3, 0);
        }
        else if (current_quality ==3){
                  lcd.setStr("Goed          ", 5, 5, COLOR, BACKGROUND);
                  analogWrite(3, 0);
        }
    }
}

ISR(TIMER1_OVF_vect)
{
  if(airqualitysensor.counter==61)//set 2 seconds as a detected duty
  {

      airqualitysensor.last_vol=airqualitysensor.first_vol;
      airqualitysensor.first_vol=analogRead(A0);
      airqualitysensor.counter=0;
      airqualitysensor.timer_index=1;
      PORTB=PORTB^0x20;
  }
  else
  {
    airqualitysensor.counter++;
  }

  
}
MFC - AlarmArduino
This code gives a representation of how the prog will work and how your calendar is read. This code in combination with 'MFC - Air quality' code is our finished program.

Note: At the moment there seems to be a problem with the moment the alarm goes off, but it does work.
#include <avr/pgmspace.h>
#include <SPI.h>
#include <Temboo.h>
#include <Wire.h>
#include <WiFi.h>
#include <WiFiClient.h>

#include "RTClib.h"
// #include "SparkFunColorLCDShield.h"

//////////////////////////////////////////////////////////////////////////////

char cBuffer_s_0[5];
char cBuffer_s_1[5];
char cBuffer_s_2[34];
char cBuffer_s_3[24];
char cBuffer_s_4[24];
char cBuffer_s_5[24];
char cBuffer_l_0[42];
char cBuffer_l_1[56];

char* cBuffer[8] = {

  cBuffer_s_0,
  cBuffer_s_1,
  cBuffer_s_2,
  cBuffer_s_3,
  cBuffer_s_4,
  cBuffer_s_5,
  cBuffer_l_0,
  cBuffer_l_1
};

String sBuffer;
String CallbackID;
String AccessToken;
DateTime* AccessToken_Time;
String RefreshToken;
String CalendarID;
DateTime* ReadCalendar_Time;

int Count;
bool Setup;

int MFC_WifiStatus;
WiFiClient MFC_WifiClient(255);

RTC_DS1307 MFC_Time;
DateTime* Now_Time;

// LCDShield MFC_LCDColorShield;

////////////////////////////////////////////////////////////////////////////////

const PROGMEM char PROGMEMTEXT_COMMON_OK[] = "OK\0";
const PROGMEM char PROGMEMTEXT_COMMON_FAIL[] = "FAIL\0";
const PROGMEM char PROGMEMTEXT_COMMON_ADJUSTED[] = "ADJUSTED\0";
const PROGMEM char PROGMEMTEXT_COMMON_UNEXPECTEDERROR[] = " [ERROR]\0";

const PROGMEM char PROGMEMTEXT_COMMON_DAYSOFTHEWEEK_OFFSET[] = "\0";
const PROGMEM char PROGMEMTEXT_COMMON_SUNDAY[] = "Sun\0";
const PROGMEM char PROGMEMTEXT_COMMON_MONDAY[] = "Mon\0";
const PROGMEM char PROGMEMTEXT_COMMON_TUESDAY[] = "Tue\0";
const PROGMEM char PROGMEMTEXT_COMMON_WEDNESDAY[] = "Wed\0";
const PROGMEM char PROGMEMTEXT_COMMON_THURSDAY[] = "Thu\0";
const PROGMEM char PROGMEMTEXT_COMMON_FRYDAY[] = "Fri\0";
const PROGMEM char PROGMEMTEXT_COMMON_SATURDAY[] = "Sat\0";

const PROGMEM char PROGMEMTEXT_COMMON_MONTHSOFTHEYEAR_OFFSET[] = "\0";
const PROGMEM char PROGMEMTEXT_COMMON_JANUARY[] = "Jan\0";
const PROGMEM char PROGMEMTEXT_COMMON_FEBRUARY[] = "Feb\0";
const PROGMEM char PROGMEMTEXT_COMMON_MARCH[] = "Mar\0";
const PROGMEM char PROGMEMTEXT_COMMON_APRIL[] = "Apr\0";
const PROGMEM char PROGMEMTEXT_COMMON_MAY[] = "May\0";
const PROGMEM char PROGMEMTEXT_COMMON_JUNE[] = "Jun\0";
const PROGMEM char PROGMEMTEXT_COMMON_JULY[] = "Jul\0";
const PROGMEM char PROGMEMTEXT_COMMON_AUGUST[] = "Aug\0";
const PROGMEM char PROGMEMTEXT_COMMON_SEPTEMBER[] = "Sept\0";
const PROGMEM char PROGMEMTEXT_COMMON_OCTOBER[] = "Oct\0";
const PROGMEM char PROGMEMTEXT_COMMON_NOVEMBER[] = "Nov\0";
const PROGMEM char PROGMEMTEXT_COMMON_DECEMBER[] = "Dec\0";

const PROGMEM char PROGMEMTEXT_COMMON_WALK[] = "Walk\0";
const PROGMEM char PROGMEMTEXT_COMMON_BICYCLE[] = "Bicycle\0";
const PROGMEM char PROGMEMTEXT_COMMON_CAR[] = "Car\0";
  
const PROGMEM char PROGMEMTEXT_COMMON_HTTPCODE[] = "HTTP_CODE\0";
const PROGMEM char PROGMEMTEXT_COMMON_HTTPCODESERIALPRINT[] = "      HTTP_CODE: \0";

const PROGMEM char PROGMEMTEXT_COMMON_RTCDETECTION[] = "RTC DET: \0";
const PROGMEM char PROGMEMTEXT_COMMON_RTCCONFIGURATION[] = "RTC CONF: \0";

const PROGMEM char PROGMEMTEXT_COMMON_WIFISHIELD[] = "WIFI DET: \0";
const PROGMEM char PROGMEMTEXT_COMMON_WIFICONNECTION[] = "WIFI CONN: \0";
const PROGMEM char PROGMEMTEXT_COMMON_WIFISSID[] = "MFC\0";
const PROGMEM char PROGMEMTEXT_COMMON_WIFIPASSWORD[] = "VTIV5IWMFC\0";

const PROGMEM char PROGMEMTEXT_COMMON_GOOGLEINITIALIZEOAUTH[] = "GOOGLE INITIALIZE: \0";
const PROGMEM char PROGMEMTEXT_COMMON_GOOGLEFINALIZEOAUTH[] = "GOOGLE FINALIZE: \0";
const PROGMEM char PROGMEMTEXT_COMMON_GOOGLESEARCHCALENDAR[] = "GOOGLE SEARCH CAL: \0";
const PROGMEM char PROGMEMTEXT_COMMON_GOOGLEREADCALENDAR[] = "GOOGLE READ CAL: \0";
const PROGMEM char PROGMEMTEXT_COMMON_GOOGLEDISTANCEMATRIX[] = "GOOGLE DISTANCE CALC: \0";

////////////////////////////////////////////////////////////////////////////////

const PROGMEM char PROGMEMTEXT_TEMBOO_ACCOUNT[] = "mfc\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_APPNAME[] = "MFC\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_APPKEY[] = "j4iHr8BebAHu9D1CHv4pOwGg07dyefES\0";

const PROGMEM char PROGMEMTEXT_TEMBOO_PROFILE_INITIALIZEMFC[] = "InitializeMFC\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_PROFILE_FINALIZEMFC[] = "FinalizeMFC\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_PROFILE_SEARCHCALENDARMFC[] = "SearchCalendarMFC\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_PROFILE_READCALENDARMFC[] = "ReadCalendarMFC\0";

const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INITIALIZEOAUTH[] = "/Library/Google/OAuth/InitializeOAuth\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_FINALIZEOAUTH[] = "/Library/Google/OAuth/FinalizeOAuth\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_SEARCHCALENDARSBYNAME[] = "/Library/Google/Calendar/SearchCalendarsByName\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_GETNEXTEVENT[] = "/Library/Google/Calendar/GetNextEvent\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_WALKINGDISTANCEMATRIX[] = "/Library/Google/DistanceMatrix/WalkingDistanceMatrix\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_BICYCLINGDISTANCEMATRIX[] = "/Library/Google/DistanceMatrix/BicyclingDistanceMatrix\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_DRIVINGDISTANCEMATRIX[] = "/Library/Google/DistanceMatrix/DrivingDistanceMatrix\0";

const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_SCOPE[] = "Scope\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_SCOPE_VALUE[] = "https://www.googleapis.com/auth/calendar\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALLBACKID[] = "CallbackID\0";
// const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALLBACKID_VALUE[] = "\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALENDARNAME[] = "CalendarName\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALENDARNAME_VALUE[] = "MultiFunctional Clock\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALENDARID[] = "CalendarID\0";
// const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALENDARID_VALUE[] = "\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_ACCESSTOKEN[] = "AccessToken\0";
// const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_ACCESSTOKEN_VALUE[] = "\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_REFRESHTOKEN[] = "RefreshToken\0";
// const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_REFRESHTOKEN_VALUE[] = "\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_ORIGIN[] = "Origins\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_ORIGIN_VALUE[] = "51.007990, 2.727744";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_DESTINATION[] = "Destinations\0";
const PROGMEM char PROGMEMTEXT_TEMBOO_CHOREO_INPUT_DESTINATION_VALUE[] = "51.063598, 2.666651\0";

const PROGMEM char PROGMEMTEXT[] = "\0";

////////////////////////////////////////////////////////////////////////////////

enum PROGMEMTEXT_LIST {
  
  OK,
  FAIL,
  ADJUSTED,
  UNEXPECTEDERROR,

  DAYSOFTHEWEEK_OFFSET,
  SUNDAY,
  MONDAY,
  TUESDAY,
  WEDNESDAY,
  THURSDAY,
  FRYDAY,
  SATURDAY,

  MONTHSOFTHEYEAR_OFFSET,
  JANUARY,
  FEBRUARY,
  MARCH,
  APRIL,
  MAY,
  JUNE,
  JULY,
  AUGUST,
  SEPTEMBER,
  OCTOBER,
  NOVEMBER,
  DECEMBER,

  WALK,
  BICYCLE,
  CAR,
  
  HTTP_CODE,
  HTTP_CODE_SERIALPRINT,

  RTC_DETECTION,
  RTC_CONFIGURATION,

  WIFI_SHIELD,
  WIFI_CONNECTION,
  WIFI_SSID,
  WIFI_PASSWORD,

  GOOGLE_INITIALIZEOAUTH,
  GOOGLE_FINALIZEOAUTH,
  GOOGLE_SEARCHCALENDAR,
  GOOGLE_READCALENDAR,
  GOOGLE_DISTANCEMATRIX,

  ACCOUNT,
  APP_NAME,
  APP_KEY,

  INITIALIZEMFC,
  FINALIZEMFC,
  SEARCHCALENDARMFC,
  READCALENDARMFC,

  INITIALIZEOAUTH,
  FINALIZEOAUTH,
  SEARCHCALENDARSBYNAME,
  GETNEXTEVENT,
  WALKINGDISTANCEMATRIX,
  BICYCLINGDISTANCEMATRIX,
  DRIVINGDISTANCEMATRIX,

  SCOPE,
  SCOPE_VALUE,
  CALLBACKID,
  // CALLBACKID_VALUE,
  CALENDARNAME,
  CALENDARNAME_VALUE,
  CALENDARID,
  //CALENDARID_VALUE,
  ACCESSTOKEN,
  // ACCESSTOKEN_VALUE,
  REFRESHTOKEN,
  // REFRESHTOKEN_VALUE,
  ORIGIN,
  ORIGIN_VALUE,
  DESTINATION,
  DESTINATION_VALUE,

  PROGMEMTEXT_LIST_SIZE
};

PROGMEMTEXT_LIST MeansOfTransport;
unsigned long UserPrepTime;
unsigned long CurrentPrepTime;

////////////////////////////////////////////////////////////////////////////////

const PROGMEM char* const PROGMEMTEXT_TABLE[]  = {
  
  PROGMEMTEXT_COMMON_OK,
  PROGMEMTEXT_COMMON_FAIL,
  PROGMEMTEXT_COMMON_ADJUSTED,
  PROGMEMTEXT_COMMON_UNEXPECTEDERROR,

  PROGMEMTEXT_COMMON_DAYSOFTHEWEEK_OFFSET,
  PROGMEMTEXT_COMMON_SUNDAY,
  PROGMEMTEXT_COMMON_MONDAY,
  PROGMEMTEXT_COMMON_TUESDAY,
  PROGMEMTEXT_COMMON_WEDNESDAY,
  PROGMEMTEXT_COMMON_THURSDAY,
  PROGMEMTEXT_COMMON_FRYDAY,
  PROGMEMTEXT_COMMON_SATURDAY,

  PROGMEMTEXT_COMMON_MONTHSOFTHEYEAR_OFFSET,
  PROGMEMTEXT_COMMON_JANUARY,
  PROGMEMTEXT_COMMON_FEBRUARY,
  PROGMEMTEXT_COMMON_MARCH,
  PROGMEMTEXT_COMMON_APRIL,
  PROGMEMTEXT_COMMON_MAY,
  PROGMEMTEXT_COMMON_JUNE,
  PROGMEMTEXT_COMMON_JULY,
  PROGMEMTEXT_COMMON_AUGUST,
  PROGMEMTEXT_COMMON_SEPTEMBER,
  PROGMEMTEXT_COMMON_OCTOBER,
  PROGMEMTEXT_COMMON_NOVEMBER,
  PROGMEMTEXT_COMMON_DECEMBER,

  PROGMEMTEXT_COMMON_WALK,
  PROGMEMTEXT_COMMON_BICYCLE,
  PROGMEMTEXT_COMMON_CAR,

  PROGMEMTEXT_COMMON_HTTPCODE,
  PROGMEMTEXT_COMMON_HTTPCODESERIALPRINT,
  
  PROGMEMTEXT_COMMON_RTCDETECTION,
  PROGMEMTEXT_COMMON_RTCCONFIGURATION,
  
  PROGMEMTEXT_COMMON_WIFISHIELD,
  PROGMEMTEXT_COMMON_WIFICONNECTION,
  PROGMEMTEXT_COMMON_WIFISSID,
  PROGMEMTEXT_COMMON_WIFIPASSWORD,
  
  PROGMEMTEXT_COMMON_GOOGLEINITIALIZEOAUTH,
  PROGMEMTEXT_COMMON_GOOGLEFINALIZEOAUTH,
  PROGMEMTEXT_COMMON_GOOGLESEARCHCALENDAR,
  PROGMEMTEXT_COMMON_GOOGLEREADCALENDAR,
  PROGMEMTEXT_COMMON_GOOGLEDISTANCEMATRIX,
  
  PROGMEMTEXT_TEMBOO_ACCOUNT,
  PROGMEMTEXT_TEMBOO_APPNAME,
  PROGMEMTEXT_TEMBOO_APPKEY,

  PROGMEMTEXT_TEMBOO_PROFILE_INITIALIZEMFC,
  PROGMEMTEXT_TEMBOO_PROFILE_FINALIZEMFC,
  PROGMEMTEXT_TEMBOO_PROFILE_SEARCHCALENDARMFC,
  PROGMEMTEXT_TEMBOO_PROFILE_READCALENDARMFC,
  
  PROGMEMTEXT_TEMBOO_CHOREO_INITIALIZEOAUTH,
  PROGMEMTEXT_TEMBOO_CHOREO_FINALIZEOAUTH,
  PROGMEMTEXT_TEMBOO_CHOREO_SEARCHCALENDARSBYNAME,
  PROGMEMTEXT_TEMBOO_CHOREO_GETNEXTEVENT,
  PROGMEMTEXT_TEMBOO_CHOREO_WALKINGDISTANCEMATRIX,
  PROGMEMTEXT_TEMBOO_CHOREO_BICYCLINGDISTANCEMATRIX,
  PROGMEMTEXT_TEMBOO_CHOREO_DRIVINGDISTANCEMATRIX,
  
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_SCOPE,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_SCOPE_VALUE,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALLBACKID,
  // PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALLBACKID_VALUE,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALENDARNAME,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALENDARNAME_VALUE,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALENDARID,
  // PROGMEMTEXT_TEMBOO_CHOREO_INPUT_CALENDARID_VALUE,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_ACCESSTOKEN,
  // PROGMEMTEXT_TEMBOO_CHOREO_INPUT_ACCESSTOKEN_VALUE,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_REFRESHTOKEN,
  // PROGMEMTEXT_TEMBOO_CHOREO_INPUT_REFRESHTOKEN_VALUE,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_ORIGIN,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_ORIGIN_VALUE,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_DESTINATION,
  PROGMEMTEXT_TEMBOO_CHOREO_INPUT_DESTINATION_VALUE,
  
  PROGMEMTEXT
};

#define getPROGMEMTEXT_DayOfTheWeek(DayOfTheWeek) (strcpy_P(cBuffer[0], (char*)pgm_read_word(&(PROGMEMTEXT_TABLE[DayOfTheWeek + PROGMEMTEXT_LIST::DAYSOFTHEWEEK_OFFSET + 1]))))
#define getPROGMEMTEXT_MonthOfTheYear(MonthOfTheYear) (strcpy_P(cBuffer[0], (char*)pgm_read_word(&(PROGMEMTEXT_TABLE[MonthOfTheYear + PROGMEMTEXT_LIST::MONTHSOFTHEYEAR_OFFSET]))))

#define getPROGMEMTEXT(enum_PROGMEMTEXT_LIST_value) (strcpy_P(cBuffer[7], (char*)pgm_read_word(&(PROGMEMTEXT_TABLE[enum_PROGMEMTEXT_LIST_value]))))
#define getPROGMEMTEXT_i(enum_PROGMEMTEXT_LIST_value, cBuffer_index) (strcpy_P(cBuffer[cBuffer_index], (char*)pgm_read_word(&(PROGMEMTEXT_TABLE[enum_PROGMEMTEXT_LIST_value]))))

////////////////////////////////////////////////////////////////////////////////

void setup() {

  Serial.begin(57600);
  while(!Serial);

  pinMode(3, OUTPUT);
  analogWrite(3, 0);

  /*
  MFC_LCDColorShield.init(PHILIPS);
  MFC_LCDColorShield.contrast(50);
  MFC_LCDColorShield.clear(WHITE);
  */

  RTC();
  
  Wifi();
}

////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {

  if(Setup == 0) {

    Serial.println(F("\nHow long do you usually take to get ready? (In minutes)"));

    while(!Serial.available());

    sBuffer = Serial.readString();

    Serial.print(sBuffer);

    UserPrepTime = (atol(sBuffer.c_str()) * 60);

    Serial.println(F("\nWhat means of transport do you use? (Walk / Bicycle / Car)"));

    while(!Serial.available());

    sBuffer = Serial.readString();

    if(sBuffer.c_str() == getPROGMEMTEXT(PROGMEMTEXT_LIST::WALK))
      MeansOfTransport = PROGMEMTEXT_LIST::WALKINGDISTANCEMATRIX;
      
    else if(sBuffer.c_str() == getPROGMEMTEXT(PROGMEMTEXT_LIST::BICYCLE))
      MeansOfTransport = PROGMEMTEXT_LIST::BICYCLINGDISTANCEMATRIX;

    else if(sBuffer.c_str() == getPROGMEMTEXT(PROGMEMTEXT_LIST::DRIVE))
      MeansOfTransport = PROGMEMTEXT_LIST::DRIVINGDISTANCEMATRIX;

    else
      MeansOfTransport = PROGMEMTEXT_LIST::DRIVINGDISTANCEMATRIX;

    Serial.println(sBuffer);

    Initialize();
    Finalize();

    SearchCalendar();
    ReadCalendar();

    Setup = 1;
  }

  delete Now_Time;
  Now_Time = new DateTime(MFC_Time.now());

  if(Now_Time->unixtime() < (ReadCalendar_Time->unixtime() - CurrentPrepTime - 300)) {
    if((Count % 300) == 0) {
      ReadCalendar();
      DistanceMatrix();
    }
  }
  
  if(((Now_Time->unixtime() - 30UL) < (ReadCalendar_Time->unixtime() - CurrentPrepTime)) && (Now_Time->unixtime() >= (ReadCalendar_Time->unixtime() - CurrentPrepTime))) {
    analogWrite(3, 20);
    delay(3000UL);
    analogWrite(3, 0);
  }
  else if(Now_Time->unixtime() > (ReadCalendar_Time->unixtime() - CurrentPrepTime)) {
    
    ReadCalendar();
    DistanceMatrix();
  }

  Serial.print(F("Current date: "));
  Serial.print(getPROGMEMTEXT_DayOfTheWeek(Now_Time->dayOfTheWeek()));
  Serial.print(F(" "));
  Serial.print(Now_Time->day(), DEC);
  Serial.print(F("/"));
  Serial.print(Now_Time->month(), DEC);
  Serial.print(F(" ("));
  Serial.print(getPROGMEMTEXT_MonthOfTheYear(Now_Time->month()));
  Serial.print(F(") "));
  Serial.println(Now_Time->year());

  Serial.print(F("Current time: "));
  Serial.print(Now_Time->hour(), DEC);
  Serial.print(F(":"));
  Serial.print(Now_Time->minute(), DEC);
  Serial.print(F(":"));
  Serial.println(Now_Time->second(), DEC);

  Serial.print(F("Alarm time: "));
  if((ReadCalendar_Time->minute() == 0) && (CurrentPrepTime != 0))
    Serial.print(ReadCalendar_Time->hour() - 1, DEC);
  else
    Serial.print(ReadCalendar_Time->hour(), DEC);
  Serial.print(F(":"));
  Serial.print(ReadCalendar_Time->minute() - CurrentPrepTime, DEC);
  Serial.print(F(":"));
  Serial.println(ReadCalendar_Time->second(), DEC);
  Serial.println();

  /*
  MFC_LCDColorShield.setStr(itoa(Now_Time->hour(), cBuffer[7], 10), 44, 10, BLACK, WHITE);
  MFC_LCDColorShield.setStr(":", 44, 26, BLACK, WHITE);
  MFC_LCDColorShield.setStr(itoa(Now_Time->minute(), cBuffer[7], 10), 44, 34, BLACK, WHITE);
  MFC_LCDColorShield.setStr(":", 44, 42, BLACK, WHITE);
  MFC_LCDColorShield.setStr(itoa(Now_Time->second(), cBuffer[7], 10), 44, 58, BLACK, WHITE);

  MFC_LCDColorShield.setStr(getPROGMEMTEXT_DayOfTheWeek(Now_Time->dayOfTheWeek()), 70, 10, COLOR, BACKGROUND);

  MFC_LCDColorShield.setStr(itoa(Now_Time->day(), Dag, 10), 70, 10, COLOR, BACKGROUND);
  MFC_LCDColorShieldcd.setStr("/", 101 , 28, COLOR, BACKGROUND);
  MFC_LCDColorShield.setStr(itoa(Now_Time->month(), Maand, 10), 103, 37, COLOR, BACKGROUND);
  MFC_LCDColorShield.setStr("/", 101, 55, COLOR, BACKGROUND);
  MFC_LCDColorShield.setStr(itoa(Now_Time->year(), Jaar, 10), 103, 61, COLOR, BACKGROUND);
  */

  delay(1000);

  Count++;
}

////////////////////////////////////////////////////////////////////////////////

void RTC(void) {

  Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::RTC_DETECTION));
  
  if (MFC_Time.begin()) {
    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::OK));
  } else {
    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::FAIL));
    while(true);
  }

  Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::RTC_CONFIGURATION));
  
  if (MFC_Time.isrunning()) {
    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::OK));
  } else {
    MFC_Time.adjust(DateTime(F(__DATE__), F(__TIME__)));
    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::ADJUSTED));
  }
}

void Wifi(void) {

  Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::WIFI_SHIELD));
  
  if (WiFi.status() != WL_NO_SHIELD) {
    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::OK));
  } else {
    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::FAIL));
    while(true);
  }
  
  Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::WIFI_CONNECTION));

  MFC_WifiStatus = WL_IDLE_STATUS;
  
  for(int i = 0; (i < 10) && (MFC_WifiStatus != WL_CONNECTED); i++) {
    MFC_WifiStatus = WiFi.begin(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::WIFI_SSID, 6), getPROGMEMTEXT_i(PROGMEMTEXT_LIST::WIFI_PASSWORD, 7));
    delay(6000);
  }
  
  if (MFC_WifiStatus == WL_CONNECTED) {
    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::OK));
  } else {
    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::FAIL));
    while(true);
  }
}

////////////////////////////////////////////////////////////////////////////////

void Initialize(void) {

  Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::GOOGLE_INITIALIZEOAUTH));

  TembooChoreo InitializeOAuthChoreo(MFC_WifiClient);

  InitializeOAuthChoreo.begin();

  InitializeOAuthChoreo.setAccountName(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::ACCOUNT, 0));
  InitializeOAuthChoreo.setAppKeyName(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::APP_NAME, 1));
  InitializeOAuthChoreo.setAppKey(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::APP_KEY, 2));

  InitializeOAuthChoreo.setProfile(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::INITIALIZEMFC, 3));

  InitializeOAuthChoreo.addInput(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::SCOPE, 4), getPROGMEMTEXT_i(PROGMEMTEXT_LIST::SCOPE_VALUE, 6));

  InitializeOAuthChoreo.setChoreo(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::INITIALIZEOAUTH, 7));

  if(InitializeOAuthChoreo.run() == 0) {

    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::OK));
    
    while(InitializeOAuthChoreo.available()) {
      
      InitializeOAuthChoreo.readStringUntil('\x1F');
      InitializeOAuthChoreo.readStringUntil('\x1E');
      
      InitializeOAuthChoreo.readStringUntil('\x1F');
      Serial.println(F("\nNavigate to this web-page and click \"Allow\"."));
      Serial.println(InitializeOAuthChoreo.readStringUntil('\x1E'));
      
      while(!Serial.available());
      
      InitializeOAuthChoreo.readStringUntil('\x1F');
      CallbackID = InitializeOAuthChoreo.readStringUntil('\x1E');
      CallbackID.trim();
      
      // Serial.print((char)InitializeOAuthChoreo.read());
    }
  } else {

    Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::FAIL));
    
    while(true);
  }

  InitializeOAuthChoreo.close();
}

////////////////////////////////////////////////////////////////////////////////

void Finalize(void) {

  Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::GOOGLE_FINALIZEOAUTH));

  TembooChoreo FinalizeOAuthChoreo(MFC_WifiClient);

  FinalizeOAuthChoreo.begin();

  FinalizeOAuthChoreo.setAccountName(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::ACCOUNT, 0));
  FinalizeOAuthChoreo.setAppKeyName(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::APP_NAME, 1));
  FinalizeOAuthChoreo.setAppKey(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::APP_KEY, 2));

  FinalizeOAuthChoreo.setProfile(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::FINALIZEMFC, 3));

  FinalizeOAuthChoreo.addInput(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::CALLBACKID, 4), CallbackID);

  FinalizeOAuthChoreo.setChoreo(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::FINALIZEOAUTH, 7));

  if(FinalizeOAuthChoreo.run() == 0) {

    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::OK));

    delete Now_Time;
    Now_Time = new DateTime(MFC_Time.now());
    
    delete AccessToken_Time;
    AccessToken_Time = new DateTime(Now_Time->year(), Now_Time->month(), Now_Time->day(), Now_Time->hour() + 1, Now_Time->minute(), Now_Time->second());
    
    while(FinalizeOAuthChoreo.available()) {
      
      FinalizeOAuthChoreo.readStringUntil('\x1F');
      FinalizeOAuthChoreo.readStringUntil('\x1E');
      
      FinalizeOAuthChoreo.readStringUntil('\x1F');
      RefreshToken = FinalizeOAuthChoreo.readStringUntil('\x1E');
      RefreshToken.trim();
      
      FinalizeOAuthChoreo.readStringUntil('\x1F');
      FinalizeOAuthChoreo.readStringUntil('\x1E');
      
      FinalizeOAuthChoreo.readStringUntil('\x1F');
      FinalizeOAuthChoreo.readStringUntil('\x1E');
      
      FinalizeOAuthChoreo.readStringUntil('\x1F');
      AccessToken = FinalizeOAuthChoreo.readStringUntil('\x1E');
      AccessToken.trim();
      
      // Serial.print((char)FinalizeOAuthChoreo.read());
    }
  } else {

    Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::FAIL));
    
    while(true);
  }

  FinalizeOAuthChoreo.close();
}

////////////////////////////////////////////////////////////////////////////////

void SearchCalendar(void) {

  Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::GOOGLE_SEARCHCALENDAR));

  TembooChoreo SearchCalendarChoreo(MFC_WifiClient);

  SearchCalendarChoreo.begin();

  SearchCalendarChoreo.setAccountName(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::ACCOUNT, 0));
  SearchCalendarChoreo.setAppKeyName(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::APP_NAME, 1));
  SearchCalendarChoreo.setAppKey(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::APP_KEY, 2));

  delete Now_Time;
  Now_Time = new DateTime(MFC_Time.now());    

  if(Now_Time->unixtime() < AccessToken_Time->unixtime()) {
    SearchCalendarChoreo.addInput(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::ACCESSTOKEN, 3), AccessToken);
  } else {

    delete AccessToken_Time;
    AccessToken_Time = new DateTime(Now_Time->year(), Now_Time->month(), Now_Time->day(), Now_Time->hour() + 1, Now_Time->minute(), Now_Time->second());
    
    SearchCalendarChoreo.setProfile(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::SEARCHCALENDARMFC, 3));
    SearchCalendarChoreo.addInput(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::REFRESHTOKEN, 4), RefreshToken);
  }

  SearchCalendarChoreo.addInput(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::CALENDARNAME, 5), getPROGMEMTEXT_i(PROGMEMTEXT_LIST::CALENDARNAME_VALUE, 6));

  SearchCalendarChoreo.setChoreo(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::SEARCHCALENDARSBYNAME, 7));

  if(SearchCalendarChoreo.run() == 0) {
 
    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::OK));
    
    while(SearchCalendarChoreo.available()) {
      
      SearchCalendarChoreo.readStringUntil('\x1F');
      SearchCalendarChoreo.readStringUntil('\x1E');

      SearchCalendarChoreo.readStringUntil('\x1F');
      SearchCalendarChoreo.readStringUntil('\x1E');
      
      SearchCalendarChoreo.readStringUntil('\x1F');
      sBuffer = SearchCalendarChoreo.readStringUntil('\x1E');
      sBuffer.trim();
      if(sBuffer != getPROGMEMTEXT(PROGMEMTEXT_LIST::PROGMEMTEXT_LIST_SIZE))
        AccessToken = sBuffer;
        
      SearchCalendarChoreo.readStringUntil('\x1F');
      SearchCalendarChoreo.readStringUntil('\x1E');
      
      SearchCalendarChoreo.readStringUntil('\x1F');
      SearchCalendarChoreo.readStringUntil('\x1E');
      
      SearchCalendarChoreo.readStringUntil('\x1F');      
      CalendarID = SearchCalendarChoreo.readStringUntil('\x1E');
      CalendarID.trim();
      
      SearchCalendarChoreo.readStringUntil('\x1F');
      SearchCalendarChoreo.readStringUntil('\x1E');

      // Serial.print((char)SearchCalendarChoreo.read());
    }
  } else {

    Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::FAIL));
    
    while(true);
  }

  SearchCalendarChoreo.close();
}

////////////////////////////////////////////////////////////////////////////////

void ReadCalendar(void) {

  Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::GOOGLE_READCALENDAR));

  TembooChoreo ReadCalendarChoreo(MFC_WifiClient);

  ReadCalendarChoreo.begin();

  ReadCalendarChoreo.setAccountName(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::ACCOUNT, 0));
  ReadCalendarChoreo.setAppKeyName(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::APP_NAME, 1));
  ReadCalendarChoreo.setAppKey(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::APP_KEY, 2));

  delete Now_Time;
  Now_Time = new DateTime(MFC_Time.now());    

  if(Now_Time->unixtime() < AccessToken_Time->unixtime()) {
    ReadCalendarChoreo.addInput(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::ACCESSTOKEN, 3), AccessToken);
  } else {

    delete AccessToken_Time;
    AccessToken_Time = new DateTime(Now_Time->year(), Now_Time->month(), Now_Time->day(), Now_Time->hour() + 1, Now_Time->minute(), Now_Time->second());
    
    ReadCalendarChoreo.setProfile(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::READCALENDARMFC, 3));
    ReadCalendarChoreo.addInput(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::REFRESHTOKEN, 4), RefreshToken);
  }

  ReadCalendarChoreo.addInput(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::CALENDARID, 6), CalendarID);

  ReadCalendarChoreo.setChoreo(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::GETNEXTEVENT, 7));

  if(ReadCalendarChoreo.run() == 0) {

    Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::OK));
    
    while(ReadCalendarChoreo.available()) {
      
      ReadCalendarChoreo.readStringUntil('\x1F');
      ReadCalendarChoreo.readStringUntil('\x1E');

      ReadCalendarChoreo.readStringUntil('\x1F');
      ReadCalendarChoreo.readStringUntil('\x1E');

      ReadCalendarChoreo.readStringUntil('\x1F');
      sBuffer = ReadCalendarChoreo.readStringUntil('\x1E');
      sBuffer.trim();

      if(sBuffer != getPROGMEMTEXT(PROGMEMTEXT_LIST::PROGMEMTEXT_LIST_SIZE)) {
        
        sBuffer[4] = '\0';
        sBuffer[7] = '\0';
        sBuffer[10] = '\0';
        sBuffer[13] = '\0';
        sBuffer[16] = '\0';
        sBuffer[19] = '\0';

        delete ReadCalendar_Time;
        ReadCalendar_Time = new DateTime(atoi(&sBuffer[0]), atoi(&sBuffer[5]), atoi(&sBuffer[8]), atoi(&sBuffer[11]), atoi(&sBuffer[14]), atoi(&sBuffer[17]));

        Serial.println();
      }
      else {

        Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::UNEXPECTEDERROR));
        
        while(true);
      }
      
      ReadCalendarChoreo.readStringUntil('\x1F');
      sBuffer = ReadCalendarChoreo.readStringUntil('\x1E');
      sBuffer.trim();
      if(sBuffer != getPROGMEMTEXT(PROGMEMTEXT_LIST::PROGMEMTEXT_LIST_SIZE))
        AccessToken = sBuffer;

      sBuffer = getPROGMEMTEXT(PROGMEMTEXT_LIST::PROGMEMTEXT_LIST_SIZE);
      
      ReadCalendarChoreo.readStringUntil('\x1F');
      ReadCalendarChoreo.readStringUntil('\x1E');

      ReadCalendarChoreo.readStringUntil('\x1F');
      ReadCalendarChoreo.readStringUntil('\x1E');

      //Serial.print((char)ReadCalendarChoreo.read());
    }
  } else {

    Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::FAIL));
    
    while(true);
  }

  ReadCalendarChoreo.close();
}

////////////////////////////////////////////////////////////////////////////////

void DistanceMatrix(void) {

  Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::GOOGLE_DISTANCEMATRIX));

  TembooChoreo DistanceMatrixChoreo(MFC_WifiClient);

  DistanceMatrixChoreo.begin();

  DistanceMatrixChoreo.setAccountName(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::ACCOUNT, 0));
  DistanceMatrixChoreo.setAppKeyName(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::APP_NAME, 1));
  DistanceMatrixChoreo.setAppKey(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::APP_KEY, 2));

  DistanceMatrixChoreo.addInput(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::ORIGIN, 3), getPROGMEMTEXT_i(PROGMEMTEXT_LIST::ORIGIN_VALUE, 4));
  DistanceMatrixChoreo.addInput(getPROGMEMTEXT_i(PROGMEMTEXT_LIST::DESTINATION, 5), getPROGMEMTEXT_i(PROGMEMTEXT_LIST::DESTINATION_VALUE, 6));
  
  DistanceMatrixChoreo.setChoreo(getPROGMEMTEXT_i(MeansOfTransport, 7));

  DistanceMatrixChoreo.run();

  if(DistanceMatrixChoreo.run() == 0) {
 
    Serial.println(getPROGMEMTEXT(PROGMEMTEXT_LIST::OK));
    
    while(DistanceMatrixChoreo.available()) {
      
      DistanceMatrixChoreo.readStringUntil('\x1F');
      DistanceMatrixChoreo.readStringUntil('\x1E');

      DistanceMatrixChoreo.readStringUntil('\x1F');
      sBuffer = DistanceMatrixChoreo.readStringUntil('\x1E');
      sBuffer.trim();

      CurrentPrepTime = UserPrepTime + atoi(sBuffer.c_str());
      
      DistanceMatrixChoreo.readStringUntil('\x1F');
      DistanceMatrixChoreo.readStringUntil('\x1E');
      
      // Serial.print((char)DistanceMatrixChoreo.read());
    }
  } else {

    Serial.print(getPROGMEMTEXT(PROGMEMTEXT_LIST::FAIL));
    
    while(true);
  }
  
  DistanceMatrixChoreo.close();
}

Comments

Similar projects you might like

Suicide Prevention Gun Safe Locking System

Project tutorial by 6 developers

  • 136 views
  • 0 comments
  • 3 respects

Smart Compost System

Project showcase by Team Boomer Sooner

  • 86 views
  • 0 comments
  • 2 respects

Purdue ExoMIND Glove

Project showcase by Team Purdue MIND

  • 503 views
  • 0 comments
  • 7 respects

Mall Assistant Robot

Project showcase by 3 developers

  • 417 views
  • 0 comments
  • 6 respects

BrainForce

Project tutorial by Daniel Rossi

  • 845 views
  • 2 comments
  • 6 respects

Magia Transformo - The Dance of Transformation

Project showcase by Team Transformative Play Lab

  • 83 views
  • 0 comments
  • 0 respects
Add projectSign up / Login