MultiFunctional Clock

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

AdvancedWork in progress24 hours19,897
MultiFunctional Clock

Things used in this project

Hardware components

Arduino UNO
Arduino 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
Arduino Wifi Shield 101
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 Rapid Development kit
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

Software apps and online services

Temboo
Temboo
Arduino IDE
Arduino IDE
PowToon

Hand tools and fabrication machines

3D - Printer

Story

Read more

Custom parts and enclosures

3D - Design

Our 3D model in .STP format.

3D - Design

A picture of our 3D model.

Schematics

Scheme

Scheme

Code

MFC - Air quality

Arduino
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 - Alarm

Arduino
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();
}

Credits

Robbie Barra

Robbie Barra

1 project • 2 followers
Stijn Vandenbussche

Stijn Vandenbussche

1 project • 3 followers
Tuur Bruneel

Tuur Bruneel

1 project • 2 followers

Comments