This blog is an example project to explain how to use an Real Time Clock (RTC) module as a mechanism to wake up an Arduino we put to sleep. The code and explanation for putting an Arduino to sleep, and how to wake it up again can be found in this tutorial: A Guide To Putting Your Arduino To Sleep . For you to understand this project I strongly recommend you read this guide first as the code in this project is based upon the code explained in that tutorial.
- The Project overview
- List of Materials needed for this project
- Connecting the Adafruit RTC 3231 breakout board
- The Code for the Adafruit 3231 RTC Breakout board
- Connecting the Adafruit Micro SD Breakout Board
- The code for the Adafruit Micro SD Breakout board
- Connecting the Humidity/ Temperature Sensor DHT11/DHT22
- The Code for the DHT11/DHT22
- Power/Current Consumption (mA)
The Project overview
The purpose of this project is to create a data logger that logs temperature/humidity data on an sd card. The data that gets logged has a date and time stamp. This project will run off a battery pack, thus we put the Arduino to sleep when no data is being logged.
In this project I am using the Adafruit DS3231 RTC breakout board. I used this particular one because of it has a SQW pin, and it uses two Analog pins for communication. In most projects the Analog pins are not used so the RTC does not take up valuable digital pins.
The other feature of this RTC is that you can set alarms that get activated without the need to communicate with the Arduino board (Your Arduino can be asleep and the alarm will still fire). When the alarm fires it pulls the SQW pin to low. We use that action to fire the Interrupt attached to digital pin 2 to wake up an sleeping Arduino, as explained in the turorial (A Guide To Putting Your Arduino To Sleep).
We use the DHT11/22 sensor to read the temperature and humidity of a specific room, and the Adafruit micro SD breakout board to write the data to an SD card. The Arduino used is the Arduino Pro Mini. When soldering the header pins also put header pins pointing upwards in the A4 and A5 holes. We will be using these to communicate with the RTC breakout board
List of Materials needed for this project
Note: This is the first project where I will be using links to Amazon products to list what products are needed. I do this just to recover the costs of the components I use. I don't sell any of these items, but will receive a very small commission. Please consider using these links to buy your products to support me creating these projects/tutorials.
Connecting the Adafruit RTC 3231 breakout board
Lets look at how to connect the RTC to your Arduino Pro Mini:
|DS3231 RTC PINS||Arduino/Breadboard Pins|
|SD Breakout PINS||Arduino/Breadboard Pins|
This image shows you what it would look like on your breadboard
The code for the Adafruit Micro SD Breakout board
The code for this breakout is easy to understand and strait forward. First we load the libraries
The libraries used are part of the Arduino IDE so no need to download anything special here. Next we declare the global variables needed for this board.
First we declare the File name object named myFile, than we declare a constant int (chipSelect). This variable sets the digital pin needed for the Adafruit breakout board. Don't change it, Adafruit wants it to be that pin so we are stuck with it like this.
The actual writing to and reading from a file is done in a function called writeData().
If you remember that this whole sketch is to log temperature and humidity data onto an sd memory card. In this function we do the actual writing. We send this function 3 arguments; float h (humidity), float t (temperature in Celsius), and float f (temperature in Fahrenheit ).
On line 149 we declare another time variable named p, and get the current date and time from the RTC on line 150. We do this for 2 reasons. Reason one is to create a filename that is today's date. This way it is easy to see when data was logged, and reason two is that we use the current time as a time stamp to know exactly when the data was logged.
On line 151 we create a string called file_Name. The string contains today's date. We use the time/date variable to do so. On line 152 we use the string to open, or create a file with the file_Name variable content as name with the SD.open() function. Lets look a bit closer at the syntax of this function.
The filepath is the path to the file including the filename. The mode is either FILE_READ to read from a file, or FILE_WRITE to append to a file. If you use the FILE_WRITE with a filename that does not exist it will create the file name. If you use the SD.open(filepath) it will automatically assume you want to read from the file. If you want to see all option click on the following link; https://www.arduino.cc/en/Reference/SDopen
The SD.open() action gets stored in the myfile object created in the declaration section. Now we have the file open and are ready to write to it.
The if(myFile) statement checks if the file exist and is in the correct format. If this statement returns a false it will print an error message to the Serial Monitor. The most common reason for this is that the sd card is not formatted correctly or not in its socket, or you used a filename that contains characters that are not allowed.
Note: The Adafruit breakout board requires a specific format. For more information on this go to the following link: https://learn.adafruit.com/adafruit-micro-sd-breakout-board-card-tutorial/formatting-notes
On line 158 we actually write to the file. We use the same format used to print a line to the serial monitor, but instead of using Serial, we use the file object myFile. After we wrote to the file we close it with the myFile.close(); line. It is very important that we close the file after reading or writing to it. If the file is not closed correctly it will be corrupted and you won't be able to write to or open that file again.
Connecting the Humidity/ Temperature Sensor DHT11/DHT22
The pinout of this sensor is done with the sensor front grid facing you:
|Data out||Arduino D4|
The image shows all components on the breadboard.
The Code for the DHT11/DHT22
In my sketch you will see the code for the DHT11 as I have this sensor in my collection of sensors, but if I had to use this project in a real world scenario I would use the DHT22 as it has greater precision.
We are using the Adafruit library. You are right this project is definitely Adafruit centric. No I am not getting paid by Adafruit, but if LadyAda is listening I can always use some cash. But enough with the useless banter as you are here to learn something. Lets look at the declaration section for this sensor;
First we load the library
Next we are creating the object to communicate to the sensor and some global variables we need to create the object;
On line 27 we declare the variable that tells the sensor what digital pin we communicate with. We use digital pin 4.
As I explained I am using the DHT11, but if you use the DHT22 comment out line 30 and un-comment line 31. Next we create the dht object on line33. We use the DHTTYPE variable to let the object know what sensor we using, and the DHTPIN variable to let it know what pin to communicate with.
In the setup() function we use the following statement to start communication with the sensor;
The actual reading from the sensor is done in function temp_Humi(). This function is called from line 107 from the Going_To_Sleep() function.
In this function we read the Humidity % with the dht.readHumidity() function, and the temperature both in Celsius dht.readTemperature() and Fahrenheit dht.readTemperature(true). We store these in float variables (h for humidity,t for temperature in Celsius, and f for temperature in Fahrenheit). We take these float values and pass them to the writeData() function where they are written to the SD card.
Power/Current Consumption (mA)
After we tested the code and see how the project runs using the FTDI cable it is time to connect it to an external power supply and a multimeter. We do this to measure how much current we draw. If you are not sure how to do this, check out my tutorial: How to measure power consumption and why should to do it.
After hooking up the project with an external power supply and multimeter we see it consumes 24-28mA when awake and a small 100th of a second spike of 100mA as we write to the SD card. When it is sleeping it only uses 10mA. We can actually save a couple of more milliAmps out of the circuit if we were able to turn the power off on the SD breakout board. Actually we save almost 7mA ending up with only a use of 3mA when it is asleep.
We do this by using an NPN transistor as a switch to turn the power off on the SD breakout board when the Arduino is asleep.
Note: When you put the Arduino to sleep all the components are still drawing a base current. If we can turn off the power on these components we lower the current/power consumption even more.
This a bit advanced so I won't go in to details how an NPN Transistor works, but I will explain how to implement it. Checkout the image below to see what the diagram looks like.
Using the 2N2222/MPS2222A transistor, we connect a 1K resistor to the middle leg of the transistor, connect the other end of the resistor to D9 on the Arduino. By putting pin D9 high we turn the switch on, and by putting pin D9 low we turn the switch Off. Next we connect the right leg of the transistor (with the flat part facing you) to the 5V on the bread board and connect the left leg to the 5V in on the SD breakout board.
Note: You might ask why don't we do this for all the components to save even more. Some components need to have power as they need to do things while the Arduino sleep e.g. the RTC needs to wake up the Arduino, and some components take time to start working when power is applied to them e.g. the Humidity/Temperature Sensor. This you find out through trial and error.
You can download the completed power saver version of the sketch from here
On line 39 we add the following line to declare the pin we use to turn the power on and off on the SD breakout board. Next we make digital pin 9 an out put pin and turn it high with the following code
We add these lines in the setup() function on line 45 and 46. Then in the Going_To_Sleep() function we pull digital pin to low to turn of the power to the SD breakout board just before we put the Arduino asleep with this line of code. We put it on line 101
After the Arduino is woken up we add a line of code that will pull pin 9 back to high on line 109 before we call the temp_Humi() function.
Finally we have to reinitialize the SD breakout because we powered it down. We do this in the writeData() function. We do this before we declare the time object with these lines of code;
Making these alterations to your project make it even more energy efficient.
This is a practical application that shows when putting your Arduino to sleep really can have practical applications. This project can run on 4 C cell batteries for approximately 3 to 4 weeks. If you run it without the sleep mode you only get 4 to 7 days out of it.
If you like this project and would like to see more of the same type, please subscribe to my newsletter using the form below or like and follow my Facebook page. This way you get notified when a new post is available. If you have questions or suggestions please email at firstname.lastname@example.org me or leave it in the comments below. Have a great day and see you next time.