Writing data of a DS18B20 sensor on a SD Card


We are a group of students working on a project that require storing data from a DS18B20 device (temperature sensor) on a SD Card. We developed a program that allows us to read the data from the sensor and print it on the serial port. We also developed a program to write basic data on the SD card (1,2,3,4…).

However, we are in trouble if we want to write the data from the DS18B20 device on the SD card. The problem is that the data from the sensor isn’t correct if we start the communication with the SD adaptator (typically, the sensor send -127°C that correspond to a 0V value).

We think that the problem comes from two different speeds of communication because of the SPI library (for the SD card) and the One wire protocol (for the sensor)

We would be very thankful if someone could help us to understand how we could pass through this problem.

Here is the code that we developed:

Writing_SD_Card_DS18B20.ino (3 KB)

We also developed a program to write basic data on the SD card (1,2,3,4...).

If you can do that, you can send sensor data in the same manner

typically, the sensor send -127°C that correspond to a 0V value

-127 is better interpreted as "device not connected"

We think that the problem comes from two different speeds of communication because of the SPI library (for the SD card) and the One wire protocol (for the sensor)

I don't see how this is a problem. The only speed issue is when you don't allow the sensor time to do it's job., in which case you should be getting 85, not 127. The time required depends on the resolution. One second in the loop will cover everything. Check the please reads to post your code in the proper manner, using tags.

// Data wire is plugged into port [color=red][b]10[/b][/color] on the Arduino
#define ONE_WIRE_BUS [b][color=red]10[/color][/b]

that's probably not a great idea when using the SPI library

You should actually set pin 10 as an output even if you have CS on pin 4 and select another pin for the one wire bus.

see SPI Reference
All AVR based boards have an SS pin that is useful when they act as a slave controlled by an external master. Since this library supports only master mode, this pin should be set always as OUTPUT otherwise the SPI interface could be put automatically into slave mode by hardware, rendering the library inoperative.

Also you are overflowing your "mess" (name well picked in that case as you are making a mess in memory :slight_smile: ) with

  char mess[15];                                                           // Define a char to store the temperature
  sprintf(mess, "Temp sonde = %i.%02i" , int(tempC), 100 * (tempC - int(tempC))); // Print the int part of the temperature "dot" the decimal part

your string with the temperature will be longer than 14 chars + the '\0'

also you'll get an interesting display if your temperature goes below 0 with the way you do %i.%02i" , int(tempC), 100 * (tempC - int(tempC)

Yes, pin 10 will not work for one-wire bus when using SPI, because one wire sets the pin as in input to read.

Thank you very much, changing the pin 10 solved the problem. I didn't know that pin 10 could not be used at the same time with SPI.

I also note your advice concerning the overflowing of the char "mess" (mess for message, even if I admit that it is currently a mess) and the negative temperature, thank you in advance !

I apologize for the way I posted my code, I do not use the forum very often.

Good luck

We all started where you are - keep learning keep trying

There is a sipler way to log the data to the SD card. if you use a Dallas temp sketch then you will see this line.
"Serial.print(“Ambient Temperature: “);”
" Serial.println(sensors.getTempCByIndex(0));”

So if you name your FILE say myFile then all you need to do is replace the serial with myFile and it will take that info and log it to the SD card aswel as display it on your IDE line. here is an example that i did of a adalogger that uses an INA219 and several DS18B20 temp sensors and all that info loggs to the SD card.

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

#define ONE_WIRE_BUS A0
const int ledPin = 8;
Adafruit_INA219 ina219;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 1000;

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
const int chipSelect = 4;
File myFile;

void setup()
uint32_t currentFrequency;

void loop()
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(LED_BUILTIN, LOW);
myFile = SD.open(“myFile.log”, FILE_WRITE);
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;

shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
loadvoltage = busvoltage + (shuntvoltage / 1000);

Serial.print(“Bus Voltage: “); Serial.print(busvoltage); Serial.println(” V”);
Serial.print(“Shunt Voltage: “); Serial.print(shuntvoltage); Serial.println(” mV”);
Serial.print(“Load Voltage: “); Serial.print(loadvoltage); Serial.println(” V”);
Serial.print(“Current: “); Serial.print(current_mA); Serial.println(” mA”);

myFile.print(“Bus Voltage: “); myFile.print(busvoltage); myFile.println(” V”);
myFile.print(“Shunt Voltage: “); myFile.print(shuntvoltage); myFile.println(” mV”);
myFile.print(“Load Voltage: “); myFile.print(loadvoltage); myFile.println(” V”);
myFile.print(“Current: “); myFile.print(current_mA); myFile.println(” mA”);
digitalWrite(ledPin, HIGH);
digitalWrite(ledPin, LOW);


Serial.print("Ambient Temperature: ");
myFile.print("Ambient Temperature: ");

Serial.print("Battery inside temperature: ");
myFile.print("Battery inside temperature: ");

Serial.print("Battery outside temperature: ");
myFile.print("Battery outside temperature: ");
myFile = SD.open(“myFile.log”, FILE_READ);