RTC3231 - Basic question actually

Hello,

I hope you are able to help me again...
For now I ordered a RTC3231 module and I am trying to set this on up. (I would like to use this timer for consistently watering the garden.)

However I am confused, because on Youtube there are several tutorials, all slightly different. And they all use other libraries. .. I found a library the 3231 from karlson but it failed with installing the zip file due to "library properties not found."
I currently installed the rtc an a rtclip library.

But could somebody provide just the simple code for using and setting this rtc up?
I would be most grateful.

Greetings.

You could start with

https://www.arduino.cc/reference/en/libraries/rtclib/

Which works well enough usually.

Get an example that you don't tinker with at all to function first.

You can do it all without an RTC library, you'd still need the Wire library, functionality those RTC libraries exploit.

Not sure which route is the kinda fun you are looking for.

a7

and get a view to the examples provided by the IDE too

You also need to make sure that you have the RTC connected properly to the Arduino.
Here is how I have mine connected in one of my projects:

  • RTC SDA goes directly to A4 of Arduino
  • RTC SDA goes through a 5100-ohm resistor to +5V
  • RTC SCL goes directly to A5 of Arduino
  • RTC SCL goes through a 5100-ohm resistor to +5V
  • RTC VCC goes to +5V
  • RTC GND goes to ground

I think that this is correct, but I am sure that someone will correct me in case this is wrong.

Seems you use I2C to communicate with it. The address of the device is "1010" + three bits defined by soldering or unsoldering A1, A2 and A3, letting you this way select the address. Better leave them as they are, which apparently means they are all 1's and that gives a device 7-bit address of 1010111. Ignore the mention of the R/W bit - the WIre library handles that. The address in hex is thus 0x57, but you can just type:

#define ADDR    B1010111

(If you're not comfortable converting between binary and hex).

I just tested an EEPROM chip using this same address scheme, with A1, A2, A3 available as pins that I could connect to GNT or 5V to set them to 0 or 1. Very handy feature!

I see the page I found refers to the library you mentioned. If it doesn't work, check you wiring, EXCEPT FOR one thing: I2C normally requires pullup-resistors, and I can't see those included in the drawings.

This means you should add two resistors in the 3-10k ohms range between SDA (Serial Data) and VCC, and similarly between SCL (Serial Clock) and VCC.

Good luck!

All that address stuff is for a second I2C device that finds itself on the same module as the RTC.

The RTC is at the address most libraries expect it to be. And there are pull-ups on the module. I have never added pull-ups using this module and the UNO, e.g.

Also and BTW, if you really have that module, you should know about and fix a flaw in the design of the battery charging circuit, viz:

Just one of dozens of sites that 'splain this matter.

a7

Pullups on the device? Really? Would not that make multiple devices on the I2C bus collectively lower the resistance, and (in principle) increase power use?

Arduinos have support for pullups on pins, but those pullups I believe are too weak (20+ kOhms), which in turn translates to low speed (CLK frequency).

I might be wrong. It has happened.

That depends on exactly which module you have. I have the ChronoDot.

Again, that depends on which module you have.

I'm sorry. I should have clarified that I was using the ChronoDot.
Again, there are many DS3231-based RTC modules, and I don't believe that the OP has specified which one they are using.

Which one? Where did you get it from? There are at least a few different types of DS3231 module out there, and how exactly you set up your hardware will depend on which one you have.

Which libraries, exactly? Where did you find them? Unfortunately, there are many libraries with the same or similar names, so it would help if you specified exactly where you got them from.

Thanks for helping me in the right way.
For now I am not able anymore to try all of your suggestions, because today I am out of compilation ...

However:
I ve read the "in depth" suggested by @Rupert909 (thnx)
Reacting: In my current setup I will use a liquid crystal which is wired to a4 & a5 on my Uno.
I've set the RTC up at 5V and pin "16 & 17" (which then is probably wrong, but I thought seeing people do this)

The library suggested by @alto777 was installed! Which lead to the latest rtclib library... I would be using the ds3231 example I assume?

and for @odometer: I ordered my rtc from Amazon... (DS3231SN 1824A4 917AD), The libraries I used I found in the description of the Youtube tutorials, which isn't very helpful, but I just re installed the latest rtclib - so I reckon this is a good starting point?!

a4 and a5 are the i2c pins on the Uno. It is a "bus", which means you communicate with multiple devices on the same two lines. That's why devices on I2C have addresses. So if your liquid crystal display uses I2C, you will wire both it and the RTC to pins a4 and a5. You'll figure it out.

2 Likes

It depends on which RTC chip you are using. The DS3231, a plausible guess at this point, is at 0x68:

static const uint8_t      RTC_ADDRESS  = 0x68; 
      // Datasheet, Page 16, Figure 3.  Note that this is 7 bits, the last (LSB) bit of an I2C address indicates Read from Slave (1) or Write to Slave (1) 

The Chronodot does not have pullups. The other module pictured, which has on board EEPROM at a second I2C address, does have pullups, and that bogus battery charging circuit.

Yes, really. Just one more way to have fun with I2C… when using the I2C bus, one must account for the pullup requirement, which might involve installing (or removing) some resistors.

@b-art86 your numbers don't lead to a part number with as much googling as I am going to give it - can you post a link to the Amazon product page for you module?

And yes, if you have the DS3231 chip on board, that's what would inform choices that the library may afford.

The library I linked works, most of them do. It is essential to start with examples that were written against the actual library you have chosen.

a7

And we haven't even talked about alarms, and interrupts on the SQW/INT pin.

Below is a schematic of one popular DS3231 module, commonly called the ZS-042. Does yours look like this?

Just to make it clear: The correct wiring also depends on which exact module you use. Some of these resistors may already be present on the module.

1 Like

What would be helpful would be a link to the exact Web page (or pages) you downloaded the libraries from.

Goodmorning,

I took a cup of tea and I am able again to look at all the suggestions, thnx!
I tried the updated rtclip library - and reconnected the rtc to the right input pins.
I have used this code: which works I guess. I am testing if it's delaying..

#include <Wire.h>
#include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup () 
{
  Serial.begin(9600);
  delay(3000); // wait for console opening

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
	
	// Comment out below lines once you set the date & time.
    // Following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
	
    // Following line sets the RTC with an explicit date & time
    // for example to set January 27 2017 at 12:56 you would call:
    // rtc.adjust(DateTime(2022, 06, 04, 07, 49, 0));
  }
}

void loop () 
{
    DateTime now = rtc.now();
    
    Serial.println("Current Date & Time: ");
    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();
    
    Serial.println();
    delay(1000);
}

To be complete:
Amazon: shop

Used Library YT vid
Arduino Project: Real time clock - code page 7 years old.
Arduino & Ds3231 Real Time Clock Tut - code page 5 years old and gave an error while installing the zip library
Lesson 19 He came up with his own library.

And last:
This is the idea I want to set up... Arduino Relay trigger - RTC
But as you can see - this guy wires up the RTC to port "16&17" And he is using an example I couldn't find. Probably because his 3231 is slightly different then?

Oke, for now I included the time. Now I want to figure out how to trigger a relay at 6.30 Am and close it after 20minutes. .. lets tinker!

D16 and D17 are the same as A4 and A5. Either way, they are SDA and SCL. His DS3231 module is the same as yours.

THX. So your RTC module is def the version with the dodgy battery charging circuit.

I recommend that as soon as you get the chance, learn about the problem and decide to fix it.

Google

ds3231 remove diode

and read or watch a few sites, see they agree about the problem and pick a solution to apply.

As for examples written against other libraries, it's never too soon to start reading the code and figuring out how to say the same thing to the library you chose.

The RTC only does a few things, I would say no library distinguish itself by having ideas you can't express with any other library.

a7

@alto777 I will thnx,

Follow up:
Guys I spend the afternoon figuring out how to set a specific time to a relay. And I am sure it is easy. But I don't get it right and I don't find the right example.

This is the code I came up with. (see down below)
I am messing with these lines.

DateTime now = rtc.now();
  t = DateTime();
  Serial.print(t.hour);
  Serial.print(" hour(s), ");
  Serial.print(t.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay (1000);

  if(t.hour == OnHour && t.min == OnMin){

it is on and of with all kind of errors.
I think this t in t.hour must be defined in one way. And this example comes from somebody who uses the ds3231.h library
So I allready found out.. you have to set it to:
RTC_DS3231 rtc;
DateTime t;

And he is using the command: t = rtc.getTime(); before Serial.print(t.hour)
But that one didn't work either, so I found the rtc.now() is working... at least working? It doesn't show an error.. ..

Probably there is again a much easier way to do things... And I am open for suggestions :smile:
Just trying to learn.

Current error:

/usr/local/bin/arduino-cli compile --fqbn arduino:avr:uno --libraries /home/builder/opt/libraries/latest --build-cache-path /tmp --output-dir /tmp/873723759/build --build-path /tmp/arduino-build-2726D92D2A6DEDCB60FEA3C1D826D46E --library /mnt/create-efs/webide/d7/bc/d7bcb425b103b8f19b6b2212ece2edc8:b-art86/libraries_v2/DallasTemperature --library /mnt/create-efs/webide/d7/bc/d7bcb425b103b8f19b6b2212ece2edc8:b-art86/libraries_v2/LiquidCrystal I2C --library /mnt/create-efs/webide/d7/bc/d7bcb425b103b8f19b6b2212ece2edc8:b-art86/libraries_v2/OneWire --library /mnt/create-efs/webide/d7/bc/d7bcb425b103b8f19b6b2212ece2edc8:b-art86/libraries_v2/RTClib --library /mnt/create-efs/webide/d7/bc/d7bcb425b103b8f19b6b2212ece2edc8:b-art86/libraries_v2/SimpleAlarmClock /tmp/873723759/Succes_2_sensors_copy

Using library adafruit_busio_1_11_6 at version 1.11.6 in folder: /home/builder/opt/libraries/adafruit_busio_1_11_6

Using library SPI at version 1.0 in folder: /home/builder/.arduino15/packages/arduino/hardware/avr/1.8.4/libraries/SPI

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino: In function 'void loop()':

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:83:22: error: invalid use of non-static member function 'uint8_t DateTime::hour() const'

Serial.print(t.hour);

^

In file included from /tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:6:0:

/mnt/create-efs/webide/d7/bc/d7bcb425b103b8f19b6b2212ece2edc8:b-art86/libraries_v2/RTClib/src/RTClib.h:174:11: note: declared here

uint8_t hour() const { return hh; }

^~~~

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:85:18: error: 'class DateTime' has no member named 'min'

Serial.print(t.min);

^~~

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:90:8: error: invalid use of member function 'uint8_t DateTime::hour() const' (did you forget the '()' ?)

if(t.hour == OnHour && t.min == OnMin){

~~^~~~

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:90:28: error: 'class DateTime' has no member named 'min'

if(t.hour == OnHour && t.min == OnMin){

^~~

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:93:15: error: invalid use of member function 'uint8_t DateTime::hour() const' (did you forget the '()' ?)

else if(t.hour == OffHour && t.min == OffMin){

~~^~~~

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:93:36: error: 'class DateTime' has no member named 'min'

else if(t.hour == OffHour && t.min == OffMin){

^~~

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:102:10: error: 'digtialRead' was not declared in this scope

else(digtialRead(switchPin1) == LOW){

^~~~~~~~~~~

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:102:10: note: suggested alternative: 'digitalRead'

else(digtialRead(switchPin1) == LOW){

^~~~~~~~~~~

digitalRead

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:111:8: error: 'digtialRead' was not declared in this scope

else(digtialRead(switchPin2) == LOW){

^~~~~~~~~~~

/tmp/873723759/Succes_2_sensors_copy/Succes_2_sensors_copy.ino:111:8: note: suggested alternative: 'digitalRead'

else(digtialRead(switchPin2) == LOW){

^~~~~~~~~~~

digitalRead

Error during build: exit status 1

code:

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"

#define RELAY1 8
#define RELAY2 12

int switchPin1 = 7; 
int switchPin2 = 4;

OneWire  ds(2);
RTC_DS3231 rtc;
DateTime t;

DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C lcd(0x27, 16, 2);

const int OnHour = 06; //SET TIME TO ON RELAY (24 HOUR FORMAT)
const int OnMin = 30;
const int OffHour = 06; //SET TIME TO OFF RELAY
const int OffMin = 55;

void setup()
{
  sensors.begin();
  Serial.begin(9600);
  rtc.begin();

// lcd.begin();
  lcd.init ();
  lcd.clear();
  lcd.backlight();

  pinMode(switchPin1, INPUT);
  pinMode(switchPin2, INPUT);
 
  pinMode(RELAY1, OUTPUT);
  digitalWrite(RELAY1, LOW);
  
  pinMode(RELAY2, OUTPUT);
  digitalWrite(RELAY2, LOW);
  
}

void loop()
{
  sensors.requestTemperatures();
  float temp1C = sensors.getTempCByIndex(0);
  float temp2C = sensors.getTempCByIndex(1);
  int tempC = (int)(temp1C + temp2C) / 2;
  Serial.println("==================");
  Serial.println(tempC);
  //-----------------

 lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Temperature:");
  lcd.setCursor(0, 1);
  lcd.print("C:");
  lcd.setCursor(2, 1);
  lcd.print(sensors.getTempCByIndex(0));
  lcd.setCursor(10,1);
  lcd.print(sensors.getTempCByIndex(1));
 
  if (tempC > 21)
  {
    digitalWrite(RELAY1, HIGH);
    lcd.setCursor(13,0);
    lcd.print("ON");
  } else{
    digitalWrite(RELAY1,LOW);
    lcd.setCursor(13,0);
    lcd.print("OFF");
  }
  
  delay(2000);
  
DateTime now = rtc.now();
  t = DateTime();
  Serial.print(t.hour);
  Serial.print(" hour(s), ");
  Serial.print(t.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay (1000);

  if(t.hour == OnHour && t.min == OnMin){
    digitalWrite(RELAY2,HIGH);
    }
    else if(t.hour == OffHour && t.min == OffMin){
      digitalWrite(RELAY2,LOW);
    }
  
  if(digitalRead(switchPin1) == HIGH){
    digitalWrite(RELAY1, HIGH);
    lcd.setCursor(13,0);
    lcd.print("ON");
  } 
    else(digtialRead(switchPin1) == LOW){
      digitalWrite(RELAY1, LOW);
      lcd.setCursor(13,0);
      lcd.print("OFF");
    }
  
  if(digitalRead(switchPin2) == HIGH){
    digitalWrite(RELAY2, HIGH);
  } 
  else(digtialRead(switchPin2) == LOW){
      digitalWrite(RELAY2, LOW);
  }
}

And another more general question:

Just wondering and trying to understand...

  • I understand the first part in which you include the libraries.
  • I also understand you must define the other hardware - I can see that.
  • I can think of the extra int/ flows etc. That you need to define parameters for the formules you use.
  • But how do I know or should I know that you need to add lines as:
    RTC_DS3231 rtc;
    DallasTemperature sensors(&oneWire);
    What does it mean?

And in my case.. above... each library is likely to use slightly different words for the same command. How should I know or where can I find these right commands? I don't understand this.
I mean should I type DateTime / Time / RTC.now / get time? it's bloody confusing for a starter.
Where does these commands refer to.
What you want is that the current time is pulled from the RTC module and then it should do something...