DS18B20 parasite power mode, output to common anode RGB LED.

I have been trying to get the temperature from a single DS18B20 (parasite power mode, power goes to data line) and use that to tell a RGB LED to light up red (for warmer temps than expected), green (for expected temp range), and blue (for colder temps than expected).

I thought I could do it by just modifying the DS_18x20 sample code. I removed all the Serial output and added a couple things

#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire  ds(2);  // on pin 2

void setup(void) {
  pinMode(13, OUTPUT); //anode
  pinMode(12, OUTPUT); //red
  pinMode(11, OUTPUT); //green
  pinMode(10, OUTPUT); //blue
  //Serial.begin(9600);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    //Serial.println("No more addresses.");
    //Serial.println();
    ds.reset_search();
    delay(250);  
    return;
  }
  
  
  //Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    //Serial.write(' ');
    //Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      //Serial.println("CRC is not valid!");
      return;
  }
  //Serial.println();
 
  // the first ROM byte indicates which chip
  
  switch (addr[0]) {
    case 0x10:
    //  Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
    //  Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
    //  Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
    //  Serial.println("Device is not a DS18x20 family device.");
      return;
  } 
  


  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  //Serial.print("  Data = ");
  //Serial.print(present,HEX);
  //Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    //Serial.print(data[i], HEX);
    //Serial.print(" ");
  }
  //Serial.print(" CRC=");
  //Serial.print(OneWire::crc8(data, 8), HEX);
  //Serial.println();

  // 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;
  fahrenheit = celsius * 1.8 + 32.0;
  //Serial.print("  Temperature = ");
  //Serial.print(celsius);
  //Serial.print(" Celsius, ");
  //Serial.print(fahrenheit);
  //Serial.println(" Fahrenheit");
  
  digitalWrite(13, HIGH);
  
  if(fahrenheit >= 68 && fahrenheit <= 83)
  {
    digitalWrite(12, HIGH);
    digitalWrite(10, HIGH);
  }
  else if(fahrenheit < 68)
  {
    digitalWrite(12, HIGH);
    digitalWrite(11, HIGH);
  }
  else if(fahrenheit > 83)
  {
    digitalWrite(11, HIGH);
    digitalWrite(10, HIGH);
  }  
}

I’ve noticed it keeps going through the initial if statement:

  if ( !ds.search(addr)) {
    //Serial.println("No more addresses.");
    //Serial.println();
    ds.reset_search();
    delay(250);  
    return;
  }

I’m using the onewire library:
http://www.pjrc.com/teensy/td_libs_OneWire.html

I tried some code of my own creation, then I tried this, and now I’m just lost. Can anyone point me in the right direction? Any advice?

Why are you connecting the LED anodes to a pin - why not to the 5V line? Do the LED pins have current-limiting resistors - they must…

As for the code - start with working code, test after each change, then you’ll know where you made the mistake. For parasite power mode you do know to wire the sensor’s Vdd terminal to ground? And you have a pull-up resistor on the data line?

You should use the serial monitor with some debugging Serial.print statements to make sure that, first of all, your code is finding the DS18b20 properly and also that the converted temperature is a reasonable value. But first ...

I've noticed it keeps going through the initial if statement:

... that statement and everything that follows, up to but NOT including the ds.reset(), should not be in the loop function. They should be in setup().

Pete

I have tested the LEDs and I think I have them sorted out, they are common anode RGB LEDs.

@MarkT: I have the 'unused' DS18B20 pins grounded. I am also using a 4.7k ohm, 1/2 watt, 5% tolerance, resistor (is it possible for it to be backwards?). I assumed the provided examples worked.

@el_supremo: I don't have a display, no where for that text to go. So the variables should be declared in setup, along with the if statement?

Kent, Have you received any messages to solve your questions?

Where are you at with this?

Forum... are their other things to check or any opinion on how to move this forward?

thank you, clinton

I have recently used quite a few DS18B20's in various projects. I'm using the DallasTemperature library on top of the OneWire library. This makes reading the DS18B20 sensors a lot easier.

http://www.milesburton.com/Main_Page?title=Dallas_Temperature_Control_Library