Holiday is always a good reason to make something cool. This time I wanted to play with Pro Minis and an RTC module. Read what I did below.
It all started with an idea of a small mysterious box. I liked the idea because I’ve never worked with 7 -segment displays and RTC modules. But the most exciting stuff for me was an Arduino Pro Mini.
How does it Work?Pro mini sleeps until it gets an analog signal more than 50. This means that the box is opened. Now it displays the number of days from an important date. For example, my code counts how many days have passed since last Christmas. If today is a special day then Arduino prints a complimentary text.
I bought enough Pro Minis to make sure I would finish my project even if I burn some of them out. Luckily, I broke only one. Also I got a USB TTL converter based on a PL2302HX chip. My cheap converter didn’t have a RESET pin so I needed to reset my pro mini manually every time I program it. I recommend to buy more expensive versions with DTR or RESET pins. Believe me, this little feature will save you a lot of nerves. When I received a 7-segment 4-digit display I was surprised with the number of pins on it. You need to reserve 11 pins for the display to work and 1 extra pin for the decimal. There is a better version by SparkFun which has an ATMEGA 328 on it so it needs only 4 pins to communicate with your main board. And you can program the display itself as a normal Arduino because it is fully compatible with the Arduino IDE. Other parts I used: a photoresistor, 1800 mAh battery, some connectors, wires and a 10K resistor.
I wanted my box to stay alive for a long time so I did a research on power consumption of Arduino boards. There is a lot of information available about this topic over the WEB. I used this great article (link) in my project. To save energy I cut the power LED out of my Pro Mini and used the RocketScream Low Power library (download here). You can see that 3.3 V Pro Mini with the listed modifications needs only 0.0541 ma which is 87 times less than a normal Pro Mini and 878 times less than an Arduino Uno!
The picture below helped me a lot with wiring my display. I didn’t use any resistors to connect the display to the Arduino. If you use a Pro Mini or Nano for your project you will be able to solder display pins directly to the board. For me it was surprising that analog inputs on every Arduino board can be used as outputs. Unless you have a Mega of a Due you will have to use analog pins because 12 (11) of 14 digital pins are required for a display, 3 for an RTC (don’t forget about GND) and 1 analog pin for a photoresistor (also GND and VCC). You will need this library to make the display work.
Final appearance:
When I assembled my scheme for the first time it didn’t work. A problem was with the wrong data from a photoresistor. Later I found out that I should had connected the analog port which a photoresistor is plugged into to the ground via a 10K resistor. RTC modules can be powered from an Arduino or from a small onboard battery. Note that if you power your RTC from an external power source such as a Pro Mini time and date will be erased in case of powering off. Also don’t forget to connect GND when power comes from a battery.
Here I’m going to explain the most interesting parts of my code.
DS1302 (library) sends a string comprising 3 numbers separated with dots. For my project I need to get each of this numbers as an integer.
Getting the data ready to be processed:
date1=(rtc.getDateStr());//Get date
date1.replace ("."," "); //Delete dots
day2=date1;
month2=date1;
year2=date1;
day2.remove(2); //Separate day, month and year
month2.remove(5);
month2.remove (0,3);
year2.remove (0,6);
day1=day2.toInt(); //Convert to integer
month1=month2.toInt()-1; //Subtract 1 for the easier later calculations
year1=year2.toInt();
Then there is a part of the code that checks if today is a special day or not. My code contains more than 30 events but here I’m going to show you only one event.
Events:
if (month1+1 == 2 && day1 == 17) {event=1; state=1;} //Sudden kindness day
if (event == 1) {
for (int i=0; i<400; i++) {disp.write ("show");}
for (int i=0; i<400; i++) {disp.write ("sddn");}
for (int i=0; i<400; i++) {disp.write ("cndr");}
}
//Display will show: "show sddn cndr" which stands for "show sudden candor"
If it is not a special day then it will count how many days have passed since a chosen date.
Counting the number of days:
//Count how many days are there in months of leap years
if ((year1 == 2016 || year1 == 2020 || year1== 2024
|| year1 == 2028 || year1 == 2032 || year1 == 2036 || year1 == 2040))
{
if (month1 == 1) {dur=31;} //If month1 == 1 then dur will be 0
if (month1 == 2) {dur=60;}
if (month1 == 3) {dur=91;}
if (month1 == 4) {dur=121;}
if (month1 == 5) {dur=152;}
if (month1 == 6) {dur=182;}
if (month1 == 7) {dur=213;}
if (month1 == 8) {dur=244;}
if (month1 == 9) {dur=274;}
if (month1 == 10) {dur=305;}
if (month1 == 11) {dur=335;}
//Total number of days (I added 7 because I want to count from the 25th of December, 2015)
year1= (year1-2016)*366 ;
num = 7 + day1 + dur + year1;
}
else
//And in normal years
{
if (month1 == 1) {dur=31;}
if (month1 == 2) {dur=59;}
if (month1 == 3) {dur=90;}
if (month1 == 4) {dur=120;}
if (month1 == 5) {dur=151;}
if (month1 == 6) {dur=181;}
if (month1 == 7) {dur=214;}
if (month1 == 8) {dur=243;}
if (month1 == 9) {dur=273;}
if (month1 == 10) {dur=304;}
if (month1 == 11) {dur=334;}
year1= (year1-2016)*365 ;
num = 7 + day1 + dur + year1;
}
if (state == 0) {for (int i=0; i<200; i++) {disp.write (num);}}
After the number/text is shown it’s necessary to reset variables and turn off a screen for a short time to let a photoresistor read the data correctly. If you don’t switch the display off the light will reflect inside a box and your photoresistor will give you a value that is too high. You can fix this problem by changing a condition of putting a board into the sleep mode but I recommend you to follow my instructions.
Reseting valuables and turning off the display:
state=0
event=0;
dur=0;
digitalWrite (5,LOW);
digitalWrite (8,LOW);
digitalWrite (9,LOW);
digitalWrite (A1,LOW);
digitalWrite (6,LOW);
digitalWrite (A2,LOW);
digitalWrite (11,LOW);
digitalWrite (13,LOW);
digitalWrite (A0,LOW);
digitalWrite (7,LOW);
digitalWrite (10,LOW);
delay (100); //Depends on your display. If it turns off fast - make this value smaller
String date1;
int day1;
int month1;
int year1;
int dur;
int t;
int event;
int state;
String day2;
String month2;
String year2;
int num=0;
#include <SevenSeg.h>
#include <DS1302.h>
#include <LowPower.h>
// Init the DS1302
DS1302 rtc(4, 3, 2);
SevenSeg disp(6,A2,11,13,A0,7,10);
const int numOfDigits=4;
int digitPins[numOfDigits]={5,8,9,A1};
void setup()
{
disp.setDigitPins (numOfDigits,digitPins);
disp.setCommonCathode ();
disp.setDPPin (12);
}
void loop() {
if (analogRead (A4) >50) {
date1=(rtc.getDateStr());//get date
date1.replace ("."," "); //delete dots
day2=date1;
month2=date1;
year2=date1;
day2.remove(2); //separate day, month and year
month2.remove(5);
month2.remove (0,3);
year2.remove (0,6);
day1=day2.toInt(); //convert to integer
month1=month2.toInt()-1;
year1=year2.toInt();
if (month1+1 == 2 && day1 == 17) {event=1; state=1;} //Sudden kindness
//count numbers of days in months of leap years
if ((year1 == 2016 || year1 == 2020 || year1== 2024
|| year1 == 2028 || year1 == 2032 || year1 == 2036 || year1 == 2040))
{
if (month1 == 1) {dur=31;}
if (month1 == 2) {dur=60;}
if (month1 == 3) {dur=91;}
if (month1 == 4) {dur=121;}
if (month1 == 5) {dur=152;}
if (month1 == 6) {dur=182;}
if (month1 == 7) {dur=213;}
if (month1 == 8) {dur=244;}
if (month1 == 9) {dur=274;}
if (month1 == 10) {dur=305;}
if (month1 == 11) {dur=335;}
year1= (year1-2016)*366 ; //total number of days (I added 7 because I want to count from the 25th of December, 2015)
num = 7 + day1 + dur + year1;
}
else
//and in normal years
{
if (month1 == 1) {dur=31;}
if (month1 == 2) {dur=59;}
if (month1 == 3) {dur=90;}
if (month1 == 4) {dur=120;}
if (month1 == 5) {dur=151;}
if (month1 == 6) {dur=181;}
if (month1 == 7) {dur=214;}
if (month1 == 8) {dur=243;}
if (month1 == 9) {dur=273;}
if (month1 == 10) {dur=304;}
if (month1 == 11) {dur=334;}
year1= (year1-2016)*365 ;
num = 7 + day1 + dur + year1;
}
if (event == 1) {
for (int i=0; i<400; i++) {disp.write ("show");}
for (int i=0; i<400; i++) {disp.write ("sddn");}
for (int i=0; i<400; i++) {disp.write ("cndr");}
}
if (state == 0) {for (int i=0; i<200; i++) {disp.write (num);}}
state=0;
event=0;
dur=0;
digitalWrite (5,LOW);
digitalWrite (8,LOW);
digitalWrite (9,LOW);
digitalWrite (A1,LOW);
<br/>
digitalWrite (6,LOW);
digitalWrite (A2,LOW);
digitalWrite (11,LOW);
digitalWrite (13,LOW);
digitalWrite (A0,LOW);
digitalWrite (7,LOW);
digitalWrite (10,LOW);
delay (100);
}
else {LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);}
}
Hope this article was interesting for you. If there are any questions or suggestions concerning the project text me using the Get in touch page.
Comments