Аналоговые часы на Arduino Nano с DS3231 RTC и микроамперметрами — деревянный прецизионный таймер
Компоненты и материалы
| Arduino Nano R3 | ×1 |
| DS3231M (Maxim Integrated) — RTC с I2C, точность ±5 ppm | ×1 |
| Микроамперметр 1 мА (аналоговый) | ×3 |
| Резистор 5 кОм | ×3 |
| Резистор 10 кОм | ×2 |
| Тактильная кнопка 12 мм (SparkFun) | ×2 |
Программное обеспечение
- Arduino IDE
О проекте
Я собрал красивые деревянные аналоговые часы на Arduino Nano с использованием трех микроамперметров (1 мА) в качестве индикаторов. Идея вдохновлена проектом из интернета. Добавлена отображение секунд и режим калибровки: при запуске стрелки пробегают весь шкалу от нуля до максимума.
Поскольку все амперметры немного отличаются, значения резисторов 5 кОм и уровни 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/
*
* Подключение:
* - USB красный (5V) -> VCC
* - USB черный -> GND
* - Кнопки: Левая/Вниз -> Digital 2, Правая/Вверх -> Digital 3
* - DS1307 RTC: SDA -> A4, SCL -> A5
* - Левый амперметр (часы) -> Digital 5 (PWM)
* - Правый амперметр (минуты) -> Digital 6 (PWM)
* - Секундный амперметр -> Digital 9 (PWM)
*
* Примечание: Все приборы немного отличаются, PWM значения нужно подстроить.
* Вы можете использовать мой код, но измените значения под свои измерители.
*/
#include "Wire.h"
#define DS1307_ADDRESS 0x68
byte zero = 0x00;
int downButton = 2;
int upButton = 3;
int hours = 0, minutes = 0, seconds = 0;
int lastMinute = 0, 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, minute = minutes, hour = hours;
if (minute > 0) --minute;
else { minute = 59; if (hour > 0) --hour; else hour = 23; }
writeTimeToRTC(second, minute, hour);
}
if (digitalRead(upButton) == HIGH) {
byte second = 0, minute = minutes, hour = hours;
if (minute < 59) ++minute;
else { minute = 0; if (hour < 23) ++hour; else hour = 0; }
writeTimeToRTC(second, minute, hour);
}
}
void writeTimeToRTC(byte second, byte minute, byte hour) {
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-часовой формат
// Вывод в Serial Monitor (раскомментируйте для отладки)
// Serial.print(hours); Serial.print(":"); Serial.println(minutes);
// Уровни PWM для каждого часа (НАСТРОЙТЕ ПОД СВОИ ПРИБОРЫ!)
if (lastMinute != minutes) {
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);
// Минуты: увеличение PWM на 4.75 каждую минуту (подстройте!)
if (minutes * 4.75 < 255) analogWrite(rightMeter, minutes * 4.75);
else analogWrite(rightMeter, 255);
lastMinute = minutes;
// Секунды: 4.25 на секунду
if (seconds * 4.25 < 255) analogWrite(secMeter, seconds * 4.25);
else analogWrite(secMeter, 255);
lastSecond = seconds;
}
}
Схема подключения

Производственный процесс
- Arduino POV-часы: сборка дисплея на эффекте сохранения образа
- Слово-часы (Word Clock) на Arduino — DIY-часы с текстовой индикацией времени
- Часы реального времени на Arduino с расчётом времени намаза
- Создание пользовательских LED-часов с будильником — видно с 12 метров
- Набор Arduino Nano: CrazyCircuits, датчики DFRobot и инструменты — создавайте проекты с уверенностью
- Аналоговые POV-часы на Arduino Nano: персистенция зрения с 17 светодиодами
- Компактное руль-триммер для FlightGear на Arduino Nano
- Панельные измерительные приборы: экономичное решение для интерфейса и управления станками
- Выбор панели: цифровые или аналоговые измерительные приборы?
- Панельные измерительные приборы: как они мониторят и контролируют промышленное оборудование