Hello,
I am trying to use the TinyRTC (DS1307 rtc, and a DS18B20 soldered on the board) with a DHT11 temperature/humidity sensor on an Arduino Mega 2560.
The time, date, weekday, and two temperature reads, along with the humidity read, are all displayed upon a GLCD (ST7920) using the u8g2 library software SPI.
I can get the GLCD to display things okay, alone.
I can get the RTC programmed up with the correct time, date, weekday data, alone. And also, using another display like a 20x4 I2C LCD, read the rtc data and all the climate data, and display all that on the LCD.
But when I try to display the rtc and climate data on the GLCD, using u8g2 lib, the rtc data is 'reset' (for lack of better word) back to as if it were powered up for the first time. Hence, the values on the GLCD are all weird.
Also, I have browsed a few topics like mine, where people have said that setting the U8g2 bus speed to 100kHz (the I2C speed the rtc uses) will help. But having tried that, as per the GitHub U8g2 Reference (setBusSpeed), it didn't make a difference. And I didn't think it would as I am not using I2C for both the rtc and GLCD.
Questions:
-
I am wondering if there's a clash when using software SPI and hardware I2C on the Mega? Would this cause the rtc to reset data?
-
Does anyone know why the rtc is getting reset? The TinyRTC module works well with the LCD (as I have to use that to re-enter the correct time/date/weekday values).
-
Most importantly to me... How can I resolve this?
My code:
// -- Include Section ------------------------------------------------------------------------------------------------------------
#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <U8g2lib.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DHT.h>
#include <Adafruit_Sensor.h>
// -- Define Section - DHT11 -----------------------------------------------------------------------------------------------------
#define DHTPIN 61 // DHT11 Sensor pin "S" on 'D61' (or 'A7') {'PF7'}
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
// -- Define Section - TinyRTC - RTC, EEPROM and DS18B20 -------------------------------------------------------------------------
#define ONE_WIRE_BUS 25 // DS18S20 Sensor pin "DS" on 'D25' {'PA3'}
#define BATT_VOLTS A6 // RTC Battery Voltage pin "BATT" on 'D60' (or 'A6') {'PF6'}
#define SQ_Wave 26 // RTC Square Wave pin "SQ" on 'D26' {'PA4'}
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
byte DS1307_ADDRESS = 0x68;
int DS1307_ADDRESS_INT = 104;
// -- Define Section - GLCD ------------------------------------------------------------------------------------------------------
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* (E) clock=*/ 24, /* (RW) DataIn=*/ 23, /* (RS) ChipSelect=*/ 22, /* (RST) reset=*/ 14);
// "GLCD_1_EN" = 'D24' {'PA2'},
// "GLCD_1_RW" = 'D23' {'PA1'},
// "GLCD_1_RS" = 'D22' {'PA0'},
// "GLCD_1_RST" = 'D14-TX3' {'PJ1'}
// "U8G2_ST7920_128X64_F_SW_SPI" - 'ST7920' = GLCD model.
// "U8G2_ST7920_128X64_F_SW_SPI" - '128X64' = pixels of GLCD.
// "U8G2_ST7920_128X64_F_SW_SPI" - 'F' = Full buffer mode. The entire display is rendered in RAM. Must use 'sendBuffer'.
// '1' or '2' = Will store one or two pages of the display in RAM only. Must use 'firstPage/nextPage'.
// "U8G2_ST7920_128X64_F_SW_SPI" - 'SW' = Software. 'HW' = Hardware. For either SPI or I2C.
// "U8G2_ST7920_128X64_F_SW_SPI" - 'SPI' = Serial Peripheral Interface (SPI). 'I2C' = Inter-intergrated circuit (I2C).
#define GLCD_BL_IO 6 // GLCD BackLight NPN (For PWM) pin "GLCD_1_BL" on 'D6' {'PH3'}
// -- Variable Section -----------------------------------------------------------------------------------------------------------
int seconds;
int minutes;
int hours24;
int weekday;
int daydate;
int month;
int year;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
float HumidityData = 0;
float TemperatureCelsiusData = 0;
float TemperatureFahrenheitData = 0;
int GLCD_BackLight_PWM_VAL = 128;
void setup() { // Configure pins, variables, and library stuff
// ---- Serial --------------------------------------------------------------------------
Serial.begin(115200);
Serial.println("TinyRTC DHT11 and U8g2 SW_SPI GLCD is Starting!");
Serial.println("Status: Start Set-Up!");
// ---- Pins ----------------------------------------------------------------------------
// ---- TinyRTC -------------------------------------------------------------------------
pinMode(SQ_Wave, INPUT);
// ---- Pin Default Assignments ---------------------------------------------------------
// ---- GLCD ----------------------------------------------------------------------------
analogWrite(GLCD_BL_IO, GLCD_BackLight_PWM_VAL); // Backlight pwm
//u8g2.setBusClock(100000);
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_pxplusibmcgathin_8f);
// Also see; https://github.com/olikraus/u8g2/wiki/fntlist8 for font list code reference titled 'U8g2 Font Names' (see below)
// -------------------------------------------------------------------------
// <prefix> '_' <name> '_' <purpose> <char set>
// -------------------------------------------------------------------------
// <purpose> | Description
// t | Transparent font. Do not use a background colour.
// h | All glyphs have common height.
// m | All glyphs have common height and width (monospace).
// 8 | All glyphs fit into a 8x8 pixel box.
// -------------------------------------------------------------------------
// <char set> | Description
// f | The font includes up to 256 glyphs.
// r | Only glyphs on the range of the ASCII codes 32 to 137 are included in the font.
// u | Only glyphs on the range of the ASCII codes 32 to 95 (uppercase chars) are included in the font.
// n | Only numbers and extra glyphs for writing date and time strings are included in the font.
// ... | Other custom character list.
// -------------------------------------------------------------------------
// List of functions; https://nodemcu.readthedocs.io/en/release/modules/u8g2/
// ---- GLCD Message --------------------------------------------------------------------
u8g2.setCursor(0, 16);
u8g2.print("Grow Home is");
u8g2.setCursor(40, 24);
u8g2.print("Starting!");
u8g2.setCursor(0, 40);
u8g2.print("Please Wait...");
u8g2.sendBuffer();
// ---- Temperature Sensors -------------------------------------------------------------
sensors.begin();
dht.begin();
// ---- RTC (Square Wave Set-Up) --------------------------------------------------------
// Enable square wave at 1Hz (Clock Registers update on the falling edge of the square wave)
Wire.beginTransmission(DS1307_ADDRESS_INT);
Wire.write(7);
Wire.write(0x10); // Register 7; 'SQWE' (Bit4) = '1' (Square Wave output enabled), 'RS1' and 'RS0' (Bit1 + Bit0) = '00' = 1Hz
Wire.endTransmission();
// ---- Serial Message ------------------------------------------------------------------
Serial.println("Status: Set-Up Complete!");
// ---- GLCD Message --------------------------------------------------------------------
u8g2.clearBuffer();
u8g2.setCursor(0, 16);
u8g2.print("Grow Home is");
u8g2.setCursor(40, 24);
u8g2.print("Starting!");
u8g2.setCursor(0, 40);
u8g2.print("Please Wait...");
u8g2.setCursor(0, 64);
u8g2.print("Completed!");
u8g2.sendBuffer();
}
byte bcdToDec(byte val) { // Convert BCD format to decimal format
return ( (val/16*10) + (val%16) );
}
void Read_Time() { // Get Time/Date values from RTC and transform into readable values
Wire.beginTransmission(DS1307_ADDRESS_INT);
Wire.write(0); // Start at SECONDS
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS_INT, 7); // Request 7 bytes of data (Seconds, Minutes, Hours, Weekday, Day, Month, Year)
seconds = bcdToDec(Wire.read());
minutes = bcdToDec(Wire.read());
hours24 = bcdToDec(Wire.read() & 0b111111);
weekday = bcdToDec(Wire.read());
daydate = bcdToDec(Wire.read());
month = bcdToDec(Wire.read());
year = 2000 + bcdToDec(Wire.read());
}
void Display_Time_Date_Temperatures(){ // Sends data to GLCD
u8g2.clearBuffer();
u8g2.setCursor(0, 8);
u8g2.print("Time: ");
u8g2.print(hours24);
u8g2.print(":");
u8g2.print(minutes);
u8g2.print(":");
u8g2.print(seconds);
u8g2.setCursor(0, 16);
u8g2.print("Wkday: ");
u8g2.print(daysOfTheWeek[(weekday - 1)]);
u8g2.setCursor(0, 24);
u8g2.print("Date: ");
u8g2.print(daydate);
u8g2.print('/');
u8g2.print(month);
u8g2.print('/');
u8g2.print(year);
u8g2.setCursor(0, 32);
u8g2.print("DS18B20: ");
u8g2.print(sensors.getTempCByIndex(0));
u8g2.write(0xB0);
u8g2.print("C");
u8g2.setCursor(0, 40);
u8g2.print("DHT11: ");
u8g2.print(TemperatureCelsiusData);
u8g2.write(0xB0);
u8g2.print("C");
u8g2.setCursor(0, 48);
u8g2.print("Humidity: ");
u8g2.print(HumidityData);
u8g2.print("%R/H");
u8g2.sendBuffer();
}
void loop() { // Main loop
// -- Time/Date and Temperatures ----------------------------------------------------------------------------
// TinyRTC - DS1307
Read_Time();
// DHT11
HumidityData = dht.readHumidity();
TemperatureCelsiusData = dht.readTemperature();
TemperatureFahrenheitData = dht.readTemperature(true);
//Check if there were any faults on the sensor
if (isnan(HumidityData) || isnan(TemperatureCelsiusData) || isnan(TemperatureFahrenheitData)) {
Serial.println(F("Failed to read from DHT Sensor!"));
return;
}
// TinyRTC - DS18B20 - Temperature Sensor
sensors.requestTemperatures();
// -- Display to GLCD ---------------------------------------------------------------------------------------
Display_Time_Date_Temperatures();
// Pause for seconds to tick over
delay(1000);
}
The GLCD display for the RTC:
- TinyRTC DS1307 has correct time, date, weekday, data on it when connected to Mega
- Time display is: 45:165:165 (unchanging)
- Weekday display is: (nothing)
- Date display is: 165/165/21(cut off on screen from here)
- DS18B20 display is: working
- DHT11 temperature display is: working
- DHT11 humidity display is: working
- Data on TinyRTC DS1307, after tested on another 20x4 LCD I2C Display seems to have been corrupted or lost (looks like it has been reset)
Btw, I am using Visual Studio Code Platform IO.
Any help would be appreciated.
Thank you ![]()