Creare passo a passo radiosveglia con Dot Matrix

Vi aggiorno sulla situazione, ho fatto dei progressi, ho capito meglio parti del codice e sono riuscito ad implementare la visualizzazione del RTC e sensore di temperatura assieme.

Però non riesco ancora a modificare, come voglio, la visualizzazione di data e ora, pur cercando su internet, RTC by Makuna è l'unica libreria con cui riesco a gestirlo.

Mentre per migliorare la visualizzazione del display, vorrei apportare alcune modifiche.
Al posto della scritta T o Temperatura, sono riuscito ad inserire il simbolo del termometro.
Per l'umidità vorrei inserire il simbolo della goccia, ma viene visualizzato un 1, qualche consiglio?

Tra le migliorie, vorrei inserire la visualizzazione di una scritta o effetti, quando Arduino viene alimentato nuovamente.
Così mentre viene eseguito il codice e controlli, il display non resta illuminato e vuoto per i secondi necessari.
Verrebbe utile anche in futuro, quando con i pulsanti, per gestire una funzione, in primo piano esce la scritta con la funzione scelta, così da facilitare l'uso.

Scusate per le diverse domande, già in rete si trovano una miriade d'esempi, come per il DHT11, ma spesso sono totalmente diversi
Grazie

Ciao a tutti, vi aggiorno sugli sviluppi.
Riesco a gestire in modo basico il buzzer attivo, fotoresistenza, LCD e DHT11.
Visualizzo a schermo le icone del termometro e la goccia per l'umidità.

Mentre non riesco ad uscirne con RTC basato su DS1302, ogni volta c'è un problema diverso, visualizzo caratteri strani, non tiene in memoria data e ora (se premo reset) riparte da quella del programma o resta fissa quella di programmazione.
Questo provando diverse librerie, presenti sia qui nel forum, che direttamente nell'IDE.

Sinceramente ho qualche dubbio, sull'effettivo funzionamento, come posso verificarlo?
Grazie

... ma nel codice c'è ancora questo:

RtcDateTime compiled = RtcDateTime(__TIME__, __DATE__);
...
Rtc.SetDateTime(compiled);

... perché il compito è proprio quello di impostare il RTC alla data/ora in cui hai compilato l'ultima volta il programma!

La batteria di backup è carica, di tipo ricaricabile e ben collegata? Il quarzo da 32768 KHz è saldato vicinissimo al chip? i collegamenti sono come da datasheet?

... semplicemente usando uno degli esempi che è a corredo della libreria che usi.

Guglielmo

Ciao, grazie per la risposta.
Con calma mi sono ripassato il libro dei progetti di Arduino e capito meglio alcune cose, come if ed else e Tone.

Riguardo l'RTC, con l'esempio, vedo che funziona e visualizza l'ora nel monitor seriale ogni 10 secondi, quindi non avrebbe problemi.
Come libreria uso RTC by Makuna, per curiosità, che differenza c'è con le altre disponibili?

Nel mio uso finale, vorrei impostare, data e ora tramite dei pulsanti, ma in questo caso come imposto il programma per comunicare con l'RTC?

Grazie

Ciao, vi aggiorno per dirvi che più o meno riparto da zero con il progetto, perchè posso usare parecchi nuovi componenti.
Alcuni sono in prestito da un amico che usò per le sue prove, quindi mi trovo con dei sensori/moduli "doppi" nella funzionalità

Volevo un vostro parere su quali conviene usare e se impostando il programma a stati con ogni loop separato è meglio, così da avere più flessibilità futura per eventuali modifiche/aggiunte.

I componenti nuovi sono:
LM35DZ: temperatura
DS18B20: temperatura
DHT22: temperatura e umidità
SHT31: temperatura e umidità
BMP280: temperatura e barometro
BMP180: barometro a 3.3v
DS1307: rtc
DS3231: rtc con eeprom sulla schedina
Display oled 0.96" SSD1306
ADXL335: accelerometro

In più una miriade di altri componenti come condensatori, transistor, diodi, amplificatori e cavi vari

Grazie per i vostri consigli

Ciao a tutti, seguendo un po' di esempi su Internet e guide varie, sono riuscito ad impostare le prime basi per la radiosveglia, usando un LCD.
Riesco ad impostare l'ora ed attivare la sveglia, ma ho diversi problemi.

Ho modificato il programma d'esempio, togliendo i secondi da impostare nella sveglia, perchè non mi interessano, ma così facendo non riesco a disattivarla, finchè non passa un minuto.
Il mio obiettivo era quello di premere un pulsante qualsiasi, per attivare uno snooze di 5 minuti e tenendo premuto il pulsante d'attivazione per 5 secondi per spegnerla.

Ho già aggiunto la funzione di 2 pulsanti aggiuntivi per accendere la radio e una specie di meteo, dove sfruttando il barometro incorporato nel sensore e gli altri dati di temperatura, vorrei ottenere un risultato simile a quello dei barometri analogici, cioè altitudine, pressione atmosferica e previsioni a spanne.

Nel frattempo sto studiando ancora come usare il display Dot Matrix e come mettere assieme il tutto.

Vi allego il programma, per i vostri suggerimenti e migliorie
Grazie

[code]
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16,2);
RTC_DS1307 rtc;

int stato = 0;
char str[3];
char settimana[7][4] = {"dom", "lun", "mar", "mer", "gio", "ven", "sab"};
DateTime now;

int alarmh, alarmm;
bool ALARM = false;

void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, OUTPUT);
  
  lcd.init();
  lcd.backlight();
  if (! rtc.begin()) {
    Serial.println("controlla rtc");
    abort();
  }
  if (! rtc.isrunning()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

void loop() {
  switch (stato) {
    case 00:
      dataora();
      break;
    case 01:
      impostaOra();
      break;
    case 02:
      impostaMinuti();
      break;
    case 03:
      impostaSecondi();
      break;
    case 10:
      accendiSveglia();
      break;
      case 11:
      impostaOraSveglia();
      break;
      case 12:
      impostaMinutiSveglia();
      break;
      case 20:
      allarmeSveglia();
      break;
      case 30:
      accendiRadio();
      break;
      case 40:
      condizioniMeteo();
      break;
  }     
}

bool FIRST = true;
unsigned long t1, dt;
int ch, cm, cs;

void dataora() {
  if (FIRST) {
    lcd.clear();
    t1 = millis();
    FIRST = false;
  }

  dt = millis() - t1;
  if (dt > 500) {
    now = rtc.now();
    ch = now.hour();
    cm = now.minute();
    cs = now.second();

    
    lcd.setCursor(0,0);
    
    sprintf(str, "%02d", ch);
    lcd.print(str);
    lcd.print(":");
    sprintf(str, "%02d", cm);
    lcd.print(str);
    lcd.print(":");
    sprintf(str, "%02d", cs);
    lcd.print(str);

    lcd.setCursor(0,1);
    if (ALARM) {
      lcd.print("SVEGLIA ON");
    } else {
        lcd.print(settimana[now.dayOfTheWeek()]);
        lcd.print(" ");
        lcd.print(now.day(), DEC);
        lcd.print('/');
        lcd.print(now.month(), DEC);
        lcd.print('/');
        lcd.print(now.year(), DEC);
    }

    if ( (ch == alarmh) && (cm == alarmm)) {
      stato = 20;
      FIRST = true;
  }
    
    t1 = millis();
  }

  if (digitalRead(4)) {  //Imposta ora
    stato = 01;
    delay(300);
    FIRST = true;
  }
  if (digitalRead(5)) {   //Imposta sveglia
    stato = 10;
    delay(300);
    FIRST = true;
  }
  if (digitalRead(3)) {   //Radio
    stato = 30;
    delay(300);
    FIRST = true;
  }
  if (digitalRead(2)) {   //Meteo
    stato = 40;
    delay(300);
    FIRST = true;
  }
}

int seth = 0;

void impostaOra() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    seth = now.hour();
    lcd.setCursor(0,0);
    lcd.print("Imposta ora");
    FIRST = false;
  }
  lcd.setCursor(0,1);
  sprintf(str, "%02d" ,seth);
  lcd.print(str);

   if (digitalRead(5)) {
    seth++;
    if (seth >= 24) seth = 0;
    delay(200);
   }
   if (digitalRead(4)) {
    rtc.adjust(DateTime(now.year(), now.month(), now.day(), seth, now.minute(), now.second()));
    stato = 02;
    FIRST = true;
    delay(200);
   }
}

int setm = 0;

void impostaMinuti() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    setm = now.minute();
    lcd.setCursor(0,0);
    lcd.print("Imposta minuti");
    FIRST = false;
  }
  lcd.setCursor(0,1);
  sprintf(str, "%02d" ,setm);
  lcd.print(str);

   if (digitalRead(5)) {
    setm++;
    if (setm>= 60) setm = 0;
    delay(200);
   }
   if (digitalRead(4)) {
    rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), setm, now.second()));
    stato = 03;
    FIRST = true;
    delay(200);
   }

}

int sets = 0;

void impostaSecondi() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    sets = now.second();
    lcd.setCursor(0,0);
    lcd.print("Imposta secondi");
    FIRST = false;
  }
  lcd.setCursor(0,1);
  sprintf(str, "%02d" ,sets);
  lcd.print(str);

   if (digitalRead(5)) {
    sets++;
    if (sets>= 60) sets = 0;
    delay(200);
   }
   if (digitalRead(4)) {
    rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), sets));
    stato = 00;
    FIRST = true;
    delay(200);
   }
}

void accendiSveglia() {
  if (FIRST) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Imposta sveglia");
    FIRST = false;
  }
  lcd.setCursor(0,1);
  if (ALARM) {
    lcd.print("ATTIVA");
  } else {
    lcd.print("SPENTA");
  }

   if (digitalRead(5)) {
    ALARM = !ALARM;
    delay(200);
   }
   if (digitalRead(4)) {
    if (!ALARM) stato = 00;
    else stato = 11;
    FIRST = true;
    delay(300);
   }
}

void impostaOraSveglia() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    alarmh = now.hour();
    lcd.setCursor(0,0);
    lcd.print("Ora sveglia");
    FIRST = false;
  }
  lcd.setCursor(0,1);
  sprintf(str, "%02d" ,alarmh);
  lcd.print(str);

   if (digitalRead(5)) {
    alarmh++;
    if (alarmh>= 60) alarmh = 0;
    delay(200);
   }
   if (digitalRead(4)) {
    stato = 12;
    FIRST = true;
    delay(200);
   }
}

void impostaMinutiSveglia() {
  if (FIRST) {
    lcd.clear();
    now = rtc.now();
    alarmm = now.minute();
    lcd.setCursor(0,0);
    lcd.print("Minuti sveglia");
    FIRST = false;
  }
  lcd.setCursor(0,1);
  sprintf(str, "%02d" ,alarmm);
  lcd.print(str);

   if (digitalRead(5)) {
    alarmm++;
    if (alarmm>= 60) alarmm = 0;
    delay(200);
   }
   if (digitalRead(4)) {
    stato = 00;
    FIRST = true;
    delay(200);
   }
}

int allarmeSveglia() {
  if (FIRST) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("SVEGLIA!!");
    FIRST = false;
  }

  tone(6, 440, 100);
  delay(100);
  if (digitalRead(4) || digitalRead(5) || digitalRead(4) || digitalRead(3)) {
    ALARM = !ALARM;
    stato = 00;
    FIRST = true;
    delay(300);
  }
}

void accendiRadio() {
  lcd.clear();
  lcd.print("RADIO IN ARRIVO!");
  delay(1000);
  stato = 00;
}

void condizioniMeteo() {
  lcd.clear();
  lcd.print("METEO IN PROVA!");
  delay(1000);
  stato = 00;
} 
[/code]

Nessun aiuto per la sveglia? :innocent:
Grazie

Ciao a tutti, nel frattempo ho migliorato alcuni passaggi nella creazione della radiosveglia, specie per la visualizzazione in una sola riga e gestione dell'illuminazione esterna per la retroilluminazione della barra con MAX7219.

Riesco a far funzionare quasi tutti i componenti in modo separato, mentre non riesco ancora con la sveglia a creare una funzione di rinvio di 5 minuti dell'allarme e disattivazione premendo un pulsante per più di 5 secondi continuativi.

Qualche dritta?
Grazie

Il tuo programma non contiene NESUN COMMENTO. Quindi ci capisci solo tu o chiunque abbia voglia di fare un "reverse engineering" e io non ne ho voglia.

Posso solo dirti che quello che vuoi fare lo puoi gestire nel loop principale usando millis(). Setti una variabile globale quando la sveglia è stata zittita, ma non disattivata. Con millis() calcoli i 5 minuti e controlli il pulssnte di disattivazione. Se Scattano i 5 minuti fai suonare di nuovo la sveglia. Se il pulsante risulta premuto, sempre con millis() verifichi che resti premuto per 5 sec e in quel caso disattivi la sveglia. Purtroppo il tuo programma è pieno di delay che allungheranno un po' i tempi da rilevare con millis().

Ciao,
P.

Ciao, grazie per il consiglio, effettivamente facendo diverse prove, ho tralasciato la parte di commenti, che viene sempre utile anche per un mio riutilizzo futuro.
Provvederò a sistemarlo.

Per la sveglia, provo a seguire il tuo esempio e vedo cosa riesco ad ottenere.
Aggiornerò il post
Grazie