Pages: [1]   Go Down
Author Topic: OneWire issues with DS18S20  (Read 500 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
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?
« Last Edit: November 30, 2012, 10:40:13 am by robert_drescher » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
  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:
  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 smiley-sad

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

Regards,
Robert
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  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.
Logged

Pages: [1]   Go Up
Jump to: