Go Down

Topic: multiple temp sensors ds18b20 (Read 4480 times) previous topic - next topic

Craig_Minca

Hi guys, im having trouble getting the led to turn on. It works fine when sensor 5 reaches and goes over 25C, but when sensor 1 - 4 go over the led only flashes every 4 seconds (refresh rate). Any help would be greatly appreciated. Thanks

/*  Multiple DS18B20 Temperature Sensors on 1 wire
  Connections:
  DS18B20 Pinout (Left to Right, pins down, flat side toward you)
  - Left   = Ground
  - Center = Signal (Pin 2):  (with 3.3K to 4.7K resistor to +5 or 3.3 )
  - Right  = +5 or +3.3 V

   


#include <OneWire.h>
#include <DallasTemperature.h>

/*-----( Declare Constants and Pin Numbers )-----*/
#define ONE_WIRE_BUS_PIN 2

/*-----( Declare objects )-----*/
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS_PIN);



/*-----( Declare Variables )-----*/
// Assign the addresses of your 1-Wire temp sensors.

DeviceAddress Probe01 = { 0x28, 0xFF, 0xF8, 0x20, 0x05, 0x16, 0x03, 0x31 }; 
DeviceAddress Probe02 = { 0x28, 0xFF, 0x1B, 0x22, 0x05, 0x16, 0x03, 0xA2 };
DeviceAddress Probe03 = { 0x28, 0xFF, 0xFC, 0xF5, 0x04, 0x16, 0x03, 0x05 };
DeviceAddress Probe04 = { 0x28, 0xFF, 0x58, 0x27, 0x05, 0x16, 0x03, 0x84 };
DeviceAddress Probe05 = { 0x28, 0xFF, 0xE0, 0x25, 0x05, 0x16, 0x03, 0xF2 };

int ledPin = 13; //led is pin 13

void setup()   /****** SETUP: RUNS ONCE ******/
{
  // start serial port to show results
  Serial.begin(9600);
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);

  pinMode(ledPin, OUTPUT);
 
  // Initialize the Temperature measurement library
  sensors.begin();
 
  // set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)
  sensors.setResolution(Probe01, 10);
  sensors.setResolution(Probe02, 10);
  sensors.setResolution(Probe03, 10);
  sensors.setResolution(Probe04, 10);
  sensors.setResolution(Probe05, 10);

}//--(end setup )---

void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  delay(4000);
  Serial.println();
  Serial.print("Number of Devices found on bus = "); 
  Serial.println(sensors.getDeviceCount());   
  Serial.print("Getting temperatures... "); 
  Serial.println();   
 
  // Command all devices on bus to read temperature 
  sensors.requestTemperatures(); 
 
  Serial.print("Probe 01 temperature is:   ");
  printTemperature(Probe01);
  Serial.println();

  Serial.print("Probe 02 temperature is:   ");
  printTemperature(Probe02);
  Serial.println();
 
  Serial.print("Probe 03 temperature is:   ");
  printTemperature(Probe03);
  Serial.println();
   
  Serial.print("Probe 04 temperature is:   ");
  printTemperature(Probe04);
  Serial.println();
 
  Serial.print("Probe 05 temperature is:   ");
  printTemperature(Probe05);
  Serial.println();

 
 
 
   
 
}//--(end main loop )---

/*-----( Declare User-written Functions )-----*/
void printTemperature(DeviceAddress deviceAddress)
{

float tempC = sensors.getTempC(deviceAddress);

   if (tempC == -127.00)
   
   {
   Serial.print("Error getting temperature  ");
   }
   else
   {
   Serial.print("C: ");
   Serial.print(tempC);
   Serial.print(" F: ");
   Serial.print(DallasTemperature::toFahrenheit(tempC));

     if (tempC > 25)
   
{
    digitalWrite(ledPin, HIGH);
}
      else
     

     digitalWrite(ledPin, LOW);
}
}
   
 
   
// End printTemperature

Koepel

The delay in the loop is 4 seconds, and every 4 seconds you check the temperarture sensors and temporarily turn on the led if the temperature is above 25 degrees Celsius and turn it off if not. Is that not what you want it to do ?

Should the led turn on when at least one of the temperatures is above 25 degrees and turn off when all the temperatures are below 25 degrees ?

For that you have to know all the temperatures or keep track how many are above 25 degrees. That can be done in a loop, and requires a re-write of your sketch.

Have you attached a label to the temperature sensors ? Can you tell the names (or the number) you gave them ?
In the 'c' language an array starts at index 0, it would be better of you start counting at zero.

Craig_Minca

Hi Koepel, I want the led to turn on and stay on once the temp of any of the sensors goes over 25, then turn off once below 25. The led will only do this on sensor 5. For sensor 1-4 the led flashes only.

Yes i have labelled each sensor and can tell which is which.

Thanks for your help

Koepel

#3
Apr 14, 2016, 08:10 am Last Edit: Apr 14, 2016, 08:23 am by Koepel
You are not thinking like a software engineer (yet). You have to describe when to turn the led off.
Do you mean that all sensors must be below 25 degrees to turn it off ?

Example: When does a software engineer walk his dog ? if the software engineer has a dog AND the dog has not been taking out this morning yet AND ( ( if the software engineer is awake AND it is between 8 and 10 o'clock AND the weather is NOT very bad ) OR when the dog has to go pee OR when the dog has to go poo OR the dog has to pee AND poo OR when the software engineer wants to walk outside )

Can you tell the labels ? I mean something like "boiler", "room", "kitchen", "outside" or "probe01" ?

Instead of counting how many sensors are above 25 degrees, all the temperatures could be tested in a big if-statement. In the next example I count them, because that can be done in the same loop that retrieves the temperatures.

Does the next code make sense to you ? The deviceAddress has to be changed into an array as well for it.
Code: [Select]

  float temp[5];

  int countAbove25 = 0;
  for( int i; i<5; i++)
  {
    temp[i] = sensors.getTempC(deviceAddress[i]);
    if( temp[i] > 25.0)
    {
      countAbove25++;
    }
  }

  if( countAbove25 > 0)             // at least one sensor above 25 degrees ?
  {
    digitalWrite(ledPin, HIGH);   // turn on the led.
  }
  else
  {
    digitalWrite(ledPin, LOW);      // every sensor is below 25 degrees, turn off the led.
  }

The example above will work with a single 'temp' for every temperature, but I would like to have all the temperatures at hand, so I put all the temperatures in an array. Then they can be printed to serial port, or to find the sensor that has the highest temperature or things like that.

Craig_Minca

Yes, thinking like a  motor mechanic....lol. Great analogy makes sense.

Yes all sensors below then led turns off

Im not sure what you mean buy tell the labels boiler etc. if you mean change their name fomr probe to what ever, then yes.

So im very much a newbie and are slowly getting my head around the code. My projects so far have been copy & paste, with some changes from me(basis stuff).

I think i understand the code. You are counting the sensors (as you said) telling the led to turn on if any sensor is above 25c. But dont know how to change the device address into an array.

Thanks for all your help

Koepel

#5
Apr 14, 2016, 12:07 pm Last Edit: Apr 14, 2016, 12:26 pm by Koepel
For a project I'm planning to do some day, I need ten DS18B20 sensors. Therefor I have enough DS18B20 sensors, and I need to make a sketch with an array some day anyway. I put 5 sensors on a breadboard with a 10k pullup resistor and started to make a sketch with an array, that matches the label to an address.

Have you attached a label to each sensor, and have you written something on that label ?

For the final sketch, I think I will put the label and the address into a 'struct'.

The next sketch might be over the top for you.

Code: [Select]

// A test with multiple DS18B20
// Connected with 5V, GND, and 10k pullup for the 1-Wire.
// 2016, Arduino Uno, Arduino IDE 1.6.8.
// OneWire and DallasTemperature libraries installed via Library Manager.
// Started with "Multiple" example of the DallasTemperature library.
//
// Changed the names of variable:
//    sensor_bus is the bus (was called 'sensors').
//    sensor_address[] is the array with the deviceaddresses of the sensors.
//
// Note that the index by the DallasTemperature is not our own index.
// I don't even print that index.
// The index used in the sketch is our own index, it matches the labels with the addresses.


// Use the ENABLE_SEARCH_ADDRESS to gather all the unique addresses of the sensors.
// Comment it out if you don't want to use it.
#define ENABLE_SEARCH_ADDRESS

// Use the ENABLE_READ_BACK_RESOLUTION to confirm that the right resolution has been set.
#define ENABLE_READ_BACK_RESOLUTION


#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 8 on the Arduino
#define ONE_WIRE_BUS 2
#define TEMPERATURE_PRECISION 10    // 12 is maximum but slower.

#define NUM_SENSORS 5               // the number of DS18B20 sensors on the 1-Wire bus.


// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire( ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensor_bus( &oneWire);

// Array to hold device addresses.
// The address is a group of 8 bytes, and there are 'NUM_SENSORS' of those groups of 8 bytes.
// The "DeviceAddress" type already defined as a group of 8 bytes.
const DeviceAddress sensor_address[NUM_SENSORS] =
{
  { 0x28, 0xFF, 0xF8, 0x20, 0x05, 0x16, 0x03, 0x31 },       // Kitchen
  { 0x28, 0xFF, 0x1B, 0x22, 0x05, 0x16, 0x03, 0xA2 },       // Living room
  { 0x28, 0xFF, 0xFC, 0xF5, 0x04, 0x16, 0x03, 0x05 },       // Hall
  { 0x28, 0xFF, 0x58, 0x27, 0x05, 0x16, 0x03, 0x84 },       // Doghouse
  { 0x28, 0xFF, 0xE0, 0x25, 0x05, 0x16, 0x03, 0xF2 },       // Basement
};

// Create labels in PROGMEM, see : https://www.arduino.cc/en/Reference/PROGMEM
// The order of the labels must match the order of the addresses in 'sensor_address[]'.
const char string0[] PROGMEM = "Kitchen";
const char string1[] PROGMEM = "Living room";
const char string2[] PROGMEM = "Hall";
const char string3[] PROGMEM = "Doghouse";
const char string4[] PROGMEM = "Basement";

const char * const string_table[] PROGMEM =
{
  string0, string1, string2, string3, string4,
};

const int ledPin = 13;          // system led

void setup()
{
  Serial.begin( 9600);
  while(!Serial);              // For Leonardo: wait for serial monitor
  Serial.println(F( "\nMultiple DS18B20"));
  Serial.println(F( "----------------"));

  pinMode( ledPin, OUTPUT);                 // defaults to LOW, led will be off

  // Start up the library
  sensor_bus.begin();

#ifdef ENABLE_SEARCH_ADDRESS
  // Get the number of devices on the 1-Wire bus.
 
  int n = sensor_bus.getDeviceCount();
  Serial.print(F( "Number of devices found: "));
  Serial.println( n);

  // Get the unique address
  // Use the actual number of found sensors, to make it possible to connect
  // the sensors one by one (and press reset every time) and see the unique address.
  // Once all the addresses are set in 'sensor_address[]', then the index of that is used,
  // and not the index of the DallasTemperature.
 
  Serial.println(F( "Copy the 8 bytes of the sensor address into the sketch."));

  DeviceAddress sens;               // temporary sensor address.
  for( int i=0; i<n; i++)           // this is the index for the DallasTemperature library
  {
    sensor_bus.getAddress( sens, i);
   
    Serial.print(F( "Device found, address: "));
    for( int j=0; j<8; j++)
    {
      Serial.print(F( "0x"));
      if( sens[j] < 16)
        Serial.print(F( "0"));
      Serial.print( sens[j], HEX);
      if( j!=7)
        Serial.print(F( ", "));
    }
    Serial.println();
  }
#endif

  // The next part is only valid if the sensor address had been written in the sketch.
 
#ifdef ENABLE_READ_BACK_RESOLUTION
  Serial.println(F( "Resolution:"));
#endif

  for( int i=0; i<NUM_SENSORS; i++)
  {
    sensor_bus.setResolution( sensor_address[i], TEMPERATURE_PRECISION);

#ifdef ENABLE_READ_BACK_RESOLUTION
    char buffer[40];
    strcpy_P( buffer, (char *) pgm_read_word( &(string_table[i])));
    Serial.print(F( "  "));
    Serial.print( buffer);

    Serial.print(F( " resolution: "));
    Serial.print( sensor_bus.getResolution( sensor_address[i]), DEC);
    Serial.println();
#endif
  }
}

void loop()
{
  // -----------------------------------------------------------------------
  // Global request to get the temperatures
  // -----------------------------------------------------------------------

  sensor_bus.requestTemperatures();

  // -----------------------------------------------------------------------
  // Gather all the temperatures
  // -----------------------------------------------------------------------
  // The temperatures are requested by using the unique address of the sensor.
  // The connected sensors with its address in this sketch will return a valid temperature,
  // regardless of other sensors that might be missing or extra sensors that might have been added.
 
  float temperature[NUM_SENSORS];
  for( int i=0; i<NUM_SENSORS; i++)
  {
    // Get temperature with its own unique address.
    // This matches the labels to the specific sensor.
    temperature[i] = sensor_bus.getTempC( sensor_address[i]);
  }

  // Now that all the temperatures are collected,
  // they can be used to write to a file, or do some math with them.

  // -----------------------------------------------------------------------
  // Print all the temperatures
  // -----------------------------------------------------------------------

  for( int i=0; i<NUM_SENSORS; i++)
  {
    char buffer[40];
    strcpy_P( buffer, (char *) pgm_read_word( &(string_table[i])));
    Serial.print( buffer);
    Serial.print(F( ": "));
    if( temperature[i] == -127.0)
    {
      Serial.print(F( "Error, not found  "));
    }
    else
    {
      Serial.print( temperature[i]);
      Serial.print(F( "  "));
    }
  }
  Serial.println();

  // -----------------------------------------------------------------------
  // For Arduino forum: http://forum.arduino.cc/index.php?topic=393653.0
  // -----------------------------------------------------------------------
  int countAbove25 = 0;
  for( int i; i<NUM_SENSORS; i++)
  {
    if( temperature[i] > 25.0)
    {
      countAbove25++;
    }
  }

  Serial.print(F( "There are "));
  Serial.print( countAbove25);
  Serial.println(F( " sensors above 25.0"));
  if( countAbove25 > 0)           // at least one sensor above 25 degrees ?
  {
    digitalWrite(ledPin, HIGH);   // turn on the led.
  }
  else
  {
    digitalWrite(ledPin, LOW);    // every sensor is below 25 degrees, turn off the led.
  }


  // -----------------------------------------------------------------------
  // For fun
  // -----------------------------------------------------------------------
  float lowest = 1000.0;
  float highest = -1000.0;
  for( int i=0; i<NUM_SENSORS; i++)
  {
    if( temperature[i] < lowest)
      lowest = temperature[i];
    if( temperature[i] > highest)
      highest = temperature[i];
  }
  Serial.print(F( "Highest temperature: "));
  Serial.println( highest);
  Serial.print(F( "Lowest  temperature: "));
  Serial.println( lowest);


  float average = 0.0;
  for( int i=0; i<NUM_SENSORS; i++)
  {
    average += temperature[i];
  } 
  average /= NUM_SENSORS;
  Serial.print(F( "Average temperature: "));
  Serial.println( average);
 

  delay(1000);
}


Can you try to mix your sketch and my sketch ? Show your new sketch between code tags. Number 7 is about code tags : http://forum.arduino.cc/index.php/topic,148850.0.html

Craig_Minca

Code: [Select]
I tried to mix the codes but no luck, just frustration,its very much beyond me. So I've used yours(thank you) but this error messages comes up

 "invalid conversion from 'const unit8_t"

[code    temperature[i] = sensor_bus.getTempC( sensor_address[i]);
  }
]


I have my sensors in order on a breadboard and the text is in notepad.
I plan on running the sensors with wires and numbering each one. They will be monitoring my batteries and when needed will turn on cooling fans. But i thought I would start with a simple led......not as simple as i thought.

Thanks for all your help!!

Koepel

I'm using Arduino IDE 1.6.8. Are you using an older version ?
For which Arduino board are you compiling ?
How did you install the libraries ? I used the Library Manager of the Arduino IDE.


I have added the word 'const' just for some extra safety in this line:
Code: [Select]

const DeviceAddress sensor_address[NUM_SENSORS] =

You can remove 'const' there.

Craig_Minca

You sir are awesome....Thank you. It works a treat.  :)  :)  I will now add a cooling fans to the code. Once again thanks for all of your patience and help.

Thanks

Go Up