/* Linear Clock driver Written by Sandy Noble ([email protected]) This version 8th Jan 2011 This uses the AFMotor library from Adafruit, because I used an Adafruit Motorshield, and I think Adafruit are the bomb. Make sure you use a version of the libraries from after 7th Jan 2011, because there's a little fix in them that is important to this code. This should be fairly simple self-explanatory code. */ #include #include// These set up the motors. The values here depend on how they've been wired up. AF_Stepper minuteHand(20, 1); // minutes int const minutesIncrement = BACKWARD; int const minutesDecrement = FORWARD; AF_Stepper hourHand(20, 2); // hours int const hoursIncrement = FORWARD; int const hoursDecrement = BACKWARD; int const stepType = DOUBLE; int const motorRPM = 150; int second=0, minute=0, hour=0; // declare time variables // Minutes setup int startMinutePos = 0; // current minute position. This gets updated all the time. float currentMinutePos = startMinutePos; // the current position of the indicators. This only gets updated when the hands move int displayMinutePos = startMinutePos; // Hours setup int startHourPos = 0; float currentHourPos = startHourPos; int displayHourPos = startHourPos; // These are the actual time, in seconds minutes and hours. // doTick() writes these values, and renderTime() reads them. int currentSeconds = 0; int currentMinutes = 50; int currentHours = 11; int const millisPerSecond = 200; int const stepsPerClock = 592; float const stepsPerMinute = stepsPerClock/60.0; float const stepsPerHourMinute = stepsPerClock/720.0; float const stepsPerHour = stepsPerClock/12.0; void setup() { Serial.begin(9600); // set up Serial library at 9600 bps Serial.println("LINEAR CLOCK!"); hourHand.setSpeed(motorRPM); // 10 rpm minuteHand.setSpeed(motorRPM); // 10 rpm } void loop() { static unsigned long lastTick = 0; // set up a local variable to hold the last time we moved forward one second // (static variables are initialized once and keep their values between function calls) // move forward one second every 1000 milliseconds unsigned long time = millis(); unsigned long sinceLastTick = time - lastTick; if (sinceLastTick >=millisPerSecond) { unsigned int secondsMissed = sinceLastTick / millisPerSecond; lastTick = millis(); for (int i = 0; i < secondsMissed; i++) { doTick(); } } renderTime(); } void doTick() { currentSeconds++; if (currentSeconds > 59) { currentSeconds = 0; currentMinutes++; if (currentMinutes > 59) { currentMinutes = 0; currentHours++; if (currentHours > 11) { currentHours = 0; } } } Serial.print(millis()); Serial.print(" - tick!"); Serial.print(currentHours); Serial.print(":"); Serial.print(currentMinutes); Serial.print(":"); Serial.println(currentSeconds); } void renderTime() { setTime(currentHours, currentMinutes); } void setTime(int hour, int minute) { setHour(hour, minute); setMinute(minute); } void setHour(int hour, int minute) { // work out the new position and set it globally eg time 4:25. // first hours // eg 0.2055 * 4 * 60 = 49.333 float justHours = stepsPerHourMinute * hour * 60; // eg 0.2055 * 25 = 5.13888 float justMinutes = stepsPerHourMinute * minute; // stick em together: position is 54.472 (4:25) currentHourPos = justHours + justMinutes; // round to integer // eg 54 int newPos = currentHourPos; // save the previous actual position so we can check if the hands need moving // eg 52 int lastPos = displayHourPos; // now see if the hand position needs to change // eg 54 - 52 = 2 int stepsToChange = newPos - lastPos; if (stepsToChange != 0) { Serial.print("sethour:"); Serial.println(hour); // update the global variable displayHourPos = newPos; changeHours(stepsToChange); } } void changeHours(int steps) { Serial.print("Incrementing hours position:"); Serial.println(steps); // make it positive int absSteps = abs(steps); if (steps < 0) { // if it's negative, then DECREMENT if (absSteps >= 1) { // only step if it's a full step hourHand.step(absSteps, hoursDecrement, stepType); } } else if (steps > 0) { // if it's positive then INCREMENT if (absSteps >= 1) { // only step if it's a full step hourHand.step(absSteps, hoursIncrement, stepType); } } Serial.print("Actual current hour position:"); Serial.println(displayHourPos); hourHand.release(); } void setMinute(int minute) { // work out the new position and set it globally // eg 2.467 * 25 = 61.675 currentMinutePos = stepsPerMinute * minute; // round to integer // eg 61 int newPos = currentMinutePos; // save the previous actual position so we can check if the hands need moving // eg 59 int lastPos = displayMinutePos; // now see if the hand position needs to change // eg 61 - 59 = 2 int stepsToChange = newPos - lastPos; if (stepsToChange != 0) { Serial.print("setmin:"); Serial.println(minute); // update the global variable displayMinutePos = newPos; changeMinutes(stepsToChange); } } void changeMinutes(int steps) { Serial.print("Incrementing minutes position:"); Serial.println(steps); // make it positive int absSteps = abs(steps); if (steps < 0) { // if it's negative, then DECREMENT if (absSteps >= 1) { // only step if it's a full step minuteHand.step(absSteps, minutesDecrement, stepType); } } else if (steps > 0) { // if it's positive then INCREMENT if (absSteps >= 1) { // only step if it's a full step minuteHand.step(absSteps, minutesIncrement, stepType); } } Serial.print("Actual current minute position:"); Serial.println(displayMinutePos); minuteHand.release(); }
高品质LED产品是怎样炼成的
时间:2026-03-14
LED电源的分类和选择
时间:2026-03-14
激光二极管模拟器的试验
时间:2026-03-14
高压LED芯片对比分析
时间:2026-03-14
led数码管结构及其检测
时间:2026-03-14
oled与tft的区别对比
时间:2026-03-14
直下式LED背光源方案
时间:2026-03-14
LED驻波指示器方案
时间:2026-03-14
大尺寸TFT-LCD的LED背光技术
时间:2026-03-14
巧用废旧塑料电筒做高亮LED电筒
时间:2026-03-14
电阻的标称阻值和允许偏差
时间:2026-03-05
变压器并列运行的条件浅析
时间:2026-03-06
玻璃釉电容器的结构与特点
时间:2026-03-05
晶体三极管放大电路的非线形失真及其解决办...
时间:2026-03-07
石英灯电子变压器电路原理
时间:2026-03-06
旋转变压器原理与应用知识
时间:2026-03-06
关于STM32WL LSE 添加反馈电阻后无法起振的...
时间:2026-03-05
贴片电阻的阻值识别方法
时间:2026-03-05
可调电阻怎么接线
时间:2026-03-05
压敏电阻有正负极吗
时间:2026-03-05