ciao ragazzi, ho un problema con un sensore della amphenol di temperatura ztpd 2210(i2c).
Il sensore restituisce valori totalmente alterati(anche negativi e di molto), quindi credo ci sia un problema nella lettura dei byte relativi alla lettura dopo aver dato il comando. Ho provato anche utilizzando un raspberry attivando da software le R di pullup da 4.7k.
Non so più che pesci prendere ed è un progetto per un esame che ho tra 5 giorni.
Questo è il codice:
#include <Wire.h>
#define SENSOR_ADDR 0x38 // Indirizzo I²C del sensore
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
Wire.beginTransmission(SENSOR_ADDR);
Wire.write(0xAA); // Comando per leggere la temperatura
Wire.endTransmission();
delay(80); // Attendi il completamento della misurazione
Wire.requestFrom(SENSOR_ADDR, 3);
if (Wire.available() == 3) {
uint8_t byte0 = Wire.read();
uint8_t byte1 = Wire.read();
uint8_t byte2 = Wire.read();
int32_t rawData = (byte0 << 16) | (byte1 << 8) | byte2;
float temperature = (rawData / 16777216.0) * 130.0 - 20.0;
Serial.print("Temperatura: ");
Serial.print(temperature);
Serial.println("°C");
}
delay(1000); // Attendi un secondo prima della prossima lettura
}
Stai invertendo l'ordine dei byte ricevuti. Il sensore segue la codifica "Little Endian" ovvero il byte LSB per primo, ma tu lo stai shiftando a sinistra di 16 bit trattandolo come se fosse il più significativo. Stessa cosa per il resto dei byte ovviamente.
devi semplicemente invertire l'ordine dei byte quando ricostruisci rawData tenendo conto che byte2 è il byte più significativo e byte0 quello meno significativo, ovvero:
Non avevo guardato con attenzione il tuo sketch, pardon.
Tu stai inviando indirizzo i2c e comando 0xAA, ma nel datasheet c'è scritto che il comando da usare dovrebbe essere 0xAF.
Inoltre secondo me il primo byte che ricevi a prescindere dal comando inviato è lo status byte
In effetti il datasheet non è molto chiaro in proposito...
L'ideale sarebbe avere un analizzatore logico di segnali e vedere effettivamente quanti byte restituisce il sensore.
In alternativa, metti da parte un attimo la ricostruzione del dato e invece che leggere solo 3 byte, prova a stampare tutto quello che arriva sul bus usando un ciclo while.
Una volta che hai chiarito quale byte si trova in quale posizione, puoi procedere con il resto.
while (Wire.available()) {
Serial.print(Wire.read(), HEX);
}
Prova a stampare tutto come ti dicevo, lascia perdere la conversione per ora.
Se non capisci quali byte e come sono ordinati è inutile che provi a convertire.
Inoltre ribadisco che il datasheet è veramente incasinato...
Quello che chiama Byte (0) nella figura è in realtà il byte MSB perché piccolo piccolo c'è scritto SensorDat <23:16> ovvero i bit dal 17-simo fino al 24-simo di SensorDat quindi è giusto lo shift come l'hai fatto inizialmente (ma con i byte corretti evidentemente).
E' corretto come hai fatto inizialmente in teoria, ma devi scartare lo status byte ovviamente.
Inoltre ti conviene leggere tutti i byte anche se non li usi, altrimenti al loop successivo andrai a leggere quelli rimanenti incasinando tutto.
Prova a stampare il valore e poi verifica con la calcolatrice di windows (modalità programmatore).
rawData è una variabile da 32 bit, ma tu ne stai leggendo solo 24.
Può darsi che lo spazio di memoria che viene riservato per la variabile da 32 contenga già dati vecchi e quindi ottieni un risultato non coerente.
Prova ad inizializzarla al valore zero prima di fare lo shift.
Se anche così ancora non va allora probabilmente è un problema di casting delle variabili int8_t.
Appena metto le mani su un PC prova a fare qualche test con il simulatore online
Allora, come sospettavo, il problema è dovuto alla promozione implicita ad un tipo di dati più grande.
Nel dettaglio il risultato di (byte0 << 16) viene implicitamente promosso al tipo dati int, ma nella piattaforma Arduino il tipo dati int occupa solo 2 byte che sono ancora insufficienti per eseguire correttamente lo shift.
La soluzione è fare un casting esplicito promuovendo le variabili ad un tipo di dati corretto per l'operazione da eseguire.
cortesemente, come prima cosa, leggi attentamente il REGOLAMENTOdi detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazioneNELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.