Pages: [1] 2   Go Down
Author Topic: Programmazione avanzata arudino  (Read 1907 times)
0 Members and 1 Guest are viewing this topic.
Bologna
Offline Offline
God Member
*****
Karma: 6
Posts: 542
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Buona sera a tutti!
Inizio questo topic per capire qualcosa in più su come interfacciare i sensori con Arduino senza usare librerie già pronte.
Per esempio, per usare il sensore DHT11 (o il DHT22) cosa bisogna "fare"? oppure per il DS18B20, come fare per "sentire cosa dice"?
Finchè si tratta di valori analogici con una semplice conversione si trova il dato cercato, ma come districarsi tra datasheet e protocolli?
Probabilente continuerò ad usare librerie già esistenti, ma vorrei provare a capire qualcosa in più del semplice scomapatta libreria.
Scusate per la confusione spero capiate cosa intendo, ma, in caso contrario, provvederò a rendermi più esplicito. smiley-lol
Grazie mille!
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

La risposta è semplice: devi scriverti tu il codice  smiley-wink

A parte gli scherzi, una libreria è un modo semplificato per fare qualcosa usando del codice scritto da altri.
Ad esempio, l'interfacciarsi con i tuoi sensori DHTxx.

Come si deve fare? Devi partire dal datasheet del componente e studiarti innanzi tutto come lavora, poi come si collega ed infine come dialogarci. A questo punto devi metterti lì e replicare via software il modo di comunicarci che hai studiato sul datasheet. Potrebbe essere facile come no. Ad esempio, se hai un componente che comunica via One-Wire, ti prendi la libreria One-Wire e poi spedisci i comandi che il sensore accetta e poi leggi sempre con quella libreria cosa esso "dice".
La One-Wire ti semplifica la vita perché è una libreria che implementa un protocollo di comunicazione. Se poi ti trovi anche la libreria che gestisce quel componente (es. DS18B20) sei a cavallo: includi 2 lib e sei a posto.
Ma se vuoi scriverti tutto da solo, devi:
1) scriverti il software per implementare la comunicazione One-Wire
2) scriverti il codice per comunicare con il DS18B20.

Capisci bene che con il tempo che sprechi a fare queste cose avevi già scritto il tuo programma usando le librerie fatte da altri  smiley-wink
Logged


Bologna
Offline Offline
God Member
*****
Karma: 6
Posts: 542
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie mille Leo!
Sì, io facevo un discorso giusto per capire, poi magari nell'applicazione pratica userò librerie pronte.
Possiamo far l'esempio del DHT11? http://www.micro4you.com/files/sensor/DHT11.pdf è il data, da cosa capisco come lavora?
Se permetete, provo a rispondermi da solo smiley-yell: fine pagina 5, inizio 6. Dice che trasmette 40 bit, ma io come faccio a capire quando e quale è il bit? come faccio a farlo capire ad arduino? smiley-sad
« Last Edit: August 27, 2013, 04:13:22 pm by SUBSEA » Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

E' tramite il protocollo One-Wire. Devi prenderti le specifiche del protocollo, studiartele e replicare il protocollo via software. A questo punto, avendo il protocollo di comunicazione, gestire quei 40 bit diventa compito del protocollo.
Ecco come avere quei 40 bit:
Quote
When MCU sends a start signal, DHT11 changes from the low-power-consumption mode to the running-mode, waiting for MCU completing the start signal. Once it is completed, DHT11 sends a response signal of 40-bit data that include the relative humidity and temperature information to MCU. Users can choose to collect (read) some data. Without the start signal from MCU, DHT11 will not give the response signal to MCU. Once data is collected, DHT11 will change to the low-power-consumption mode until it receives a start signal from MCU again.
Quindi prima ti scrivi la One-Wire, poi con questa interroghi il chip. E poi il tuo codice troverà i dati in base a quei 40 bit.

Ecco perché ti dico che è sempre meglio, quando si può, evitare di reinventare la ruota  smiley-wink
Logged


Bologna
Offline Offline
God Member
*****
Karma: 6
Posts: 542
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, quindi si usa il one-wire, e quindi quasi sicuramente libreria, ma cosa darebbe fuori, già i dati leggibili?
P.s. Per le specifiche del protocollo, wikipedia?
« Last Edit: August 27, 2013, 04:32:31 pm by SUBSEA » Logged

Cagliari, Italy
Online Online
Tesla Member
***
Karma: 112
Posts: 7123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

--> http://en.wikipedia.org/wiki/1-Wire
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, quindi si usa il one-wire, e quindi quasi sicuramente libreria, ma cosa darebbe fuori, già i dati leggibili?
Sì, assemblati in quei 40 bit in un certo ordine, compreso un CRC di controllo, da cui poi tu devi estrarli e ricomporre l'informazione.
Logged


Bologna
Offline Offline
God Member
*****
Karma: 6
Posts: 542
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quindi dice già temperatura e umidità? E la conversione da bit a leggibile la fa il one wire? Ultima cosa su wiki ce scritto già come interpretare i dati? E questi dati come arrivano? 001101 ecc? Se si, come Vanno riconosciuti da Arduino? Grazie ancora per la pazienza! smiley-sweat smiley-mr-green
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quindi dice già temperatura e umidità?
Così dice il datasheet. Pag. 5

Quote
E la conversione da bit a leggibile la fa il one wire?
No. One-Wire è il canale di trasmissione. La conversione la fa l'algoritmo che spedisce le richieste al sensore e che riceve i dati da questo. Che sia una lib già fatta o un tuo codice, il succo non cambia.

Quote
Ultima cosa su wiki ce scritto già come interpretare i dati? E questi dati come arrivano? 001101 ecc? Se si, come Vanno riconosciuti da Arduino? Grazie ancora per la pazienza! smiley-sweat smiley-mr-green
Continui a fare confusione fra canale di  trasmissione e dati trasmessi su quel canale  smiley-wink
I dati ogni sensore li spedisce secondo un proprio protocollo di trasmissione, nel caso del DHT11 è scritto nel PDF che hai linkato (pag 5):
Quote
Data format: 8bit integral RH data + 8bit decimal RH data + 8bit integral T data + 8bit decimal Tdata + 8bit check sum. If the data transmission is right, the check-sum should be the last 8 bit of "8 bit integral RH data+
8 bit decimal RH data + 8 bit integral T data + 8 bit decimal T data"
Logged


Bologna
Offline Offline
God Member
*****
Karma: 6
Posts: 542
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie ancora, approfitterò ancora un po' della tua esperienza.
Quote
La conversione la fa l'algoritmo che spedisce le richieste al sensore e che riceve i dati da questo. Che sia una lib già fatta o un tuo codice, il succo non cambia.
questo algoritmo quindi prende questi
Quote
Data format: 8bit integral RH data + 8bit decimal RH data + 8bit integral T data + 8bit decimal Tdata + 8bit check sum. If the data transmission is right, the check-sum should be the last 8 bit of "8 bit integral RH data+
8 bit decimal RH data + 8 bit integral T data + 8 bit decimal T data
e li rende leggibili. Ma Arduino come fa a sapere quale è un bit? glielo dice il one wire? e poi, questi bit sono 0 e 1, giusto? come faccio a dire: bene, dopo 8 0 o 1 che ti arrivano fermali e converti da binario a decimale (se così bisogna fare)?
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Un consiglio, per capire certe cose spesso è meglio vederle che sentirle  smiley-wink
Quindi prendi la lib One-Wire ed una lib che accede ai DHTxx e studiati i sorgenti.
Logged


Bologna
Offline Offline
God Member
*****
Karma: 6
Posts: 542
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, provo a fare così, poi se non capisco chiedo! quindi, preparatevi!!! smiley-lol
Logged

Cagliari, Italy
Online Online
Tesla Member
***
Karma: 112
Posts: 7123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

preparatevi!!! smiley-lol

Dobbiamo studiare la one-wire anche noi?  smiley-sweat
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Bologna
Offline Offline
God Member
*****
Karma: 6
Posts: 542
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

rieccomi! Allora, intanto quale file devo aprire? smiley-sweat
Proviamo col .h
Code:
private:
  uint8_t data[6];
  uint8_t _pin, _type, _count;
  boolean read(void);
  unsigned long _lastreadtime;
  boolean firstreading;

 public:
  DHT(uint8_t pin, uint8_t type, uint8_t count=6);
  void begin(void);
  float readTemperature(bool S=false);
  float convertCtoF(float);
  float readHumidity(void);

};
E' qui che legge i bit? mmmm, credo di no. Proviamo con questo:
Code:
DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) {
  _pin = pin;
  _type = type;
  _count = count;
  firstreading = true;
}

void DHT::begin(void) {
  // set up the pins!
  pinMode(_pin, INPUT);
  digitalWrite(_pin, HIGH);
  _lastreadtime = 0;
}

//boolean S == Scale.  True == Farenheit; False == Celcius
float DHT::readTemperature(bool S) {
  float f;

  if (read()) {
    switch (_type) {
    case DHT11:
      f = data[2];
      if(S)
       f = convertCtoF(f);
      
      return f;
    case DHT22:
    case DHT21:
      f = data[2] & 0x7F;
      f *= 256;
      f += data[3];
      f /= 10;
      if (data[2] & 0x80)
f *= -1;
      if(S)
f = convertCtoF(f);

      return f;
    }
  }
  Serial.print("Read fail");
  return NAN;
}

float DHT::convertCtoF(float c) {
return c * 9 / 5 + 32;
}

float DHT::readHumidity(void) {
  float f;
  if (read()) {
    switch (_type) {
    case DHT11:
      f = data[0];
      return f;
    case DHT22:
    case DHT21:
      f = data[0];
      f *= 256;
      f += data[1];
      f /= 10;
      return f;
    }
  }
  Serial.print("Read fail");
  return NAN;
}


boolean DHT::read(void) {
  uint8_t laststate = HIGH;
  uint8_t counter = 0;
  uint8_t j = 0, i;
  unsigned long currenttime;

  // pull the pin high and wait 250 milliseconds
  digitalWrite(_pin, HIGH);
  delay(250);

  currenttime = millis();
  if (currenttime < _lastreadtime) {
    // ie there was a rollover
    _lastreadtime = 0;
  }
  if (!firstreading && ((currenttime - _lastreadtime) < 2000)) {
    return true; // return last correct measurement
    //delay(2000 - (currenttime - _lastreadtime));
  }
  firstreading = false;
  /*
    Serial.print("Currtime: "); Serial.print(currenttime);
    Serial.print(" Lasttime: "); Serial.print(_lastreadtime);
  */
  _lastreadtime = millis();

  data[0] = data[1] = data[2] = data[3] = data[4] = 0;
  
  // now pull it low for ~20 milliseconds
  pinMode(_pin, OUTPUT);
  digitalWrite(_pin, LOW);
  delay(20);
  cli();
  digitalWrite(_pin, HIGH);
  delayMicroseconds(40);
  pinMode(_pin, INPUT);

  // read in timings
  for ( i=0; i< MAXTIMINGS; i++) {
    counter = 0;
    while (digitalRead(_pin) == laststate) {
      counter++;
      delayMicroseconds(1);
      if (counter == 255) {
        break;
      }
    }
    laststate = digitalRead(_pin);

    if (counter == 255) break;

    // ignore first 3 transitions
    if ((i >= 4) && (i%2 == 0)) {
      // shove each bit into the storage bytes
      data[j/8] <<= 1;
      if (counter > _count)
        data[j/8] |= 1;
      j++;
    }

  }

  sei();
  
  /*
  Serial.println(j, DEC);
  Serial.print(data[0], HEX); Serial.print(", ");
  Serial.print(data[1], HEX); Serial.print(", ");
  Serial.print(data[2], HEX); Serial.print(", ");
  Serial.print(data[3], HEX); Serial.print(", ");
  Serial.print(data[4], HEX); Serial.print(" =? ");
  Serial.println(data[0] + data[1] + data[2] + data[3], HEX);
  */

  // check we read 40 bits and that the checksum matches
  if ((j >= 40) &&
      (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) {
    return true;
  }
  

  return false;

}


AIUTOOO!! e' pieno di unit8!!!! smiley
« Last Edit: September 05, 2013, 08:05:31 am by leo72 » Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 332
Posts: 22803
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Per favore non urlare....  smiley-roll
Inoltre sono uint8, non unit8... Se conosci il C, sai che uint8 è l'unsigned char, che in Arduino corrisponde al tipo "byte".
Logged


Pages: [1] 2   Go Up
Jump to: