Second Arduino Clock
Second Arduino Clock
Updated version of the Second Arduino Clock Adjustable with two buttons
Here is a clock with hours, minutes and seconds
2 stepper motors, driven by an arduino nano and an RTC for accuracy.
It includes two buttons to set up the hands at the right time
See it here:
The build video:
Clock and prototype:
All the parts are easy to find on Amazon, Ebay and others.
For the wiring, look for schematics.pdf
Here is the arduino code:
/*
Jacques favre:
drive 2 stepper motors to power a clock using a RTC for acuracy
2 buttons to adjust time
1 button: move seconds
other button: move hours and minutes
2 buttons: move hours and minutes back
Including work from:
# http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
# https://learn.adafruit.com/adafruit-arduino-lesson-16-stepper-motors/arduino-code
# Adafruit RTClib [![Build Status](https://travis-ci.com/adafruit/RTClib.svg?branch=master)](https://travis-ci.com/adafruit/RTClib)
This is a fork of JeeLab's fantastic real time clock library for Arduino.
For details on using this library with an RTC module like the DS1307, PCF8523, or DS3231, see the guide at: https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/overview
Works great with Adafruit RTC breakouts:
- [DS3231 Precision RTC](https://www.adafruit.com/product/3013)
- [PCF8523 RTC](https://www.adafruit.com/product/3295)
- [DS1307 RTC](https://www.adafruit.com/product/3296)
To install, use the Arduino Library Manager to search for "RTClib", find "RTClib by Adafruit" and install the library.
Please note that dayOfTheWeek() ranges from 0 to 6 inclusive with 0 being 'Sunday'.
I use unixtime from the RTC with an interval of 1 second
Every 1 second ask stepper motor to move x steps(seconds)
Every 1 second ask stepper motorB to move x steps(hour and minutes)
And blink the onboard led
Drive a stepper motor to power a clock
Using kuman small stepper motor 5V 1/64 gearing and provided driver
For the second hand:
The exact gearing is 1/64
with 32 steps at motor, that is 2048 steps at shaft revolution, divided by 60 for 1 second motion (6 degree)
2048 x 1/60 = 34.133 steps/second
The exact move would be 34.133333 steps per second
So move 34 steps, keep track of reminder, and add 1 step when remainder bigger that 1
Print info to console to keep track of progress
Minute and hour motor calculation
Same idea exept, ration 2:1 to minute, 1:6 to hour
That gives the 1:12 between minute and hour
For the minute:(the "second" formula / 120)(60 second in 1 minute, but ratio 2:1, so 120 )
2048 x 1/60 x 1/120 = 0.284444 steps/second
So move 0 steps, keep track of reminder, and add 1 step when remainder bigger that 1, move a step
Print info to console to keep track of progress
The minute hand will move every 4 seconds or sometime after 3 seconds
2 buttons to set time:
button 1 to move seconds
button 2 to move hours/minutes forward
both buttons to move hours/minutes back
*/
//FOR RTC
//Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include
#include "RTClib.h"
RTC_DS3231 rtc;
//FOR stepper
#include
// constants won't change. Used here to set a pin number:
const int ledPin = LED_BUILTIN;// the number of the LED pin/built in led
//2 button to adjust time
const int button1pin = 7; // the number of the pushbutton pin, one for second
const int button2pin = 8; // the number of the pushbutton pin, one four minutes and hours
// 32 step motor
// second motor
Stepper motor(32,9,11,10,12);
// hour and minute motor
Stepper motorB(32,3,5,4,6);
//and variable that will change
int ledState = LOW; // ledState used to set the LED
//int button1State = 0; // variable for reading the pushbutton status
//int button2State = 0; // variable for reading the pushbutton status
unsigned long previousSECOND = 0; // will store last time LED was updated
// constants won't change:
const long interval = 1; // interval at which to blink (1 seconds)
//For seconds
const float absoluteSteps = 512.000000/15; //2048 x 1/60 = 512/15 = 34.133333 steps/second
const float extraStep = absoluteSteps - 34; // 0.133333 leftover remainder
// variables
float totExtraStep; // to keep track of decimal part of steps
int totSteps; //adding all steps
int seconds; //display seconds counter
// for hours and minutes
//2048 x 1/60 x 1/120 = 64/225 = 0.284444 steps/second
//neeed take ratio of gears, minute hand to motor ratio 2 to 1
float absoluteStepsB = 64.000000/225; //0.284444 steps/second, calculated steps per second
const float extraStepB = absoluteStepsB - 0; // 0.284444 leftover remainder
// variables
float totExtraStepB; // to keep track of decimal part of steps
int totStepsB; //adding all steps
// to print time to console
unsigned long time;
//SETUP****************************************
void setup () {
// set the digital pin for LED output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
//pinMode(buttonPin, INPUT);
//for sec
pinMode(button1pin, INPUT_PULLUP);
//pinMode(buttonPin, INPUT);
//for min and hour
pinMode(button2pin, INPUT_PULLUP);
#ifndef ESP8266
while (!Serial); // for Leonardo/Micro/Zero
#endif
//set motor speed
motor.setSpeed(450);
motorB.setSpeed(450);
Serial.begin(9600);//start print to monitor
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, lets set the time!");
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
}
//LOOP*****************************************
void loop () {
// here is where you'd put code that needs to be running all the time.
//Creat RTC object
DateTime now = rtc.now();
//load current second
int steps; //acual steps as integer for the seconds
int stepsB; //acual steps as integer for the minutes and hours
// now the buttons
// constant motion
int i=0; // count how long button is pressed
// check if the pushbutton is pressed. If it is, pin 7 to ground, the buttonState is LOW:
if (digitalRead(button1pin) == LOW & digitalRead(button2pin) == HIGH) {
motor.step(-2); //second move forward
i++;
Serial.print("Total i: ");
Serial.println(i); //prints adjusted steps
}
if (digitalRead(button1pin) == HIGH & digitalRead(button2pin) == LOW) {
motorB.step(-1); //hour,minutes move forward
}
else if (digitalRead(button1pin) == LOW & digitalRead(button2pin) == LOW) {
motorB.step(1); //2 buttons press: hour,minutes move back
}
else { //work as a clock
// check to see if it's time to move hands; that is, if the difference
// between the current time and last time you moved the hand(s) is bigger than
// the interval.
unsigned long currentSECOND = now.unixtime();
if (currentSECOND - previousSECOND >= interval) {
//print time to console
Serial.print("Time: ");
time = now.unixtime();
Serial.println(time); //prints time since program started
seconds++; // count the seconds at each time "if function" is true, check for drifting/debuging?
previousSECOND = currentSECOND;
//And do something
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
//And activate the stepper motors
//FOR THE SECOND MOTOR***********************************
steps = int(absoluteSteps);//convert float steps to integer steps, loop alway start with 34.133
totExtraStep = totExtraStep + extraStep;// and keep track of the decimal part of steps
//and IF the decimal gets bigger than 1, add a step to steps and substratc 1 to totExtraSteps
if (totExtraStep > 1){
totExtraStep = totExtraStep - 1;
steps = steps + 1;
}
totSteps = totSteps + steps;//for display
//move x steps, 34 or 35
motor.step(-steps); //seconds motor!! - to move in correct direction!!
//Serial.print("INT Steps seconds: ");
///Serial.println(steps); //prints integer steps
//Serial.print("Tot Extra Steps: ");
//Serial.println(totExtraStep); //prints adjusted steps
Serial.print("Total Steps seconds: ");
Serial.println(totSteps); //prints adjusted steps
Serial.print("Steps seconds/2048: ");
Serial.println(totSteps/2048); //prints actual minutes for every 60 seconds
Serial.print("Total seconds counter: ");
Serial.println(seconds); //prints adjusted steps
//FOR THE MINUTES************************************
stepsB = int(absoluteStepsB);//convert float steps to integer steps, loop actually start with 0 (0.284....)
totExtraStepB = totExtraStepB + extraStepB;// and keep track of the decimal part of steps
//and IF the decimal gets bigger than 1, add a step to steps and substratc 1 to totExtraSteps
if (totExtraStepB > 1){
totExtraStepB = totExtraStepB - 1;
stepsB = stepsB + 1;
}
//move x steps, 0 or 1
motorB.step(-stepsB);// move minute, hour stepper, backwards because of gears
totStepsB = totStepsB + stepsB;//for display
//Serial.print("Steps to do: ");
//Serial.println(absoluteStepsB,6); //prints float steps to do minutes
//Serial.print("Adding Steps to do: ");
//Serial.println(absoluteStepsB); //prints float steps to do
//Serial.print("INT Steps minutes: ");
//Serial.println(stepsB); //prints integer steps
//Serial.print("Tot Extra Steps: ");
//Serial.println(totExtraStepB,6); //prints adjusted steps
Serial.print("Total Steps minutes: ");
Serial.println(totStepsB); //prints adjusted steps
}//end if intervall over
} //end of: else { work as a clock...
}//end of loop
Printed in PLA, 0.2mm layer
Date published | 02/01/2020 |
Sin apoyo | YES |