https://fossbytes.com/localhosts-ip-address-127-0-0-1-meaning/
https://fossbytes.com/localhosts-ip-address-127-0-0-1-meaning/
https://www.oreilly.com/library/view/understanding-and-using/9781449344535/ch04.html
https://stackoverflow.com/questions/1052818/create-a-pointer-to-two-dimensional-array
https://dyclassroom.com/c/c-pointers-and-two-dimensional-array
https://www.geeksforgeeks.org/pointer-array-array-pointer/
In this tutorial, we will discuss the purpose of getting the current date and time on the Arduino, what is a Real-Time Clock, what is a DS3231 RTC module and we will build a project using a DS3231 RTC module, a 16×2 I2C LCD and an Arduino Uno.
Keeping track of the current date/time for an Arduino has many purposes. One use for it is for recording/log purposes. For example, an Arduino Weather Station needs timestamps in recording weather data. Another example is for an Arduino digital clock or calendar. Arduino-based clocks use the current time as a timer for reminders or to execute a scheduled command via the Arduino’s I/O pins. Depending on the project, having a way to get the current date and time is very useful.
There are several ways to get the current date and time. We can get it from a Real-Time Clock (RTC), a GPS device, or a time server.
An RTC is a very popular and accurate source of time and date in an embedded system like an Arduino because it has low power consumption.
If you want to learn how to communicate with an internet time server to get the current time and date, please read How to Keep Track of the Date and Time on an Arduino.
The DS3231 RTC module is a real-time clock module using the DS3231 IC. The DS3231 IC is a very affordable and extremely accurate RTC with an I2C interface. It is very accurate because it uses an integrated temperature-compensated crystal oscillator (TCXO) along with a crystal. To keep track of time even if the main power source is removed, the DS3231 has a backup battery mounted at the back of the module. The chip automatically switches between main and backup power sources when necessary.
The RTC keeps track of seconds, minutes, hours, day, date, month, and
year data. It also automatically adjusts for months with less than 31
days and also for leap years. The clock can operate in either 24H or 12H
(with AM/PM) formats. There are also two programmable time-of-day
alarms and also a programmable square-wave output. Communication with
the RTC is done through an I2C interface with a fixed default address of
0x68
.
Aside from the RTC chip, this particular module also has a 24C32
EEPROM chip. An EEPROM is a kind of data storage device wherein you can
read/write data. The 24C32 has 32 bytes of available data storage space.
It shares the module’s I2C bus with the DS3231 and has the default
address of 0x57
. We can change the EEPROM’s default address by bridging the solder pads indicated by A0, A1, and A2 as shown in Figure 2.
After learning about timekeeping and the DS3231 RTC, it is now time to build a project using the DS3231 RTC. For this project, we will make a simple Arduino Calendar Clock using a DS3231 module, a 16×2 I2C LCD, and an Arduino Uno board.
The wiring diagram for our project is shown in Figure 4. Because we are using I2C, all devices share a common bus consisting of only 4 wires.
To make it easy for us to develop the code of our project, we will use libraries and create custom functions to make our code easier to read.
Our project will include the following libraries. See Figure 5 to check which libraries to install using the Arduino IDE’s built-in Library Manager.
Wire.h
library for the I2C interface (included in Arduino IDE)LiquidCrystal_I2C.h
library (by Frank de Brabander) for the I2C 16×2 LCD module (GitHub link)RTClib.h
library (by Adafruit) for the DS3231 RTC module (GitHub link)The Wire.h
library and the I2C protocol were already discussed in previous articles (here and here) and therefore will not be addressed in this tutorial.
To start our sketch, add the abovementioned libraries to our code by using the keyword #include
. We will also initialize two objects lcd()
and rtc
to be used for communicating with the LCD and DS3231 respectively.
#include <Wire.h> // for I2C communication
#include <LiquidCrystal_I2C.h> // for LCD
#include <RTClib.h> // for RTC
LiquidCrystal_I2C lcd(0x27, 16, 2); // create LCD with I2C address 0x27, 16 characters per line, 2 lines
RTC_DS3231 rtc; // create rtc for the DS3231 RTC module, address is fixed at 0x68
To make our code easier to manage, we will create two custom functions
The first function we will code is the function updateRTC()
.
This function will be responsible for asking the user for the date and
time and updating the RTC’s internal clock with the user’s input data.
After getting the user input, we can update the RTC’s internal clock by
using the function rtc.adjust()
from the RTCLib.h
library. The rtc.adjust()
function receives a parameter with type DataTime
which it uses to update the rtc’s internal time and date.
/*
function to update RTC time using user input
*/
void updateRTC()
{
lcd.clear(); // clear LCD display
lcd.setCursor(0, 0);
lcd.print("Edit Mode...");
// ask user to enter new date and time
const char txt[6][15] = { "year [4-digit]", "month [1~12]", "day [1~31]",
"hours [0~23]", "minutes [0~59]", "seconds [0~59]"};
String str = "";
long newDate[6];
while (Serial.available()) {
Serial.read(); // clear serial buffer
}
for (int i = 0; i < 6; i++) {
Serial.print("Enter ");
Serial.print(txt[i]);
Serial.print(": ");
while (!Serial.available()) {
; // wait for user input
}
str = Serial.readString(); // read user input
newDate[i] = str.toInt(); // convert user input to number and save to array
Serial.println(newDate[i]); // show user input
}
// update RTC
rtc.adjust(DateTime(newDate[0], newDate[1], newDate[2], newDate[3], newDate[4], newDate[5]));
Serial.println("RTC Updated!");
}
The second custom function we will create is the function updateLCD()
.
This function will update or refresh the text displayed on the LCD.
Inside this function, we will first get the time and date from the RTC.
This is done by calling rtc.now()
function which is included in the RTCLib.h
library.
The function rtc.now()
in our code returns a DateTime
data type that contains the current date and time of the rtc. We then
assign the data to different variables for additional formatting on the
LCD. After assigning the variables, we use the functions lcd.setCursor()
and lcd.print()
from the LiquidCrystal_I2C.h
to
position the cursor and to display the text respectively on the LCD.
The code below shows how these functions come together to get the rtc
time, format the text and display it to the LCD.
/*
function to update LCD text
*/
void updateLCD()
{
/*
create array to convert digit days to words:
0 = Sunday | 4 = Thursday
1 = Monday | 5 = Friday
2 = Tuesday | 6 = Saturday
3 = Wednesday |
*/
const char dayInWords[7][4] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
/*
create array to convert digit months to words:
0 = [no use] |
1 = January | 6 = June
2 = February | 7 = July
3 = March | 8 = August
4 = April | 9 = September
5 = May | 10 = October
6 = June | 11 = November
7 = July | 12 = December
*/
const char monthInWords[13][4] = {" ", "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
// get time and date from RTC and save in variables
DateTime rtcTime = rtc.now();
int ss = rtcTime.second();
int mm = rtcTime.minute();
int hh = rtcTime.twelveHour();
int DD = rtcTime.dayOfTheWeek();
int dd = rtcTime.day();
int MM = rtcTime.month();
int yyyy = rtcTime.year();
// move LCD cursor to upper-left position
lcd.setCursor(0, 0);
// print date in dd-MMM-yyyy format and day of week
if (dd < 10) lcd.print("0"); // add preceeding '0' if number is less than 10
lcd.print(dd);
lcd.print("-");
lcd.print(monthInWords[MM]);
lcd.print("-");
lcd.print(yyyy);
lcd.print(" ");
lcd.print(dayInWords[DD]);
// move LCD cursor to lower-left position
lcd.setCursor(0, 1);
// print time in 12H format
if (hh < 10) lcd.print("0");
lcd.print(hh);
lcd.print(':');
if (mm < 10) lcd.print("0");
lcd.print(mm);
lcd.print(':');
if (ss < 10) lcd.print("0");
lcd.print(ss);
if (rtcTime.isPM()) lcd.print(" PM"); // print AM/PM indication
else lcd.print(" AM");
}
The last phase in completing our code for an Arduino Calendar Clock is to add the standard Arduino functions setup()
and loop()
.
Inside setup()
, we will initialize the serial interface, the lcd
and the rtc
objects. To initialize the serial with a baud rate of 9600 bps, we will use the code Serial.begin(9600);
. For the LCD, we need to initialize the LCD object and switch-on the backlight of the display. This is achieved by the codes lcd.init();
and lcd.backlight();
. And finally, we add the code rtc.begin();
to initialize the rtc object.
void setup()
{
Serial.begin(9600); // initialize serial
lcd.init(); // initialize lcd
lcd.backlight(); // switch-on lcd backlight
rtc.begin(); // initialize rtc
}
For the loop()
function, we will update the text displayed on the LCD by calling updateLCD();
.
We will also add the capability to accept user input to update the
RTC’s internal clock. If the user sends the char ‘u’ via the serial
monitor, it means the user wants to modify the set time and date of the
rtc. If this is the case, then we call the function updateRTC();
to handle user input and update the RTC internal clock.
void loop()
{
updateLCD(); // update LCD text
if (Serial.available()) {
char input = Serial.read();
if (input == 'u') updateRTC(); // update RTC time
}
}
Our sketch is now complete. Save the sketch as arduino-rtc-tutorial.ino and upload it to your Arduino Uno.
After uploading the sketch, your Arduino Uno should display the date and time on the LCD as shown in Figure 6.
To change the date/time, open your Serial Monitor, and send the letter ‘u’. And then just follow the on-screen prompts to enter the new date and time.
In summary, an RTC module is an easy and inexpensive way to add timekeeping capability to an Arduino based project. This tutorial just showed the basic capability of the DS3231 RTC module. And with more tinkering, you can find lots of uses for this module.
Nguồn: https://www.circuitbasics.com/how-to-use-a-real-time-clock-module-with-the-arduino/
https://gribblelab.org/CBootCamp/7_Memory_Stack_vs_Heap.html
http://net-informations.com/faq/net/stack-heap.htm
https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap
https://slideplayer.com/slide/12752485/
https://www.allaboutcircuits.com/technical-articles/what-is-the-sinc-function-and-why-is-it-important-in-electrical-engineering/?fbclid=IwAR1LWbQcCyVjGbL4FDbV-1-Cwjocwtm-XklD4GydsvRr1TBbvJj_bEvlcIw
A good article from The Cave Pearl Project.
https://thecavepearlproject.org/2015/03/30/using-ds18b20-one-wire-sensors-to-make-a-diy-thermistor-string-pt-2-calibration/