Ciao a tutti :),
da un paio di giorni, mi sono messo a giocare con un RTC DS3231 (http://datasheets.maximintegrated.com/en/ds/DS3231.pdf), appurato che tutto sommato lo si può tranquillamente leggere e scrivere come fosse un DS1307, mi sono concentrato nella lettura del suo registro della temperatura, nel datasheet se ne parla a pag. 15.
Purtroppo per me restituisce i valori negativi in complemento a 2, mi sono andato a studiare come funziona la cosa ed avrei scritto lo sketch che vedete qui sotto.
#include <Wire.h>
byte secondi, minuti, ora, giornosett, giorno, mese;
int anno;
char* gset[] = {"Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi", "Sabato", "Domenica"};
byte decToBcd(byte val) // Da decimale a binario
{ return ( (val / 10 * 16) + (val % 10) );
}
byte bcdToDec(byte val) // Da binario a decimale
{ return ( (val / 16 * 10) + (val % 16) );
}
void LetturaDataOra()
{ Wire.beginTransmission(0x68);
Wire.write((byte)0x00);
Wire.endTransmission();
Wire.requestFrom(0x68, 7);
//recupero i 7 byte relativi ai corrispondenti registri
secondi = bcdToDec(Wire.read() & 0x7f);
minuti = bcdToDec(Wire.read());
ora = bcdToDec(Wire.read() & 0x3f);
giornosett = bcdToDec(Wire.read());
giorno = bcdToDec(Wire.read());
mese = bcdToDec(Wire.read());
anno = bcdToDec(Wire.read()) + 2000;
}
float Temp() {
Wire.beginTransmission(0x68);
Wire.write(0x11);
Wire.endTransmission();
Wire.requestFrom(0x68, 2);
int MSBtemp = Wire.read();
byte LSBtemp = Wire.read();
if (MSBtemp >> 7 == 1) //controllo il bit 7 per sapere se ho ricevuto un numero negativo
MSBtemp = ~(~MSBtemp + 1 + 128) + 1; // se lo è eseguo la coversione del byte con complemento a 2
float Temperature = (float) (MSBtemp) + (float) ((LSBtemp >> 6) * 0.25);
return Temperature;
}
void stampa0 (int dato_tempo)
{ if (dato_tempo < 10)
Serial.print(F("0"));
Serial.print(dato_tempo);
}
void setup()
{
//inizializzo la seriale
Serial.begin(9600);
//inizializzo la libreria
Wire.begin();
Wire.beginTransmission(0x68); //il primo byte stabilisce il registro iniziale da scivere
Wire.write((byte)0x00);
Wire.write(decToBcd(1));
Wire.write(decToBcd(41));
Wire.write(decToBcd(10));
Wire.write(decToBcd(2));
Wire.write(decToBcd(8));
Wire.write(decToBcd(4));
Wire.write(decToBcd(14));
Wire.endTransmission();
}
void loop()
{
LetturaDataOra();
Serial.print(gset[giornosett - 1]);
Serial.print(" ");
stampa0(giorno);
Serial.print("/");
stampa0(mese);
Serial.print("/");
stampa0(anno);
Serial.print(" ");
stampa0(ora);
Serial.print(":");
stampa0(minuti);
Serial.print(":");
stampa0(secondi);
Serial.print(" Temperatura: ");
Serial.print(Temp());
Serial.println();
delay(1000);
}
Nella pratica, ho fatto un po’ di prove in quest’altro sketch e sembra che la conversione dei binari a 7 bit funzioni, in alto nei commenti ho messo un paio di esempi da provare.
/* -25 = -00011001
11100110 + byte negato
1
--------
11100111 complemento a 2 ovvero come dovrebbe essere il registro dell'RTC in caso di temperatura -25
-40 = -00101000
11010111 + byte negato
1
--------
11011000 complemento a 2 ovvero come dovrebbe essere il registro dell'RTC in caso di temperatura -25
*/
byte regtemp_RTCDS3231 = B11100111; // -25 complemento a due
void setup() {
Serial.begin(9600);
Serial.print("regRTCDS3231= ");
Serial.print(regtemp_RTCDS3231, BIN); // giusto per essere sicuro che il byte sia memorizzato correttamente
Serial.print(" Valore decimale = ");
if (regtemp_RTCDS3231 >> 7 == 1) { // se il bit 7 è 1 ho un valore negativo
bitWrite(regtemp_RTCDS3231, 7, 0); // azzero il bit del segno
int valore_dec = ~(~regtemp_RTCDS3231 + 1 + 128) + 1;
Serial.print(" Valore decimale = ");
Serial.print(valore_dec);
}
else
Serial.print(regtemp_RTCDS3231);
}
void loop() {
// put your main code here, to run repeatedly:
}
Nella teoria però non sono sicuro di aver fatto le cose a modino, a dirla tutta, a furia di fare tentativi non ricordo nemmeno più come ci sono arrivato , magari c’è un metodo molto più semplice, se fosse me lo potreste illustrare?
Chiaramente la prova pratica la farò stasera tenendo l’RTC nel freezer per un po’ e andandolo a leggere poi, ovviamente con le dovute cautele e cercando il più possibile di evitare corti dovuti alla condensa o altro.
Grazie in anticipo per il tempo che vorrete dedicarmi.