I am trying to get DHT22 and DS18B20 to work together. The code below is the one I am using:
#include <SD.h>
#include "SPI.h"
#include "DHT.h"
#include <RTClibExtended.h>
#include <Wire.h>
#include <LowPower.h>
#include <stdlib.h>
#include <avr/interrupt.h> // library for interrupts handling
#include <avr/sleep.h> // library for sleep
#include <avr/power.h> // library for power control
#include <OneWire.h>
#include <DallasTemperature.h>
#define DHTPIN 7 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
#define wakePin 2 //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
#define ONE_WIRE_BUS 4 //DS18B20 is plugged into pin 4
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
const int chipSelect = 10;
int interval_sec=0; //An alarm interval in seconds
int interval_min=5; //An alarm interval in minutes
int interval_hr=0; //An alarm interval in hours
char file_name[25]="Readings.csv"; //
DHT dht(DHTPIN, DHTTYPE);
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
void setup () {
Serial.begin(9600);
delay(3000); // wait for console opening
/**RTC**/
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
/**INTERRUPT**/
//Set pin D2 as INPUT for accepting the interrupt signal from DS3231
pinMode(wakePin, INPUT_PULLUP);
Wire.begin();
//clear any pending alarms
rtc.armAlarm(1, false);
rtc.clearAlarm(1);
rtc.alarmInterrupt(1, false);
rtc.armAlarm(2, false);
rtc.clearAlarm(2);
rtc.alarmInterrupt(2, false);
//Set SQW pin to OFF (in my case it was set by default to 1Hz)
//The output of the DS3231 INT pin is connected to this pin
//It must be connected to arduino D2 pin for wake-up
rtc.writeSqwPinMode(DS3231_OFF);
//Initialize DS18B20 libraries
sensors.begin();
/**SD CARD**/
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
//Remove File from SD card and create a new one
SD.remove(file_name);
File dataFile = SD.open(file_name, FILE_WRITE);
dataFile.println("Date,Hour,Minute,Air_Temp,Humidity,Surface_Temp"); //Write the header
dataFile.close();
Serial.println("Initialisation complete.");
delay(100); //Allow for serial print to complete.
}
void loop () {
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
/**Temperature and Humidity**/
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius
float t = dht.readTemperature();
// Read temperature as Fahrenheit
//float f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
//if (isnan(h) || isnan(t) || isnan(f)) {
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// Compute heat index
// Must send in temp in Fahrenheit!
//float hi = dht.computeHeatIndex(f, h);
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C\t");
delay(3000); // wait for console
/**DS18B20**/
// call sensors.requestTemperatures() to issue a global temperature request to all devices on the bus
sensors.requestTemperatures(); // Send the command to get temperatures
float surface_temp=sensors.getTempCByIndex(0);
Serial.print("Temperature for the device 1 (index 0) is: ");
Serial.println(surface_temp);
delay(3000); // wait for console
/**Store on SD**/
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open(file_name, FILE_WRITE);
String dataString = now.day() + String("/") + now.month() + String("/") + now.year() + String(",") + now.hour() + String(",") + now.minute() + String(",") + t + String(",") + h + String(",") + surface_temp;
//String dataString = now.day() + String("/") + now.month() + String("/") + now.year() + String(",") + now.hour() + String(",") + now.minute() + String(",") + t + String(",") + h + String(",") + String("surface_temp");
//Serial.println(dataString);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
//Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening file to log data");
}
/**INTERRUPT Based sleep**/
DateTime nextAlarm = now + TimeSpan(0, interval_hr, interval_min, interval_sec);
//Format is TimeSpan(day,hour,min,sec). Either use interval_min or interval_sec
Serial.print("Alarm at:");
Serial.println(nextAlarm.hour());
Serial.println(nextAlarm.minute());
Serial.println(nextAlarm.second());
rtc.setAlarm(ALM1_MATCH_HOURS, nextAlarm.second(), nextAlarm.minute(), nextAlarm.hour (), 1); //set wake-up time here
rtc.alarmInterrupt(1, true);
delay(3000); // wait for console
attachInterrupt(0, wakeUp, LOW); //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
//Arduino enters sleep mode here
detachInterrupt(0);
//execution resumes from here after wake-up
//When exiting the sleep mode we clear the alarm
rtc.armAlarm(1, false);
rtc.clearAlarm(1);
rtc.alarmInterrupt(1, false);
Serial.println();
delay(3000);
}
void wakeUp() {
// here the interrupt is handled after wakeup
}
The above code ideally should read and store the temperature from DS18B20, and temperature and humidity from DHT22 and then go to sleep for a pre-determined time (5mins now) and then wake up when an interrupt is generated from the RTC.
However, I am unable to get both DHT22 and DS18B20 to work together. The code above works as expected if I comment out the code for DS18B20. Similarly, if I just run the examples (named Single and Simple) for DS18B20 as provided by DallasTemperature on the same Arduino keeping all the connections intact (DHT, RTC, SD Card, along with DS18B20) the DS18B20 also work as expected. Hence, I think I can be certain that the connections are proper. However, if I run the code above which include both DHT22 and DS18B20, then the output I get is as follows:
Initializing SD card...card initialized.
Initialisation complete.
201Initializing SD card...card initialized.
Initialisation complete.
2⸮
I would appreciate if someone can point me to where I am going wrong.
P.S.: I have also successfully tried a simple program like the one below to ensure that there are no conflicts in libraries of DHT22 and DS18B20.
#include <DallasTemperature.h>
#include <OneWire.h>
#include <DHT.h>
#define ONE_WIRE_BUS 4
#define DHTPIN 7 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
void setup(void) {
Serial.begin(9600);
Serial.println("Dallas Temperature IC Control Library Demo");
sensors.begin();
}
void loop(void) {
sensors.requestTemperatures();
Serial.print("Temperature1: ");
Serial.print(dht.readTemperature());
Serial.print(" Temperature 2 : ");
Serial.println(sensors.getTempCByIndex(0));
}