Questo è il programma che sono riuscito a mettere assieme, prendendo spunto online e modificandolo per le mie necessità.
Manca la parte della Radio FM e rilevamento temperatura che devo ancora implementare, ma un passo per volta. 
Ho usato uno schermo oled per comodità, a tempo debito dovrò convertirlo tutto per visualizzarlo su Dot Matrix.
Ora il mio problema, non sono capace a far funzionare il posponi come vorrei.
La sveglia ha 4 pulsanti, quando suona la sveglia, premendone uno qualsiasi, vorrei posporre tutto per 5 minuti e via così finchè non disattivo l'allarme.
Per disattivare l'allarme vorrei premere un pulsante specifico per tot secondi, così da evitare pressioni involontarie.
Grazie per l'aiuto. 
PS. Non ci sono problemi per qualunque modifica e miglioramento in generale al codice, ogni consiglio è ben accetto
// Includo le librerie per RTC, OLED
#include <Wire.h>
#include "RTClib.h"
#include <U8x8lib.h>
// Assegno i nomi allo schermo OLED, RTC, BMP280 e RadioFM
U8X8_SSD1306_128X64_ALT0_HW_I2C oled;
RTC_DS1307 rtc;
// Definisco i PIN per pulsanti e cicalino
#define pulsante1 4 // Pulsante radio e diminuisci valore
#define pulsante2 5 // Pulsante sveglia e aumenta valore
#define pulsante3 3 // Pulsante OK e volume -
#define pulsante4 2 // Pulsante dataora e volume +
#define cicalino 6
// Imposto lo stato dei pulsanti a 0 e giorni per RTC
int stato = 0;
char str[3];
char settimana[7][4] = {"dom", "lun", "mar", "mer", "gio", "ven", "sab"};
DateTime now;
// Imposto variabili per la sveglia
int alarmh, alarmm;
int alarms = 0; // Messo a 0, così non imposto i secondi della sveglia, quando scatta il minuto suona
bool ALARM = false;
unsigned long t_pulsanteoff = 0;
void setup() {
Wire.begin();
Serial.begin(9600);
// Imposto i PIN, per i pulsanti e per il buzzer
pinMode(pulsante1, INPUT);
pinMode(pulsante2, INPUT);
pinMode(pulsante3, INPUT);
pinMode(pulsante4, INPUT);
pinMode(cicalino, OUTPUT);
// Inizializzo lo schermo OLED e imposto il font
oled.begin();
oled.setFont(u8x8_font_5x7_f);
// Inizializzo RTC e imposto data e ora
if (! rtc.begin()) {
Serial.println("Errore RTC");
abort();
}
if (! rtc.isrunning()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop() {
// Nel loop gira nei vari stati della radiosveglia
switch (stato) {
case 0:
dataora();
break;
case 1:
impostaOra();
break;
case 2:
impostaMinuti();
break;
case 3:
impostaSecondi();
break;
case 4:
impostaGiorno();
break;
case 5:
impostaMese();
break;
case 6:
impostaAnno();
break;
case 10:
accendiSveglia();
break;
case 11:
impostaOraSveglia();
break;
case 12:
impostaMinutiSveglia();
break;
case 20:
allarmeSveglia();
break;
case 21:
posponiSveglia();
break;
case 30:
radioFM();
break;
case 40:
meteo();
break;
}
}
bool FIRST = true;
unsigned long t1, dt;
int ch, cm, cs;
// stato 0 - Schermata principale dove visualizzo data/ora e se sveglia attiva
void dataora() {
if (FIRST) {
oled.clear();
t1 = millis();
FIRST = false;
}
// Assegno i nomi ch, cm, cs per visualizzare l'RTC
dt = millis() - t1;
if (dt > 500) {
now = rtc.now();
ch = now.hour();
cm = now.minute();
cs = now.second();
oled.setCursor(0, 0);
// Visualizzo ora, minuti e secondi sul display
sprintf(str, "%02d", ch);
oled.print(str);
oled.print(":");
sprintf(str, "%02d", cm);
oled.print(str);
oled.print(":");
sprintf(str, "%02d", cs);
oled.print(str);
// Se la sveglia è accesa scrivo ON, se spenta visualizzo la data corrente
oled.setCursor(0, 1);
if (ALARM) {
oled.print("ON");
} else {
oled.print(settimana[now.dayOfTheWeek()]);
oled.print(" ");
oled.print(now.day(), DEC);
oled.print('/');
oled.print(now.month(), DEC);
oled.print('/');
oled.print(now.year(), DEC);
}
// Se ora, minuti e secondi sono uguali a quelli impostati per la sveglia, vai allo stato 20 - allarmeSveglia();
if ( (ch == alarmh) && (cm == alarmm) && (cs == alarms)) {
stato = 20;
FIRST = true;
}
t1 = millis();
}
// Se premi pulsante4, vai allo stato 1 - impostaOra();
if (digitalRead(pulsante4)) {
stato = 1;
delay(200);
FIRST = true;
}
// Se premi pulsante2, vai allo stato 10 - accendiSveglia();
if (digitalRead(pulsante2)) {
stato = 10;
delay(200);
FIRST = true;
}
// Se premi pulsante1, vai allo stato 30 - radioFM();
if (digitalRead(pulsante1)) {
stato = 30;
delay(200);
FIRST = true;
}
// Se premi pulsante3, vado allo stato 40 - meteo();
if (digitalRead(pulsante3)) {
stato = 40;
delay(200);
FIRST = true;
}
// Se premo il pulsante2 per 5 secondi, cambio lo stato della sveglia per spegnerla.
if (digitalRead(pulsante2) == HIGH) {
t_pulsanteoff = millis();
}
else {
if ((millis() - t_pulsanteoff) >= 5000)
{
ALARM = !ALARM;
delay(200);
}
}
}
// Imposto la variabile seth a 0, nel void impostaOra() assegno alla variabile l'ora
int seth = 0;
// stato 1 - Qui imposto l'ora
void impostaOra() { // Recupero l'ora dal RTC e viene assegnata a seth
if (FIRST) {
oled.clear();
now = rtc.now();
seth = now.hour();
FIRST = false;
}
// Visualizzo a schermo che viene modificata l'ora, minuti e secondi sono tratteggiati
oled.setCursor(0, 0);
sprintf(str, "%02d" , seth);
oled.print(str);
oled.print(" : -- : --");
// Se premi pulsante2, aumento le ore, arrivato a 24, riparte da 0
if (digitalRead(pulsante2)) {
seth++;
if (seth >= 24) seth = 0;
delay(200);
}
// Se premi il pulsante1, diminuisco le ore, arrivato a 0, torna a 23
if (digitalRead(pulsante1)) {
seth--;
if (seth < 0) seth = 23;
delay(200);
}
// Se premo il pulsante3, salvo l'ora impostata nel RTC e vado nello stato 02 - void impostaMinuti();
if (digitalRead(pulsante3)) {
rtc.adjust(DateTime(now.year(), now.month(), now.day(), seth, now.minute(), now.second()));
stato = 02;
FIRST = true;
delay(200);
}
}
// Imposto la variabile setm a 0, nel void impostaMinuti() assegno alla variabile i minuti
int setm = 0;
// stato 2 - Qui imposto i minuti
void impostaMinuti() {
// Recupero i minuti dal RTC e li assegno alla variabile setm
if (FIRST) {
oled.clear();
now = rtc.now();
setm = now.minute();
FIRST = false;
}
// Visualizzo a schermo che vengono modificati i minuti, ora e secondi sono tratteggiati
oled.setCursor(0, 0);
sprintf(str, "%02d" , setm);
oled.print("-- : ");
oled.print(str);
oled.print(" : --");
// Se premi il pulsante2, aumento i minuti, arrivato a 60 riparto da 0
if (digitalRead(pulsante2)) {
setm++;
if (setm >= 60) setm = 0;
delay(200);
}
// Se premi il pulsante1, diminuisco i minuti, arrivato a 0 riparto da 59
if (digitalRead(pulsante1)) {
setm--;
if (setm < 0) setm = 59;
delay(200);
}
// Se premi il pulsante3, salvo i minuti impostati nel RTC e vado allo stato 3 - impostaSecondi()
if (digitalRead(pulsante3)) {
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), setm, now.second()));
stato = 03;
FIRST = true;
delay(200);
}
}
// Imposto la variabile sets a 0, nel void impostaSecondi() assegno alla variabile i secondi
int sets = 0;
// stato 3 - Qui imposto i secondi
void impostaSecondi() {
// Recupero i secondi dal RTC e li assegno alla variabile sets
if (FIRST) {
oled.clear();
now = rtc.now();
sets = now.second();
FIRST = false;
}
// Visualizzo a schermo che vengono modificati i secondi, ora e minuti sono tratteggiati
oled.setCursor(0, 0);
sprintf(str, "%02d" , sets);
oled.print("-- : -- : ");
oled.print(str);
// Se premi il pulsante2, aumento i secondi, se arrivano a 60, riparte da zero
if (digitalRead(pulsante2)) {
sets++;
if (sets >= 60) sets = 0;
delay(200);
}
// Se premi il pulsante1, diminuisco i secondi, se arrivano a 0, riparte da 59
if (digitalRead(pulsante1)) {
sets--;
if (sets < 0) sets = 59;
delay(200);
}
// Se premo il pulsante3, salvo i secondi impostati nel RTC e vado allo stato 4 - impostaGiorno()
if (digitalRead(pulsante3)) {
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), sets));
stato = 4;
FIRST = true;
delay(200);
}
}
// Imposto la variabile setg a 0, nel void impostaGiorno() assegno alla variabile il giorno
int setg = 0;
// stato 4 - Qui imposto il giorno della data
void impostaGiorno() {
// Recupero il giorno dal RTC e assegno alla variabile setg
if (FIRST) {
oled.clear();
now = rtc.now();
setg = now.day();
FIRST = false;
}
// Visualizzo a schermo che viene modificato il giorno, mese e anno sono tratteggiati
oled.setCursor(0, 0);
sprintf(str, "%02d" , setg);
oled.print(str);
oled.print("/--/----");
// Se premo il pulsante2, aumento i giorni, se arrivano a 31, riparte da 1
if (digitalRead(pulsante2)) {
setg++;
if (setg > 31) setg = 1;
delay(200);
}
// Se premo il pulsante1, diminuisco i giorni, se arriva a 1, riparte da 31
if (digitalRead(pulsante1)) {
setg--;
if (setg < 1) setg = 31;
delay(200);
}
// Se premo il pulsante3, salvo il giorno impostato nel RTC e vado allo stato 5 - impostaMese()
if (digitalRead(pulsante3)) {
rtc.adjust(DateTime(now.year(), now.month(), setg, now.hour(), now.minute(), now.second()));
stato = 5;
FIRST = true;
delay(200);
}
}
// Imposto la variabile setmese 0, nel void impostaMese() assegno alla variabile il mese
int setmese = 0;
// stato 5 - Qui imposto il mese della data
void impostaMese() {
// Recupero il mese dal RTC e assegno alla variabile setmese
if (FIRST) {
oled.clear();
now = rtc.now();
setmese = now.month();
FIRST = false;
}
// Visualizzo a schermo che viene modificato il mese, giorno e anno sono tratteggiati
oled.setCursor(0, 0);
sprintf(str, "%02d" , setmese);
oled.print("--/");
oled.print(str);
oled.print("/----");
// Se premo il pulsante2, aumento i mesi, se arrivano a 12, riparte da 1
if (digitalRead(pulsante2)) {
setmese++;
if (setmese > 12) setmese = 1;
delay(200);
}
// Se premo il pulsante1, diminuisco i mesi, se arriva a 1, riparte da 12
if (digitalRead(pulsante1)) {
setmese--;
if (setmese < 1) setmese = 12;
delay(200);
}
// Se premo il pulsante3, salvo il mese impostato nel RTC e vado allo stato 6 - impostaAnno()
if (digitalRead(pulsante3)) {
rtc.adjust(DateTime(now.year(), setmese, now.day(), now.hour(), now.minute(), now.second()));
stato = 6;
FIRST = true;
delay(200);
}
}
// Imposto la variabile setanno = 2021, nel caso perdo data/ora non devo scorrere tutti i millenni
int setanno = 2021;
// stato 6 - Qui imposto l'anno della data
void impostaAnno() {
if (FIRST) {
oled.clear();
now = rtc.now();
FIRST = false;
}
// Visualizzo a schermo che viene modificato l'anno, giorno e mese sono tratteggiati
oled.setCursor(0, 0);
oled.print("--/--/ ");
oled.print(setanno);
// Se premo il pulsante2, aumento l'anno
if (digitalRead(pulsante2)) {
setanno++;
delay(200);
}
// Se premo il pulsante1, diminuisco l'anno
if (digitalRead(pulsante1)) {
setanno--;
delay(200);
}
// Se premo il pulsante3, salvo l'anno impostato nel RTC e vado allo stato 0 - DataOra()
if (digitalRead(pulsante3)) {
rtc.adjust(DateTime(setanno, now.month(), now.day(), now.hour(), now.minute(), now.second()));
stato = 0;
FIRST = true;
delay(200);
}
}
// stato 10 - Qui attivo la sveglia
void accendiSveglia() {
if (FIRST) {
oled.clear();
oled.setCursor(0, 0);
oled.print("Sveglia: ");
FIRST = false;
}
// In base allo stato di ALARM, scrivo se la sveglia è attiva o spenta
oled.setCursor(10, 0);
if (ALARM) {
oled.print("ON ");
}
else {
oled.print("OFF");
}
// Se premo pulsante1 o pulsante2, cambio lo stato attuale della sveglia
if (digitalRead(pulsante1) || digitalRead(pulsante2)) {
ALARM = !ALARM;
delay(200);
}
// Premendo il pulsante3, confermo lo stato della sveglia
// Se spenta vado alla schermata principale - stato 0, se accesa vado allo stato 11 - impostaOraSveglia()
if (digitalRead(pulsante3)) {
if (!ALARM) stato = 0;
else stato = 11;
FIRST = true;
delay(300);
}
}
// stato 11 - Qui imposto alla variabile alarmh l'ora corrente
void impostaOraSveglia() {
if (FIRST) {
oled.clear();
now = rtc.now();
alarmh = now.hour();
FIRST = false;
}
oled.setCursor(0, 0);
sprintf(str, "%02d" , alarmh);
oled.print(str);
oled.print(" : -- : -- A");
// Se premo il pulsante2, aumento le ore per la sveglia
if (digitalRead(pulsante2)) {
alarmh++;
if (alarmh >= 24) alarmh = 0;
delay(200);
}
// Se premo il pulsante1, diminuisco le ore per la sveglia
if (digitalRead(pulsante1)) {
alarmh--;
if (alarmh < 0) alarmh = 23;
delay(200);
}
// Se premo il pulsante3, confermo l'ora impostata e vado allo stato 12 - impostaMinutiSveglia()
if (digitalRead(pulsante3)) {
stato = 12;
FIRST = true;
delay(200);
}
}
// stato 12 - Qui imposto i minuti della sveglia
void impostaMinutiSveglia() {
if (FIRST) {
oled.clear();
now = rtc.now();
alarmm = now.minute();
FIRST = false;
}
oled.setCursor(0, 0);
sprintf(str, "%02d" , alarmm);
oled.print("-- : ");
oled.print(str);
oled.print(" : -- A");
// Se premo il pulsante2, aumento i minuti della sveglia
if (digitalRead(pulsante2)) {
alarmm++;
if (alarmm >= 60) alarmm = 0;
delay(200);
}
// Se premo il pulsante1, diminuisco i minuti della sveglia
if (digitalRead(pulsante1)) {
alarmm--;
if (alarmm < 0) alarmm = 59;
delay(200);
}
// Se premo il pulsante3, salvo i minuti e torno alla schermata principale, stato 0 - dataora()
if (digitalRead(pulsante3)) {
stato = 0;
FIRST = true;
delay(200);
}
}
// stato 20 - Si attiva quando, la data impostata per la sveglia è uguale a quella del RTC
void allarmeSveglia() {
if (FIRST) {
oled.clear();
oled.setCursor(0, 0);
oled.print("SVEGLIA!!");
FIRST = false;
}
tone(6, 440, 100);
delay(100);
// Se premo uno qualsiasi dei 4 pulsanti, vado nello stato snooze
if (digitalRead(pulsante1) || digitalRead(pulsante2) || digitalRead(pulsante3) || digitalRead(pulsante4)) {
stato = 21;
FIRST = true;
delay(300);
}
}
// Creo variabili per il posponi
int posponim1 = 0;
int posponim2 = 0;
// Attivo il posponi per 5 minuti, se premo il tasto 4 per 5 secondi disattivo la sveglia
void posponiSveglia() {
noTone(6);
if (FIRST) {
oled.clear();
now = rtc.now();
posponim1 = now.minute();
posponim2 = posponim1 + 1;
alarmm = posponim2;
stato = 0;
FIRST = true;
delay(200);
}
}
// Stato 30 - Qui gestisco la radio FM
void radioFM() {
Serial.print("funzione radio fm");
}
// Stato 40 - Qui gestisco per il meteo/temperatura
void meteo() {
Serial.print("funzione meteo");
}