Arduino Mega Datalogging with DS18B20 Sensors

First Hello all, First time poster - long time lurker tho.

I have searched the forum and rest of the internet, but only thread I came across for this is the following (Uno data logging DS18B20 daisy chained sensors - #17 by tynawg9 - Sensors - Arduino Forum). The pins are set up correctly for a Mega even though the posted thread is for a Uno, and I have read the entire thread, and have searched the internet but I am having a problem writing the temperature data that the DS18B20 Sensors are producing to my microsd Card in a .csv file. Everything displays correctly except the data is outputing to zero (0) in the .csv file but the serial monitor actually shows the correct temperature in *C.

Here is my code:

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

#define ONE_WIRE_BUS_PIN 2
OneWire oneWire(ONE_WIRE_BUS_PIN);
DallasTemperature sensors(&oneWire);

const int chipSelect = 4;

float tempC, Probe01, Probe02, Probe03;

DeviceAddress Probe01 = { 0x28, 0x89, 0x1A, 0x08, 0x80, 0x00, 0x80, 0xBF };
DeviceAddress Probe02 = { 0x28, 0x4A, 0x05, 0x08, 0x80, 0x00, 0x80, 0x54 };
DeviceAddress Probe03 = { 0x28, 0xC6, 0x29, 0x08, 0x80, 0x00, 0x80, 0xD8 };


void setup()   /****** SETUP: RUNS ONCE ******/
{
  // start serial port to show results
  Serial.begin(9600);
    delay(300);//Wait for newly restarted system to stabilize
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
 
    Serial.print("Initializing");
  delay(2000);

  pinMode(10, OUTPUT);

if (!SD.begin(chipSelect))
  {
  Serial.print("failed!");
    delay (2000);
    return;
  }
  Serial.println("  init. OK!");

 
  // 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);

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

void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  delay(3000);
  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();
  probe1 = tempC;

  Serial.print("Probe 02 temperature is:   ");
  printTemperature(Probe02);
  Serial.println();
  probe2 = tempC;

  Serial.print("Probe 03 temperature is:   ");
  printTemperature(Probe03);
  Serial.println();
  probe3 = tempC;
   
 
    File datafile = SD.open("tdata.csv", FILE_WRITE);
        if(datafile)
        {
          datafile.print("P-1");
          datafile.print(",");
          datafile.print(probe1);
          datafile.print(",");
          datafile.print("P-2");
          datafile.print(",");
          datafile.print(probe2);
          datafile.print(",");
          datafile.print("P-3");
          datafile.print(",");
          datafile.print(probe3);
          datafile.print(",");
          datafile.println();
          datafile.close();
        }
        else
          Serial.println("SD card error.");

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

/*-----( Declare User-written Functions )-----*/
void printTemperature(DeviceAddress deviceAddress){
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));
   }
}// End printTemperature
//*********( THE END )***********

Any help would be appreciated, thanks.

Nick

You seem to have not declared probe1, probe2 & probe3 but declared Probe01..Probe03 twice, suspect that this is an oversight. Perhaps calling these values temp1 to temp3 might make it easier to read?

What happens if you print out the value of probe1 after its assigned? Is it 0 at that point?

A better way might be to have the function return the value something like

	Serial.print("Probe 03 temperature is:   ");
	probe3= printTemperature(Probe03);
	Serial.println();
	

float printTemperature(DeviceAddress deviceAddress){
	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));
	}
        return tempC
}// End printTemperature

Thanks for the reply, That was an oversight on my end upon writing the issue on the forumn (sorry). I took your advice and changed to different variables to make it easier to read. When trying the code you provided and calling the new variable temp1 = print.temperature(Probe01) I am faced with the following error.

error: assigning to 'float' from incompatible type 'void'

Similar but simpler code

/* Basic 2xDS18B20 code for serial monitor, bluetooth, Excel or w.h.y.
 Derived from Hacktronics.
 http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html
 Use their address sniffer and substitute your
 numbers. Use Hacktronics connections diagram.
 Stay away from using parasite power
 -127C means bad connection
 85 means you haven't gotten a read yet, probably wrong order of commands
 Use your own LCD connections
 */

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

// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 3

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

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

byte Thermo1[8] = {0x28, 0x39, 0xFD, 0x50, 0x04, 0x00, 0x00, 0X69};
byte Thermo2[8] = {0x28, 0x09, 0xA9, 0xC0, 0x03, 0x00, 0x00, 0x95};

float tempC,Temp1,Temp2; 

void setup(){
  Serial.begin(9600);
  sensors.begin();
 
/*No resolution command means default to 12 bit
  sensors.setResolution(Thermo1, 10);
  sensors.setResolution(Thermo2, 10);
*/

  delay(1000);//Wait for newly restarted system to stabilize
}

void loop() {
  sensors.requestTemperatures();  // call readings from the addresses
  Temp1 = sensorValue(Thermo1);
  Temp2 = sensorValue(Thermo2); 

  Serial.print("      Temp1 = ");
  Serial.print(Temp1);
  Serial.print("      Temp2 = ");
  Serial.println(Temp2);

  delay(1000);
}

//sensorValue function
float sensorValue (byte deviceAddress[])
{
  tempC = sensors.getTempC (deviceAddress);
  return tempC;
}

@Nick_Pyne,
Thank you for that sample code, it is so much simpler than what I was attempting to do. It works perfectly and I even got it to display and record both °C and °F to the SD card file. I am a noob with arduino and coding in C so this is much appreciated thank you.

Thumper702:
I even got it to display and record both °C and °F to the SD card file.

Excellent. Now all you need to do is get them off the SD!

http://homepages.ihug.com.au/~npyner/Arduino/Bluetooth_graphic_5110_with_file_retrieve_DY.ino

Thanks Nick_Pyner for the reply from Arduino Mega Datalogging with DS18B20 Sensors - #4 by Nick_Pyner - Sensors - Arduino Forum.

I have a similar problem and used your code. It did not work using pin 3. However, after changing the definition on line 16 from pin3 to pin 10, it worked just fine. I have tried this with other sketches found online and they only work with pin 10. As I am trying to develop a project with an RTC/SD shield that uses pin 10 for its function, I have tried to change the sketches to use other pins for the OneWire bus. I am also working with a Mega 2560. I have tried pins 3, 4, 5, 11, 44, 45, and 46 with the same results. Any thoughts?

This is a bit hard to follow. I use pin 3 for OneWire only out of habit but, if it didn't work for you, it can only be for mechanical reasons, or you didn't properly declare for pin 3 in your programme. That said, any will do, and you can even use multiple instances of OneWire on multiple pins. I submit that, if you are chasing around a Mega, with all those pins, and you only need one that works, your problem is more likely to be at the other end of the wire.

I don't know anything about your RTC/SD shield but be aware that it might not be using pin 10 anyway. Pin 10 is called as an output for SD on a Uno, even if you don't use it, but pin 53 is used for that on a Mega. In the light of this, I rather suspect pin 10 for OneWire would be kosher anyway.

That said, I'm pretty sure your problem is not what you think it is, and I believe you need to address that first - and leave the shield out of the game.

Thank you for the attention Nick_Pyner.

The pin declaration is done as copy and paste and then change the "10" for "3". I have used 5, 6, 44, 45, 46, all with the same result. If I find a solution, I will share it here.

Thanks again.

OK, but as I said, you might check the connections to the sensor, as this is all highly suss. If you pursue this, I recommend you start a new topic about pin selection for OneWire, as this may pertain the the software rather than the DS18B20.