亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Arduino Nano模拟指针时钟:DS3231 RTC + 1mA电流表精密木制计时器

组件与物料清单

组件数量备注
Arduino Nano R31主控板
Maxim DS3231M RTC实时时钟模块1±5ppm高精度,I2C接口
1mA 指针式电流表3分别显示时、分、秒
5kΩ 电阻3配合电流表调节PWM输出
10kΩ 电阻2按钮上拉
12mm 轻触开关2时间调节按钮(上/下)

软件与工具

项目简介

这是一个外观精美的木质模拟指针时钟,基于Arduino Nano和三个1mA指针式电流表制作。灵感来源于网络上的类似项目,我增加了秒针显示功能,并添加了启动时全刻度扫描校准功能。

关键提示:由于每个电流表特性略有差异,5kΩ电阻值及PWM输出数值需根据实测调整。代码中的数值针对我的电流表校准,复刻时必须修改对应参数。

接线说明

完整代码

/* Analog Panel Meter - Clock ONLY Mode
 * Instructables Link: https://www.instructables.com/id/Analog-VU-meter-and-Clock-Arduino-Powered/
 * Credits: bildr - DS1307 RTC code https://bildr.org/2011/03/ds1307-arduino/
 *_____________________
 Wiring:
 - USB red wire (5v) to VCC
 - USB black wire to GND
 - Buttons: Left/Down to Digital 2, Right/Up to Digital 3
 - DS1307 RTC: SDA to Analog 4, SCL to Analog 5
 - Left Analog Meter to Digital 5 (PWM)
 - Right Analog Meter to Digital 6 (PWM)
 - Seconds Analog meter to Digital 9 (PWM)
_____________________
 Note: Because all meters are slightly different, the PWM values need to be adjusted based on your design.
 Feel free to use my code, but you will have to change some values because it is set to work specifically with my meters.
 */
#include <Wire.h>
#define DS1307_ADDRESS 0x68
byte zero = 0x00;

int downButton = 2;
int upButton = 3;
int hours = 0;
int minutes = 0;
int seconds = 0;
int lastMinute = 0;
int lastSecond = 0;
int leftMeter = 5;
int rightMeter = 6;
int secMeter = 9;

void setup() {
  Wire.begin();
  Serial.begin(9600);
  pinMode(leftMeter, OUTPUT);
  pinMode(rightMeter, OUTPUT);
  pinMode(secMeter, OUTPUT);
  
  // 启动自检:全刻度扫描
  digitalWrite(leftMeter, HIGH);
  digitalWrite(rightMeter, HIGH);
  digitalWrite(secMeter, HIGH);
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(leftMeter, LOW);
  digitalWrite(rightMeter, LOW);
  digitalWrite(secMeter, LOW);
  digitalWrite(13, LOW);
  delay(1000);
}

void loop() {
  printDate();
  delay(75);

  // 按钮调整时间
  if (digitalRead(downButton) == HIGH) {
    byte second = seconds;
    byte minute = minutes;
    byte hour = hours;
    if (minutes > 0) { --minute; }
    else { minute = 59; if (hours > 0) --hour; else hour = 23; }
    
    Wire.beginTransmission(DS1307_ADDRESS);
    Wire.write(zero);
    Wire.write(decToBcd(second));
    Wire.write(decToBcd(minute));
    Wire.write(decToBcd(hour));
    Wire.write(zero);
    Wire.endTransmission();
  }

  if (digitalRead(upButton) == HIGH) {
    byte second = 0;
    byte minute = minutes;
    byte hour = hours;
    if (minutes < 59) { ++minute; }
    else { minute = 0; if (hours < 23) ++hour; else hour = 0; }
    
    Wire.beginTransmission(DS1307_ADDRESS);
    Wire.write(zero);
    Wire.write(decToBcd(second));
    Wire.write(decToBcd(minute));
    Wire.write(decToBcd(hour));
    Wire.write(zero);
    Wire.endTransmission();
  }
}

byte decToBcd(byte val) {
  return ((val / 10 * 16) + (val % 10));
}

byte bcdToDec(byte val) {
  return ((val / 16 * 10) + (val % 16));
}

void printDate() {
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 7);
  
  seconds = bcdToDec(Wire.read());
  minutes = bcdToDec(Wire.read());
  hours = bcdToDec(Wire.read() & 0b111111); // 24小时制

  // 仅当分钟变化时更新指针,减少抖动
  if (lastMinute != minutes) {
    // 时针PWM查表(需根据实测校准)
    if (hours == 1 || hours == 13) analogWrite(leftMeter, 0);
    else if (hours == 2 || hours == 14) analogWrite(leftMeter, 29);
    else if (hours == 3 || hours == 15) analogWrite(leftMeter, 52);
    else if (hours == 4 || hours == 16) analogWrite(leftMeter, 75);
    else if (hours == 5 || hours == 17) analogWrite(leftMeter, 98);
    else if (hours == 6 || hours == 18) analogWrite(leftMeter, 130);
    else if (hours == 7 || hours == 19) analogWrite(leftMeter, 152);
    else if (hours == 8 || hours == 20) analogWrite(leftMeter, 172);
    else if (hours == 9 || hours == 21) analogWrite(leftMeter, 192);
    else if (hours == 10 || hours == 22) analogWrite(leftMeter, 213);
    else if (hours == 11 || hours == 23) analogWrite(leftMeter, 234);
    else if (hours == 0 || hours == 12) analogWrite(leftMeter, 255);

    // 分针:每分钟约4.75 PWM步进(理想值4.25,视表头特性调整)
    if (minutes * 4.75 < 255) analogWrite(rightMeter, minutes * 4.75);
    else analogWrite(rightMeter, 255);

    // 秒针:每秒4.25 PWM步进
    if (seconds * 4.25 < 255) analogWrite(secMeter, seconds * 4.25);
    else analogWrite(secMeter, 255);

    lastMinute = minutes;
    lastSecond = seconds;
  }
}

原理图

Arduino Nano模拟指针时钟:DS3231 RTC + 1mA电流表精密木制计时器

制作要点总结

制造工艺

  1. Arduino POV 时钟:自制视觉暂留 LED 显示器
  2. DIY Arduino单词时钟 – 极简优雅的实时文字显示
  3. 自制 Arduino 伊斯兰祷告时间实时时钟
  4. 自制大尺寸LED主时钟带闹钟功能 — 12米外清晰可见
  5. Arduino Nano 智能礼服:心率感应 LED 装饰,融合 CrazyCircuits 与 DFRobot 传感器
  6. 模拟指针风格 POV 时钟:Arduino Nano + 17 LED + 霍尔传感器
  7. 自制 FlightGear 飞行模拟升降舵配平轮:Arduino Nano + Python UDP 桥接方案
  8. Arduino Nano + 摇杆控制双步进电机:Visuino 图形化教程
  9. 用 Arduino Pro Mini 与 DS1302 RTC 打造精准七段数码管时钟
  10. 面板仪表:机器界面与控制的高性价比方案
  11. 面板选型指南:数字与模拟方案的深度对比
  12. 面板仪表详解:如何监测与控制工业设备