Go Down

Topic: Problem with the code for DS18S20 sensor. (Read 814 times) previous topic - next topic

Will_jr

Hello

I´ve got a problem with a DS18S20 sensor. I´ve used a code from an already existing project but it were built for an DS18B20 sensor.
When I run the code it works but I cant get the right value from the sensor. I run the sensor in a room (21 C degrees) but the sensor says 26 C degrees. Please someone help me. I think I must have missed something in the code that only works for a DS18B20. Hope you understand my bad english :)

#define TEMP_PIN 5 //

void OneWireReset(int Pin);
void OneWireOutByte(int Pin, byte d);
byte OneWireInByte(int Pin);

void setup() {
   digitalWrite(TEMP_PIN, LOW);
   pinMode(TEMP_PIN, INPUT);      // sets the digital pin as input (logic 1)
Serial.begin(9600);
   delay(100);
   Serial.print("Temperatur:\n");
}

void loop(){
 int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;

 OneWireReset(TEMP_PIN);
 OneWireOutByte(TEMP_PIN, 0xcc);
 OneWireOutByte(TEMP_PIN, 0x44); // perform temperature conversion, strong pullup for one sec

 OneWireReset(TEMP_PIN);
 OneWireOutByte(TEMP_PIN, 0xcc);
 OneWireOutByte(TEMP_PIN, 0xbe);

 LowByte = OneWireInByte(TEMP_PIN);
 HighByte = OneWireInByte(TEMP_PIN);
 TReading = (HighByte << 8) + LowByte;
 SignBit = TReading & 0x8000;  // test most sig bit
 if (SignBit) // negative
 {
   TReading = (TReading ^ 0xffff) + 1; // 2's comp
 }
 Tc_100 = ((TReading*100/2));    // multiply by 0.5

 Whole = Tc_100 / 100;  // separate off the whole and fractional portions
 Fract = Tc_100 % 100;


 if (SignBit) // If its negative
 {
    Serial.print("-");
 }
 Serial.print(Whole);
 Serial.print(".");
 if (Fract < 10)
 {
    Serial.print("0");
 }

 Serial.print(Fract);

     Serial.print("\n");
 delay(5000);      
}

void OneWireReset(int Pin) // reset.  Should improve to act as a presence pulse
{
    digitalWrite(Pin, LOW);
    pinMode(Pin, OUTPUT); // bring low for 500 us
    delayMicroseconds(500);
    pinMode(Pin, INPUT);
    delayMicroseconds(500);
}

void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first).
{
  byte n;

  for(n=8; n!=0; n--)
  {
     if ((d & 0x01) == 1)  // test least sig bit
     {
        digitalWrite(Pin, LOW);
        pinMode(Pin, OUTPUT);
        delayMicroseconds(5);
        pinMode(Pin, INPUT);
        delayMicroseconds(60);
     }
     else
     {
        digitalWrite(Pin, LOW);
        pinMode(Pin, OUTPUT);
        delayMicroseconds(60);
        pinMode(Pin, INPUT);
     }

     d=d>>1; // now the next bit is in the least sig bit position.
  }

}

byte OneWireInByte(int Pin) // read byte, least sig byte first
{
   byte d, n, b;

   for (n=0; n<8; n++)
   {
       digitalWrite(Pin, LOW);
       pinMode(Pin, OUTPUT);
       delayMicroseconds(5);
       pinMode(Pin, INPUT);
       delayMicroseconds(5);
       b = digitalRead(Pin);
       delayMicroseconds(50);
       d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
   }
   return(d);
}

//Will_jr

robtillaart


Temperature can fluctuate locally although 5 degrees is quite much. Does the IC feel hot? Or is it near a hot powersupply, laptopFan , ...?


There may be a problem with the precision (number of bits) as the 18S20 supports only 9 bits and the 18B20 supports 9..12 bit. Check the datasheet to see if the formulas and bit positions are identical. As far as I recall they are, and the code looks OK.


The Dallas Temperature Library support both IC's. Install it and you would have an alternative reference. - http://milesburton.com/index.php/Dallas_Temperature_Control_Library


Finally you can make displaying the Temp easier with a float var

float Temperature = TReading * 0.5;
Serial.println(Temperature, 1); // print with 1 bit precision

give it a try
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up