1st read of DS18S20 temp sensor is wrong

My project includes a transmitter with 4 buttons. When any one of these buttons is pressed, my code reads a temp sensor and then starts a generator. I've posted just the temp reading portion of my code below. The rest of the works fine once the temp is read correctly.

When I plug in my usb cable the first time and hit a Tx button, the temp is always read as 185. When I press the button immediately after, the temp reads correctly. This website is the source for the temp reader code I'm using. I don't fully understand it, but I'm trying to. How do I get rid of the errant first temp reading?

/*
reads the temp sensor when a button on the Tx is pressed
*/

// OneWire used to read DS18S20 temp sensor
#include <OneWire.h>

// inputs from Rx
int VtFromRx = 12;
int buttonAFromRx = 11;
int buttonBFromRx = 10;
int buttonCFromRx = 9;
int buttonDFromRx = 8;

// other devices
int tempSensor = 13;

//Temperature chip i/o
OneWire ds(tempSensor);
float tempGen = 60;

void setup() {
  Serial.begin(9600);
  
  pinMode(VtFromRx, INPUT);
  pinMode(buttonAFromRx, INPUT);
  pinMode(buttonBFromRx, INPUT);
  pinMode(buttonCFromRx, INPUT);
  pinMode(buttonDFromRx, INPUT);
  
  pinMode(tempSensor, INPUT);
  
  Serial.println("setup complete");
}

void loop() {
  
  // read the inputs from the key fob
  int readVtFromRx = digitalRead(VtFromRx);
  int readButtonAFromRx = digitalRead(buttonAFromRx);
  int readButtonBFromRx = digitalRead(buttonBFromRx);
  int readButtonCFromRx = digitalRead(buttonCFromRx);
  int readButtonDFromRx = digitalRead(buttonDFromRx);
      
  if (readVtFromRx == HIGH){     //this line checks to see if any button was pushed
    Serial.println("");
    Serial.print("---- Some button was pushed ---- ");
    tempGen = getTemp();
    Serial.println(tempGen);
    
    if (readButtonAFromRx == HIGH){
      tempGen = getTemp();
      Serial.println("-- A was pushed --");
      Serial.print("The temp is ");
      Serial.println(tempGen);
    }
    
    if (readButtonBFromRx == HIGH){
      Serial.println("-- B was pushed --");
    }
    
    if (readButtonCFromRx == HIGH){
      Serial.println("-- C was pushed --");
    }
    
    if (readButtonDFromRx == HIGH){
      Serial.println("-- D was pushed --");
    }
      
  }
  delay(200);
}

float getTemp(){
//returns the temperature from one DS18S20 in DEG Fahrenheit

byte data[12];
byte addr[8];

if ( !ds.search(addr)) {
//no more sensors on chain, reset search
ds.reset_search();
return -1000;
}

if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return -1000;
}

if ( addr[0] != 0x10 && addr[0] != 0x28) {
Serial.print("Device is not recognized");
return -1000;
}

ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end

byte present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad

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

ds.reset_search();

byte MSB = data[1];
byte LSB = data[0];

float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSumC = tempRead / 16;
float TemperatureSumF = TemperatureSumC * 9/5 + 32;

return TemperatureSumF;
}

Here's what the serial output looks like for a sequence of 5 button pushes:

Normally you should check the CRC == data[8] after reading

Check out the Dallas Temperature Control Library (google is your friend)

ds.write(0x44,1); // start conversion, with parasite power on at the end

The important word in the comment is start. You aren't giving the device time to finish the conversion so the first time through you get rubbish.
If you have the resolution set to 12 bits (I think that's the default), it takes 750 milliseconds to do the conversion. I give it 800 just to be sure:

ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(800);

Pete

robtillaart:
Normally you should check the CRC == data[8] after reading

Check out the Dallas Temperature Control Library (google is your friend)

Thanks for the tip. I'm so new, I don't even know what to Google. This helps.

el_supremo:

ds.write(0x44,1); // start conversion, with parasite power on at the end

The important word in the comment is start. You aren't giving the device time to finish the conversion so the first time through you get rubbish.
If you have the resolution set to 12 bits (I think that's the default), it takes 750 milliseconds to do the conversion. I give it 800 just to be sure:

ds.write(0x44,1); // start conversion, with parasite power on at the end

delay(800);




Pete

That makes sense, but I never would have thought of that. Thanks. I'll try it when I get home.

ticklechicken:

el_supremo:

ds.write(0x44,1); // start conversion, with parasite power on at the end

The important word in the comment is start. You aren't giving the device time to finish the conversion so the first time through you get rubbish.
If you have the resolution set to 12 bits (I think that's the default), it takes 750 milliseconds to do the conversion. I give it 800 just to be sure:

ds.write(0x44,1); // start conversion, with parasite power on at the end

delay(800);




Pete

That makes sense, but I never would have thought of that. Thanks. I'll try it when I get home.

I just got my code updated, and it works great. Thanks again.