Vi scrivo perchè ho un problema con un DS3231 collegato ad un arduino nano 328P.
Il programma che sto scrivendo dovrebbe scrivermi i secondi su seriale ma evidentemente non ho capito bene come funzioni la comunicazione tra l'RTC e l'arduino.
Ho letto il datasheet (gli inzirizzi sono a pagina 11) e ho cercato di capire come fare funzionare la comunicazione tra questo sensore e l'arduino senza l'utilizzo di librerie esterne (come consigliava un utente qui sul forum in una vecchia discussione che ho trovato mentre cercavo di risolvere il problema).
Vi incollo anche il codice che ho scritto, con tanto di commenti: vi prego di non risparmiarmi critiche.
#define ripeti 1
#define bit_vettore 7
void decabin(int num);
int bin[bit_vettore]={0,0,0,0,0,0,0};
#include<Wire.h>
int ind_RTC = 0x57; // indirizzo sensore RTC
int ind_sec = 0; // Indirizzo decine di secondi
int ind_min = 1; // Indirizzo decine di minuti
int ind_ora = 2; // Indirizzo ore
int ind_g_sett = 3; // Indirizzo giorni della settimana
int sec = 0; // Secondi
int u_min = 0; // Unità di minuti
int d_min = 0; // Decine di minuti
int u_ore = 0; // Unità di ore
int d_ore = 0; // Decine di ore
int g_sett = 0; // Giorno della settimana
int tmp=0;
int j=1; // serve per un ciclo nel loop()
void setup() {
Serial.begin(9600); // frequenza di trasmissione tra Arduino e PC
Serial.print("SI COMINCIA!!!!! \n"); // Stampa su monitor seriale la stringa in argomento
}
void loop() {
int i=0; // serve per ciclare in tutte le funzioni del programma
int k = 0; // serve per ciclare in tutte le funzioni del programma
sec =0 ;
if(j==1){ // serve per non ripetere il loop grazie a...
j=ripeti; // ... questo: se j==0,scrive una volta sola. se j!=0, ripete all'infinito.
Wire.begin(); // inizializzo la libreria Wire
Wire.beginTransmission(ind_RTC); // inizio la trasmissione con l'RTC
Wire.write(ind_sec); // voglio leggere i minuti
Wire.endTransmission(); // ho finito di leggere i minuti
Wire.requestFrom(ind_RTC,1); // richiedo il valore acquisito...
tmp= Wire.read(); // ... e lo salvo in tmp
decabin(tmp); // adesso quel valore lo converto in binario e salvo ogli cifra di quel numero binario nel vettore globale bin[];
// PARTE CON IL MSB
sec = (4*bin[0]+2*bin[1]+bin[2]) * 10 +8*bin[3]+4*bin[4]+2*bin[5]+bin[6];
//qui sopra ho trasformato i 7 bit che mi ha trasmesso l'rtc in secondi,
//partendo dai primi tre che mi indicano le decine dei secondi
//e proseguendo con gli ultimi 4 che mi indicano le unità.
// Questo metodo non funziona.
Serial.println(sec); // stampo su seriale i secondi
delay(2000); //aspetto due secondi prima di ricominciare il loop
} // CHIUSA GRAFFA DELL'IF(j==0), NON DEL LOOP!!!
}// QUESTA INVECE È PROPRIO LA CHIUSA GRAFFA DEL LOOP
void decabin(int num){ // Questa funzione converte il numero decimale passatogli in argomento in binario
// salvandone ciascun bit in un elemento del vettore bin []. Questa funziona, l'ho provata.
int i =0;
for(i=0;i<bit_vettore;i++){
bin[i]= (num%2);
num = floor(num/2); // lo so che il floor non serve perchè la variabile è di tipo int...
}
}
Ho provato ad installare alcune librerie per il funzionamento del DS3231 ma nessuna di queste in realtà funzionava, quindi ho cercato su questo forum ed ho trovato questa discussione:
nid69ita:
Io uso la lib senza problemi. rtc by makuna
Innanzi tutto ti ringrazio tantissimo perché l'ho scaricata e sembra funzionare, anche se, dal momento che vorrei imparare, mi piacerebbe non utilizzare librerie ove (forse?) non sono necessarie e soprattutto capire cosa sto sbagliando nell'estrapolazione dei dati che cerco di fare con il mio programma... dopotutto ci sarà qualcuno che le librerie le scrive e quindi sa come trasformare ciò che esce dall'SDA in fantastici dati.
propifol:
soprattutto capire cosa sto sbagliando nell'estrapolazione dei dati che cerco di fare con il mio programmai.
Non hai letto con attenzione il datasheet
"The contents of the time and calendar registers are in the binary-coded decimal (BCD) format."
Quindi se l' orologio segna le 15,40 i dati ti arrivano cosi
(0001 0101) (0100 0000) ogni 4 bit si ha un digit se come hai fatto tu converti in decimale hai 21 e 64 invece che 15 e 40 e il tuo orologio da i numeri !
Dal gestore librerie installa la RTClib che ti permette di usare le stesse funzioni su diversi RTC hardware e uno software con millis.
Tra gli esempi ce n'è uno per DS3131.
Per il datalogger leggiti i post in inglese su questo blog
L'autore scrive in inglese anche su questo forum.
Ci sono un sacco di trucchi per realizzare un economico datalogger con Pro Mini e DS3231 e l'autore ha parecchia esperienza rispetto agli altri progetti che ho visto.
Io ho usato anche lo shield con il DS1307 e la microSD ma non va bene per i progetti a batteria a meno di non usare batterie giganti o solo per poco tempo.
La prima converte il valore decimale in BCD e la seconda dal BCD in decimale.
Guglielmo
PaoloF_60:
Non hai letto con attenzione il datasheet
"The contents of the time and calendar registers are in the binary-coded decimal (BCD) format."
Quindi se l' orologio segna le 15,40 i dati ti arrivano cosi
(0001 0101) (0100 0000) ogni 4 bit si ha un digit se come hai fatto tu converti in decimale hai 21 e 64 invece che 15 e 40 e il tuo orologio da i numeri !
Ciao
Paolo
Grazie mille per l'aiuto, siete stati molto cortesi e disponibili!
Ad ogni modo io pensavo di fare esattamente quello che mi avete detto voi tramite questa riga:
questi sono proprio solo i secondi dell'orario. in pratica converto in decimale i primi tre bit, memorizzati nel vettore, per creare le decine di secondi (quello che sarebbe il MSB delle decine dei secondi lo ignoro perchè dal datasheet si evince che è sempre 0, infatti le decine dei secondi vanno da 0 a 5 e non servirebbe). I 4 bit rimanenti, memorizzati negli altri elementi del vettore, una volta convertiti sempre nella riga qui sopra diventano le unità dei secondi.
zoomx:
Dal gestore librerie installa la RTClib che ti permette di usare le stesse funzioni su diversi RTC hardware e uno software con millis.
Tra gli esempi ce n'è uno per DS3131.
Per il datalogger leggiti i post in inglese su questo blog https://thecavepearlproject.org/
L'autore scrive in inglese anche su questo forum.
Ci sono un sacco di trucchi per realizzare un economico datalogger con Pro Mini e DS3231 e l'autore ha parecchia esperienza rispetto agli altri progetti che ho visto.
Ti ringrazio moltissimo per il consiglio e qualora avessi bisogno in futuro userò il sito che mi hai linkato come fonte per informazioni "certificate"
Stasera comunque ho finito quello che dovevo fare, a meno che non siano necessarie modifiche in futuro.
zoomx:
Io ho usato anche lo shield con il DS1307 e la microSD ma non va bene per i progetti a batteria a meno di non usare batterie giganti o solo per poco tempo.
Io ne avevo acquistato uno tempo fa e mi ero trovato malissimo (ho scritto per la prima volta su questo forum proprio per chiedere chiarimenti ): pensa che ho acceso e fatto partire l'rtc a settembre e riprovandolo la settimana scorsa mi segnava dicembre come "mese attuale" (quindi ha accumulato un ritardo di tre mesi in sette mesi)! Probabilmente sono stato sfortunato io con lo shield ma ora che ho provato il DS3231 probabilmente userò solo più questo. È vero che non ha lettore sd incorporato ma
Come batterie si potrebbe usare una maxi powerbank per esempio?
Anche i DS1307 che ho usato io danno questi problemi probabilmente perché il quarzo non è preciso e magari perché non è accoppiato bene al chip.
E' saltata una parte di ciò che hai postato ma si, i power bank vanno bene a meno di autoscarica. Il tizio del blog usa delle alcaline non ricaricabili. Non è un esperto di elettronica ma sui datalogger con componenti economici ha sperimentato molto e, soprattutto, li ha usati sul campo. Su alcune cose che lui descrive sul campionamento analogico ho dei dubbi ma in fondo io uso quasi solo sensori digitali.
Leggi le modifiche ai moduli DS3231, va rimosso un diodo e anche il led.
Lui poi usa i ProMini cloni cinesi dove rimuove il led e taglia la pista che viene dal regolatore, cosa che ho fatto anche io, il consumo in sleep cala drasticamente.
Lui poi usa la versione a 3.3V 8MHz per cui si collega direttamente alla microSD usando l'adattatore microSD/SD realizzato per il vecchio modello di RaspberryPI. Ma puoi utilizzare anche un adattatore normale a cui saldi i fili o dei pin.
L'alternativa sarebbe usare la versione più comune a 16MHz ma a 3.3V invece che a 5V solo che siamo fuori dalle specifiche, usando i 3.3V si potrebbe andare al massimo a 12MHz. PErò molti hanno provato e sembra che la cosa vada probabilmente perché la maggior parte del tempo la MCU è in sleep.
Nel suo blog c'è una pagina apposta per la realizzazione del datalogger con solo i 3 componenti che ti ho descritto ma non ricordo il link.