Sensore di umidità

Salve a tutti, qualcuno sa dove si può reperire un sensore che rileva l’umidità atmosferica a un prezzo contenuto?

Salve a tutti, alla fine ho deciso di provare con il sensore SHT11 della Sensirion, nonostante l’errore del negoziante che mi ha spedito la versione smd sono riuscito miracolosamente a saldarci dei fili e a collegarlo alla breadboard sperimentale. Oltre al sensore appena illustrato ho un RTC (DS1307) e un display lcd 16x2. Quello che devo fare è scrivere l’ora fornita dal DS1307 sulla prima riga del display, mentre sulla seconda riga voglio mettere la temperatura e l’umidità rilevate dal sensore. Sono riuscito a farlo funzionare, riesco a fargli rilevare la temperatura e l’umidità soltanto che ho riscontrato una cosa molto fastidiosa: l’orologio non va fluido, ma salta alcuni secondi. Posto lo script che ho semplificato per renderlo più leggibile:

#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>
#include <LiquidCrystal.h>
#include <SHT1x.h>
#define dataPin 12
#define clockPin 13
SHT1x sht1x(dataPin, clockPin);
float temp_c;
float humidity;
LiquidCrystal lcd(2,3,4,5,6,7,8);
int rtc[7];

void setup()
{
RTC.stop();
RTC.set(DS1307_SEC,1);
RTC.set(DS1307_MIN,59);
RTC.set(DS1307_HR,22);
RTC.set(DS1307_DOW,2);
RTC.set(DS1307_DATE,18);
RTC.set(DS1307_MTH,2);
RTC.set(DS1307_YR,9);
RTC.start();
lcd.begin(16,2);
lcd.clear();
}

void loop()
{
temp_c = sht1x.readTemperatureC();
humidity = sht1x.readHumidity();

lcd.setCursor(0,0); // prima riga display

RTC.get(rtc,true);
lcd.print(rtc[2]); // ore
lcd.print(":");
lcd.print(rtc[1]); // minuti
lcd.print(":");
lcd.print(rtc[0]); // secondi

lcd.setCursor(0,1); // seconda riga display
lcd.print(“T=”);
lcd.print(temp_c);
lcd.print(" U=");
lcd.print(humidity);
}

Secondo me l’errore sta nella libreria utilizzata per gestire il sensore perchè al suo interno contiene dei delay. In un altro script l’errore dell’orologio che salta i secondi l’ho risolto sostituendo i delay presenti con la funzione millis() consigliata da alcuni utenti del forum. Questa volta i delay sono in una libreria, come posso risolvere?
Grazie a tutti per l’attenzione

Ho fatto delle prove, sembra che i delay presenti nel file SHT1x.cpp vanno in qualche modo in conflitto con l'RTC. Ho provato a commentare i delay e l'orologio scorre fluido ma il sensore poi non restituisce nessun dato. Secondo voi esiste un modo per far funzionare l'RTC insieme al sensore?

ce lo hai vero? http://docs-europe.electrocomponents.com/webdocs/0d2f/0900766b80d2f542.pdf

Si, ce l'ho il datasheet, l'ho usato per vedere come collegare il sensore ad arduino. Mi spiego meglio, il sensore riesco a farlo interagire con arduino, mi restituisce temperatura e umidità. Il problema sta che nella libreria SHT1x utilizzata per farlo funzionare ho visto che ci sono 2 delay che interferiscono in qualche modo con un DS1307 (RTC), in pratica l'orologio salta parecchi secondi. Sto cercando un modo per cambiare i delay con la funzione millis() e non so neppure se è questo il modo per risolvere il problema, al momento brancolo nel buio.

uffi … io nn so leggere le dll … comunque è abbastanza normale un ritardo nei sensori … cioè soprattutto quelli di umidità fanno una media su più valori è anno un tempo … adesso nn ho tanto tempo … di leggere il datasheet, e vediano… se l’interrogazione dei sensori con tempi ben precisi … hai provato a vedere gli eventi nn so … qualcosa del tipo … if “”""" sht1x.humidyti.value “”" ecc…

Grazie per l’interesse mostrato, non ci sono dll da analizzare. Metto lo script incriminato della libreria, sono i 2 delay che in qualche modo danno fastidio all’RTC.

/**
*/
int SHT1x::shiftIn(int _dataPin, int _clockPin, int _numBits)
{
int ret = 0;
int i;

for (i=0; i<_numBits; ++i)
{
digitalWrite(_clockPin, HIGH);
delay(10); // I don’t know why I need this, but without it I don’t get my 8 lsb of temp
ret = ret*2 + digitalRead(_dataPin);
digitalWrite(_clockPin, LOW);
}

return(ret);
}

/**
*/

void SHT1x::waitForResultSHT(int _dataPin)
{
int i;
int ack;

pinMode(_dataPin, INPUT);

for(i= 0; i < 100; ++i)
{
delay(10);
ack = digitalRead(_dataPin);

if (ack == LOW) {
break;
}
}

if (ack == HIGH) {
//Serial.println(“Ack Error 2”); // Can’t do serial stuff here, need another way of reporting errors
}
}

dai un occhio ai posts http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1253800587/13#13
ho notato che il viene usato un protocollo i2c e nei posts indicati se ne parla…
magri è lì il problema… mma nn so …
la mia esperienza in “c” è modesta , ma c’è quella variabile"ret" che … nn n mi è chiara che funzione abbia… i delay sembrano obligatori per la costruzione del BYTE … di lettura …

Sicuro che venga utilizzato il protocollo i2c? Da quello che ho capito cercando in rete, il sensore non è i2c compatibile. Scusa la domanda forse stupida ma non si potrebbe risolvere sostituendo i delay con la funzione millis()?

da pagina 6 del datasheet... viene descritto il protocollo di comunicazione.. e a pagina 5 "The sensor cannot be addressed by I2C protocol; however, the sensor can be connected to an I2C bus without interference with other devices connected to the bus." quindi avevo letto un po' troppo veelocemente il documento e il "connected to" mi ha tratto in iganno ... comunque nn lo esclude del tutto . .. nel pome do un occhiata...meglio con la funzione millis() beh .. poi creare una sorta di evento in effetti ... a dopo ciao

prova cosi :

/**
 */
 int SHT1x::shiftIn(int _dataPin, int _clockPin, int _numBits)
{
int i;
long MillisecIniziali;
int ritardo=10;

  int ret = 0;

  for (i=0; i<_numBits; ++i)
  {
     digitalWrite(_clockPin, HIGH);
     
      if(millis()-MillisecIniziali==ritardo)
        {
          MillisecIniziali=millis();
        //delay(10);// I don't know why I need this, but without it I don't get my 8 lsb of temp
       ret = ret*2 + digitalRead(_dataPin);   
     digitalWrite(_clockPin, LOW);
       }
       
  }

  return(ret);
 }

/**
 */
 MillisecIniziali=0;
 void SHT1x::waitForResultSHT(int _dataPin)
{
  int i;
  int ack;

  pinMode(_dataPin, INPUT);

  for(i= 0; i < 100; ++i)
  {
    //delay(10); 
    if(millis()-MillisecIniziali==ritardo)
        {
          MillisecIniziali=millis();
          ack = digitalRead(_dataPin);
        }
    if (ack == LOW) {
    
      break;
    }
  }

  if (ack == HIGH) {
    //Serial.println("Ack Error 2"); // Can't do serial stuff here, need another way of reporting errors
  }
}

nno so se il primo “digitalWrite(_clockPin, LOW);” va messo dentro lo if o no … ma credo di si …
mi date una mano ?

Anche io avevo provato a fare in questo modo, così l'orologio va bene ma il sensore restituisce -40, che significa che ha dei problemi di comunicazione. Sto iniziando a pensare di prendere il sensore e schiacciarlo in una morsa da officina!!!

ma avevi posto MillisecIniziali=0; dopo il primo ciclo? comunque se mai a pagina 7 del datascheet .. c'è un esempio .... ci vuole un po' di tempo a tradurlo in codice .... se hai pazienza prima o poi ci provo ... la moesa ??? ma noooooooooooooooooooooooooooooooooooo :)

Ho appena riprovato con il codice che hai postato, niente da fare ma ti ringrazio comunque. Per quanto riguarda l'esempio del datasheet non sono in grado di tramutarlo in codice, mi sa che è meglio che mi metto sotto a studiare, più vado avanti più mi rendo conto che la strada va sempre più in salita ma non mollo! Ciao

Ragazzi, per ora ho trovato un rimedio momentaneo che sembra funzionare. Non ho modificato la libreria, ho fatto in modo di interrogare il sensore solamente una volta ogni 15 secondi basandomi sul tempo restituito dal RTC. Secondo me non è il modo migliore di risolvere il problema ma finchè non studio qualcosa di migliore, spero che questo sia sufficente. Ecco lo script:

if (rtc[0]==15 || rtc[0]==30 || rtc[0]==45 || rtc[0]==59) { temp_c = sht1x.readTemperatureC(); humidity = sht1x.readHumidity(); }

/**
 */
 int SHT1x::shiftIn(int _dataPin, int _clockPin, int _numBits)
{
int i;
long MillisecIniziali;
int ritardo=10;

  int ret = 0;

  for (i=0; i<_numBits; ++i)
  {
     digitalWrite(_clockPin, HIGH);
    
      if(millis()-MillisecIniziali==ritardo)
        {
          MillisecIniziali=millis();
        //delay(10);// I don't know why I need this, but without it I don't get my 8 lsb of temp
       ret = ret*2 + digitalRead(_dataPin);  
     digitalWrite(_clockPin, LOW);
       }
      
  }

  return(ret);
 }

/**
 */
 
long MillisecIniziali;
int ritardo=10;

 void SHT1x::waitForResultSHT(int _dataPin)
{
  int i;
  int ack;

  pinMode(_dataPin, INPUT);

  for(i= 0; i < 100; ++i)
  {
    //delay(10);
    if(millis()-MillisecIniziali==ritardo)
        {
          MillisecIniziali=millis();
          ack = digitalRead(_dataPin);
        }
    if (ack == LOW) {
    
      break;
    }
  }

  if (ack == HIGH) {
    //Serial.println("Ack Error 2"); // Can't do serial stuff here, need another way of reporting errors
  }
}

un paio di errori nel seconda parte credo
( /**
*/

long MillisecIniziali;
int ritardo=10;)
nel codice che ti avevo mandato … ma comunque… ci ritorneremo

Non va, segna sempre -40 , mi sa che lascio come ho provato :'( Non so se hai visto come ho limitato il danno del delay, in quel modo sembra funzionare solo che la temperatura rilevata dal sensore è leggermente inferiore rispetto a quella rilevata da due sensori Lm35 presenti sullo stesso shield. Adesso sto indagando perchè i valori letti dai sensori sono differenti, speriamo bene... Innanziutto mi procuro dei termometri ad alcool per avere un'idea su quale sensore sgarra, qualora la differenza fosse costante risolvo modificando il valore via script. Può essere un problema legato al modo che ho usato per collegare il sensore?

si .... dal valore di resistenza e del tipo di cavo .. la divergenza può dipendere dalla temperatura..... e/o dalla campionatura del segnale.... comunque.. è normare avere casini con ste cose .. nn disperare .....

Ho sostituito i delay con dei while vuoti, non sono sicuro che funzioni, è più che altro un esperimento… Se hai tempo di fare una prova facci sapere!

int SHT1x::shiftIn(int _dataPin, int _clockPin, int _numBits)
{
  int ret = 0;
  int i;
  long timerIN;

  for (i=0; i<_numBits; ++i)
  {
     digitalWrite(_clockPin, HIGH);
     timerIN = millis();
     while(timerIN-millis()<10){}
     //delay(10);  // I don't know why I need this, but without it I don't get my 8 lsb of temp
     ret = ret*2 + digitalRead(_dataPin);
     digitalWrite(_clockPin, LOW);
  }

  return(ret);
}

 void SHT1x::waitForResultSHT(int _dataPin)
{
  int i;
  int ack;
  long timerIN;
  pinMode(_dataPin, INPUT);

  for(i= 0; i < 100; ++i)
  {
    timerIN = millis();
    while(timerIN-millis()<10){}
    //delay(10);
    ack = digitalRead(_dataPin);

    if (ack == LOW) {
      break;
    }
  }

  if (ack == HIGH) {
    //Serial.println("Ack Error 2"); // Can't do serial stuff here, need another way of reporting errors
  }
}

Ho provato, ci stiamo avvicinando.... con il codice di GentlemanRider l'umidità funziona correttamente mentre la temperatura rilevata è sempre negativa, però stavolta invece di restituire -40 il valore varia. L'orario scorre perfetto.