Sida 1 av 1

Arduino och DS18S20

Postat: 16 januari 2016, 19:25:42
av RadioDJ
Till alla Er som är mycket bättre på Arduino och C än mig.

Jag håller på att bygga en väderstation med givare som jag själv har fräs och svarvat.
Jag kan i dagsläget mäta av vindriktning, vindhastighet, temperatur, regnmängd, luftfuktighet, ljusstyrka och lufttryck. Har planer även på att läsa av åska.
Har fått det mesta att fungera men har just nu problem med temperaturen.
Värdena stämmer tills jag går under 0 grader, då hoppar den 4096 grader. Blir inga minusgrader.
Någon som kan hjälpa mig med vad jag har gjort för fel.

En hel del kod är "stulen" och lite knappande själv.
Jag har försökt att plocka ut de bitar som har med temperaturen att göra i stället för att skicka med all kod till väderstationen, som börjar bli lite lång nu.

DS18S20 är kopplad med separat +, jord och data. Ingen parasit här inte.

Var har jag gjort fel??

Kod: Markera allt

// Variabel för att hålla temperaturen. Sätts bland alla globala variabler 
float tempC = 0;


// Anropas var 10 sekund ifrån "Loop"
  tempC = readTemperature();     // temperatur från DS18S20


// Denna skickas ut till en RS422 anslutning för vidare avläsning i datorn en gång per minut
  Serial.print(tempC, 2);


// Rutin för att läsa av tempen
// Stulen kod
float readTemperature()
{
byte present = 0;
byte data[12];
float celsius;
char buffer[10];
int i;

  oneWire.reset();
  oneWire.select(addr);
  oneWire.write(0x44); 
  
  delay(750);     // maybe 750ms is enough, maybe not
  
  present = oneWire.reset();
  oneWire.select(addr);    
  oneWire.write(0xBE);         // Read Scratchpad

  for ( i = 0; i < 9; i++) // we need 9 bytes
  {
    data[i] = oneWire.read();
  }

// convert the data to actual temperature
  unsigned int raw = (data[1] << 8) | data[0];

  if (type_s) 
  {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) 
    {
// count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  }
  else 
  {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
// default is 12 bit resolution, 750 ms conversion time
  }

  celsius = (float)raw / 16.0;

  return (celsius);
}  

Re: Arduino och DS18S20

Postat: 16 januari 2016, 19:36:45
av JanErik
Antagligen måst returvärdet beaktas som tvåkomplement; https://en.wikipedia.org/wiki/Two's_complement

Har använt DallasTemperature, https://milesburton.com/Dallas_Temperat ... ol_Library , som i sin tur använder OneWire-biblioteket.

Re: Arduino och DS18S20

Postat: 16 januari 2016, 19:54:20
av svanted
det är vad givaren ger ut....
-0.0625° ger FFEh = 4096

Re: Arduino och DS18S20

Postat: 16 januari 2016, 21:59:00
av hawkan
Så här är det gjort i DallasTemperature

Kod: Markera allt

// reads scratchpad and returns fixed-point temperature, scaling factor 2^-7
int16_t DallasTemperature::calculateTemperature(const uint8_t* deviceAddress, uint8_t* scratchPad){

    int16_t fpTemperature =
    (((int16_t) scratchPad[TEMP_MSB]) << 11) |
    (((int16_t) scratchPad[TEMP_LSB]) << 3);

    /*
    DS1820 and DS18S20 have a 9-bit temperature register.
    Resolutions greater than 9-bit can be calculated using the data from
    the temperature, and COUNT REMAIN and COUNT PER °C registers in the
    scratchpad.  The resolution of the calculation depends on the model.
    While the COUNT PER °C register is hard-wired to 16 (10h) in a
    DS18S20, it changes with temperature in DS1820.
    After reading the scratchpad, the TEMP_READ value is obtained by
    truncating the 0.5°C bit (bit 0) from the temperature data. The
    extended resolution temperature can then be calculated using the
    following equation:
                                    COUNT_PER_C - COUNT_REMAIN
    TEMPERATURE = TEMP_READ - 0.25 + --------------------------
                                            COUNT_PER_C
    Hagai Shatz simplified this to integer arithmetic for a 12 bits
    value for a DS18S20, and James Cameron added legacy DS1820 support.
    See - http://myarduinotoy.blogspot.co.uk/2013/02/12bit-result-from-ds18s20.html
    */

    if (deviceAddress[0] == DS18S20MODEL){
        fpTemperature = ((fpTemperature & 0xfff0) << 3) - 16 +
            (
                ((scratchPad[COUNT_PER_C] - scratchPad[COUNT_REMAIN]) << 7) /
                  scratchPad[COUNT_PER_C]
            );
    }

    return fpTemperature;
}

Re: Arduino och DS18S20

Postat: 17 januari 2016, 10:28:42
av RadioDJ
Tack för ledtrådarna.
Har nu lagt in mer kod och allt ser ut att fungera.
Tack...

Re: Arduino och DS18S20

Postat: 17 januari 2016, 18:42:13
av NULL
Gärna bilder på givaren. :tumupp:

Re: Arduino och DS18S20

Postat: 18 januari 2016, 10:22:25
av RadioDJ
Kan jag väl göra.
Nu blir det väl snart som så att jag får flytta till Projekt istället.
Här kommer 2 bilder som blev tagna igår kväll bara för att jag skulle visa dessa för en kollega.
Ni får ta dem så som det är.

Givarna är gjorda i mässing, koppar och rostfritt.

All elektronik sitter i det vita huset samt givare för temperatur, ljusstyrka, luftfuktighet och lufttryck.

Regnmätare finns för tillfället inte.

Ber om ursäkt om det blir konstigt med bilderna. Första gången jag provar detta.