salve a tutti.
Ho collegato un AM2321 al mio arduino micro e funziona benino.
l'unico problema che ho riscontrato e, che non riesco a risolvere, è che quando
effettuo la lettura su di esso alcune volte si blocca tutto.
ecco il codice:
void loop()
{
static bool ct1=false,ct2=false,ct3=false;
if(millis()-relztime > 500 && !ct1)
{leggisensori();ct1=true;} //questo ci impiega circa 20 millisecondi ma alcune volte anche 8000 secondi
if(millis()-relztime > 700 && !ct3)
{ VisualizzaMainScreen(); ct3=true;} //questo ci impiega circa 120 millisecondi
if(millis()-relztime > 900 && !ct2)
{ controllotasti(); ct2=true;} //questo ci impiega circa 20 millisecondi
if(millis()-relztime >= (100-p0)*10)
digitalWrite(4,true); //accende in base alla percentuale p0
if(millis()-relztime >= 999)
{
ct1=false;ct2=false;ct3=false; //resetta le variabili statiche
relztime=millis(); //ogni secondo ricomincia il conteggio
digitalWrite(4,false); // e spegne
}
}
void leggisensori()
{
am2321.read();
if(am2321.available())
{
u0= am2321.humidity/10.0L;
t1= am2321.temperature/10.0L;
}
}
Non capisco come mai succede: di norma la funzione leggisensori() impiega solo pochi millisecondi, altre volte impiega fino a otto secondi per effettuare le letture.
Questa cosa non va bene inquanto tutto il programma così va in malfunzionamento.
qualcuno mi può aiutare?
grazie e saluti.
La prima cosa che risulta evidente è lo scheduler delle varie operazioni che mi sembra un po' contorto.
Ma, a parte questo, nel calcolo della temperatura ed umidità dividi per 10.0L che non mi sembra corretto visto che la prima variabile è unsigned int e la seconda int.
u0= am2321.humidity / 10;
t1= am2321.temperature / 10;
Dovresti vedere il codice del metodo .read della classe am2321 all'interno della libreria.
Potrebbero esserci dei while o dei delay di attesa finché il dato non è disponibile.
Grazie PaoloP. Hai centrato il problema:
ho già fatto un po' di debugging delle librerie utilizzate per la lettura del sensore.
Mi sono accorto che il blocco avviene proprio nel metodo read() della classe wire.
Infatti la classe AM2321 utilizza wire.h per leggere i dati in modo seriale.
di seguito il codice detto cioè il metodo usato da AM2321 per leggere tramite wire.h:
Il blocco avviene proprio in questa funzione.
Ho notato inoltre che il blocco aumenta la propria frequenza con l'aumentare del valore dell'umidità.
credo dunque che il problema sia proprio nel chip del sensore che s'imballa.
Però il fatto che la libreria wire.h non preveda il blocco dei looping di lettura mi sembra un po'
grave...forse il codice è giovane?
ciao e grazie.
risolto!!!!
nella twi.h dei cicli while non controllati entravano in looping infinito
ho modificato un po' così:
#define TIMEOUT 250
uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop)
{
uint8_t i;
unsigned long tempo;
// ensure data will fit into buffer
if(TWI_BUFFER_LENGTH < length){
return 1;
}
// wait until twi is ready, become master transmitter
tempo=millis();
while(TWI_READY != twi_state)
{
if(millis()-tempo>TIMEOUT) return 4; //se il loop impiega più del tempo prestabilito esce e torna un errore
continue;
}
twi_state = TWI_MTX;
twi_sendStop = sendStop;
// reset error state (0xFF.. no error occured)
twi_error = 0xFF;
// initialize buffer iteration vars
twi_masterBufferIndex = 0;
twi_masterBufferLength = length;
// copy data to twi buffer
for(i = 0; i < length; ++i){
twi_masterBuffer[i] = data[i];
}
// build sla+w, slave device address + w bit
twi_slarw = TW_WRITE;
twi_slarw |= address << 1;
// if we're in a repeated start, then we've already sent the START
// in the ISR. Don't do it again.
//
if (true == twi_inRepStart) {
// if we're in the repeated start state, then we've already sent the start,
// (@@@ we hope), and the TWI statemachine is just waiting for the address byte.
// We need to remove ourselves from the repeated start state before we enable interrupts,
// since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning
// up. Also, don't enable the START interrupt. There may be one pending from the
// repeated start that we sent outselves, and that would really confuse things.
twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR
TWDR = twi_slarw;
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START
}
else
// send start condition
TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs
// wait for write operation to complete
tempo=millis();
while(wait && (TWI_MTX == twi_state))
{
if(millis()-tempo>TIMEOUT) return 4; //se il loop impiega più del tempo prestabilito esce e torna un errore
continue;
}
if (twi_error == 0xFF)
return 0; // success
else if (twi_error == TW_MT_SLA_NACK)
return 2; // error: address send, nack received
else if (twi_error == TW_MT_DATA_NACK)
return 3; // error: data send, nack received
else
return 4; // other twi error
}