I am a mechanical guy looking to expand my electronics skills. I would like to make a simple digital watch mainly for academic fun. Right now I am running into endless issues due to my inexperience. My plan currently is to use an ATTINY 84 linked to a DS3231 TXCO to keep time with lower power consumption. The display will be a 7-sEGMENT LED display. I am going for something close to this: https://555dreams.blogspot.com/2018/10/creating-dip-attiny85-watch-with-ds3231.html I want the time to show when you press a small button as a series of digit flashed sequentially. I.E. "0...9...4...5" on for one second, off half a second. My main problem is that I have found a method to brute force the problem that works. However I know there has to be a better way, but I don't have the knowledge to figure it out on my own. I have the code working here on Wokwi Simulator using an Arduino Uno and a DS1307 RTC Module: https://wokwi.com/arduino/projects/315723199727796802 In the code I have only coded one single minute of time, where it reads the RTC time as a variable and performs some basic logic to give outputs to the necessary segments. I would need to write out a set of pin logic commands for every single minute of the day for this setup to work. The code in the simulation only works when you press the button within the 4:01pm minute, it work exactly as I want though. I would love suggestions for streamlining with special emphasis on reducing required memory in order to fit this onto smaller ATTINY platforms later.
2 Answers
I was able to get a workable solution to the first part of my problem from another forum: https://wokwi.com/arduino/projects/315745322971169346 Thanks everyone!
Below is the finished code that I was looking for. So far I have only tested it in Wokwi Simulator but it works when the user presses a button the display flashes out each digit of the current 12 hour time. I presented this as an answer because the original problem I asked for a solution to was that I was trying to brute force displaying the time as collection of variables and assigning led outputs manually. The use of a matrix and a better understanding of the no.time() functions allowed me to greatly streamline my code. Thank you very much for everyone's' help!
#include "RTClib.h"
RTC_DS1307 rtc;
const int buttonPin = 9;
int buttonState = 0;
int8_t pinSegA = 6;
int8_t pinSegB = 7;
int8_t pinSegC = 8;
int8_t pinSegD = 2;
int8_t pinSegE = 3;
int8_t pinSegF = 5;
int8_t pinSegG = 4;
// Segment a b c d e f g // Digit
boolean digits [10] [7] = {1, 1, 1, 1, 1, 1, 0, // 0
0, 1, 1, 0, 0, 0, 0, // 1
1, 1, 0, 1, 1, 0, 1, // 2
1, 1, 1, 1, 0, 0, 1, // 3
0, 1, 1, 0, 0, 1, 1, // 4
1, 0, 1, 1, 0, 1, 1, // 5
1, 0, 1, 1, 1, 1, 1, // 6
1, 1, 1, 0, 0, 0, 0, // 7
1, 1, 1, 1, 1, 1, 1, // 8
1, 1, 1, 0, 0, 1, 1, }; // 9
void setup () {
if (! rtc.begin()) {2;
abort();
}
pinMode (pinSegA, OUTPUT);
pinMode (pinSegB, OUTPUT);
pinMode (pinSegC, OUTPUT);
pinMode (pinSegD, OUTPUT);
pinMode (pinSegE, OUTPUT);
pinMode (pinSegF, OUTPUT);
pinMode (pinSegG, OUTPUT);
pinMode(buttonPin, INPUT);
}
void displayDigit(uint8_t digit)
{
digitalWrite(pinSegA, digits[digit][0]);
digitalWrite(pinSegB, digits[digit][1]);
digitalWrite(pinSegC, digits[digit][2]);
digitalWrite(pinSegD, digits[digit][3]);
digitalWrite(pinSegE, digits[digit][4]);
digitalWrite(pinSegF, digits[digit][5]);
digitalWrite(pinSegG, digits[digit][6]);
delay(1000);
digitalWrite(pinSegA, LOW);
digitalWrite(pinSegB, LOW);
digitalWrite(pinSegC, LOW);
digitalWrite(pinSegD, LOW);
digitalWrite(pinSegE, LOW);
digitalWrite(pinSegF, LOW);
digitalWrite(pinSegG, LOW);
}
void loop () {
DateTime now = rtc.now();
int minutes = now.minute();
int tens = minutes / 10;
int ones = minutes % 10;
int hours = now.hour();
int tenss = hours / 10;
int oness = hours % 10;
int hoursss = hours - 12;
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH)
{
if (hours >= 12)
{
displayDigit(hoursss);
}
else if (hours < 12)
{
displayDigit(tenss);
delay(250);
displayDigit(oness);
}
delay(250);
digitalWrite(pinSegG, HIGH);
delay(500);
digitalWrite(pinSegG, LOW);
delay(250);
displayDigit(tens);
delay(250);
displayDigit(ones);
delay(250);
}
}
-
1\$\begingroup\$ Austin Fox - Hi, Thanks for coming back with the answer to your question. In order to mark the topic as solved, please "accept" your answer (click the "tick mark" next to your answer, to turn it green). Then it is shown as having an accepted answer in various lists, and we don't get nagged for it being a question with an unaccepted answer. Note that you must wait 48 hours after you asked the question before you can accept your own answer. So please come back in a couple of days to accept it. Thanks! \$\endgroup\$– SamGibson ♦Commented Nov 21, 2021 at 18:46
You should use the SevSeg library, it will make your life much easier.
I did an example for your case, please have a look here.
I have left some print()'s to illustrate the results, but do remove them if you are concerned about memory usage.
Serial.print(now.minute()%10);
... does that give you any ideas? \$\endgroup\$