Go Down

Topic: OneWire issues with DS18S20 (Read 568 times) previous topic - next topic

Nov 30, 2012, 04:34 pm Last Edit: Nov 30, 2012, 04:40 pm by robert_drescher Reason: 1
I am having serious issues with my code when trying to access the DS18S20 probes.
Once I think I got it and get proper readouts, I start changing the next thing and suddenly my sketch freezes after getting the first temperature.
So I think "well, I coded something wrong", but when I comment out the call to the method that is reading the OneWire bus, everything runs smoothly. So I would appreciate if someone would have a look at what is happening in this method:

First of all, the following method scans for probes on the bus and saves their address into a 2-dimensional array probes[][]

Code: [Select]

void scanAllProbes()
{  
 probespresent = 0;
 ds.reset_search();
 while(probespresent < 8 && ds.search(addr))
 {
   if ( addr[0] != 0x10 && addr[0] != 0x28 )
   {
     output("Unknown","probe");
   }
   else
   {
     String address = "";
     for(int i = 0; i < 8; i++)
     {    
       probes[probespresent][i] = addr[i];
       address += String(addr[i],HEX);
     }
     output("Found probe:", address);      
     probespresent++;
   }
   delay(1000);
 }   
 //probespresent now contains the number of probes connected  
}


Code: [Select]

void getTemperature()
{  
 if(lastRequestTimestamp == 0) //no request done yet
 {
   for(int i = 0; i < probespresent; i++)
   {
     ds.reset();
     ds.select(probes[i]);
     ds.write(0x44,1); // start conversion, with parasite power on at the end
     temp[i] = 0;
   }
   lastRequestTimestamp = millis();
   return;
 }
 
 //check if last temperature request was over 5 sec ago
 if( (millis() - lastRequestTimestamp) >= 5000 )
 {
   //now data should be present for each probe
   average = 0;  
   for(int i = 0; i < probespresent; i++)
   {      
     byte data[12];
     ds.reset();
     //select each connected probe
     ds.select(probes[i]);
     ds.write(0xBE);
     for(int j = 0; j < 9; j++)
     {
       data[j] = ds.read();
     }
     byte MSB = data[1];
     byte LSB = data[0];
 
     temp[i] = ((MSB << 8) | LSB) / 16; //using two's compliment      
     average += temp[i];
     
   }
   average = average / max(probespresent,1);    
   
   //now make another request    
   for(int i = 0; i < probespresent; i++)
   {
     ds.reset();
     ds.select(probes[i]);
     ds.write(0x44,1); // start conversion, with parasite power on at the end
   }
   //set the timestamp to current time
   lastRequestTimestamp = millis();
 }        
}


The getTemperature-Method is executed on each iteration of loop() and places a request. On consecutives runs, no further action is taken until 5 seconds have passed since the last request, then it tries to retrieve the values from the scratchpad, save them into an array and calculate the average temperature. After that, a new request is placed and the timestamp saved.

I cannot see any problem with that, but if I output the temperature after each run of getTemperature, I get
1st run Probe 1: 0, Probe 2: 0, average 0
2nd run Probe 1: 24, Probe 2: 0, average 12 and the program freezes.
So it is actually not getting/writing the temperature from the second probe but goes on outputting the value
Then somewhere in the 3rd run it is freezing...

Any ideas about what's going wrong here?

PaulS

Quote
Any ideas about what's going wrong here?

Without seeing all of your code, no.

This is not good, though:
      String address = "";
        address += String(addr,HEX);
There is NO reason to convert the address to a String to print it.

Quote
I cannot see any problem with that, but if I output the temperature after each run of getTemperature, I get
1st run Probe 1: 0, Probe 2: 0, average 0
2nd run Probe 1: 24, Probe 2: 0, average 12 and the program freezes.
So it is actually not getting/writing the temperature from the second probe but goes on outputting the value
Then somewhere in the 3rd run it is freezing...

I don't see any Serial.print()s in the getTemperature() function, so I have no idea how you arrived at this conclusion.

I'd be looking at writing outside the bounds of an array.

Thanks for the hints, at least i knew that there was nothing wrong per sé with the OneWire interaction.
I removed all the extra stuff and started implementing it again bit by bit and found something:
You can see the "output" function that I thought would be perfect to set the cursor and write the LCD lines in order to not write lcd.clear(), lcd.setCursor(), lcd.print() over and over again.
That lead to the mania of putting the whole LCD lines together by adding strings ...

and the string adding is responsible for the lockups.
Code: [Select]

  lcd.setCursor(0,0);
  lcd.print(fstr("P" + String(probeselected+1),LEFT,2));
  lcd.print(fstr(ffloat(temp[probeselected]),RIGHT,5));
  lcd.print(fstr(ffloat(average),RIGHT,5));
 
works, while
Code: [Select]

  lcd.setCursor(0,0);
  lcd.print(fstr("P" + String(probeselected+1),LEFT,2)
        + fstr(ffloat(temp[probeselected]),RIGHT,5)
        + fstr(ffloat(average),RIGHT,5));
 
does not :(

So I'll be more careful with my strings. Problem is that I have a pretty elaborate menu navigation

Regards,
Robert

PaulS

Code: [Select]
  lcd.print(fstr("P" + String(probeselected+1),LEFT,2));
You need to ditch the String class and learn how to use sprintf() if you feel the need (unnecessary) to limit the number of lcd.print()s done.

Go Up