Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Ретро-часы на индикаторах Numitron с Arduino: просто, надёжно, экономно

Компоненты и материалы

Arduino Nano R3 ×1
Maxim Integrated DS3231M — ±5 ppm, I²C RTC ×1
TPIC6C595 Shift Register (High-Current Driver) ×4
Лампа-индикатор IV9 Numitron (4-разрядный) ×4
Светодиод (для индикации секунд) ×2
Конденсатор 100 нФ (декуплирующий) ×4
Диод 1N4007 — высоковольтный, высокотоковый ×2
Тумблер (Питание / Яркость дисплея) ×1
Резистор 1 кОм (токоограничивающий) ×1

Необходимые инструменты

Программное обеспечение

О проекте

Это руководство проводит через сборку стильных часов на лампах-индикаторах Numitron под управлением Arduino Nano, модуля реального времени DS3231 и сдвиговых регистров TPIC6C595. Результат — низкотемпературный, надёжный дисплей, показывающий время, дату, год и температуру окружающей среды каждые 30 секунд.

Исходная идея взята из этого GitHub-репозитория. При первой сборке я столкнулся с проблемами: сдвиговые регистры 74HC595 перегревались, так как суммарный ток превышал их номинал 70 мА, а программа использовала блокирующие задержки, из-за чего RTC опрашивался только раз в минуту.

Переход на высокотоковые драйверы TPIC6C595 и рефакторинг прошивки на неблокирующий тайминг через millis() позволили часам обновляться в реальном времени, держать индикаторы Numitron холодными и даже предложить энергосберегающий режим с приглушённой индикацией.

Ключевые моменты:

После сборки схемы и загрузки кода просто поместите часы в декоративный корпус. Они станут темой для разговора в любой мастерской или витрине.

Код

Arduino Code (C/C++)

#include <RTClib.h> // RTC с температурой для DS3231
RTC_DS3231 rtc; // экземпляр DS3231
#include <Wire.h> // I2C
#include <TimeLib.h> // функции времени
#include <Time.h> // библиотека времени
#include <DS1307RTC.h> // дополнительная поддержка RTC
#include <SPI.h>

#define led 7
const int latchPin = 13; // latch для TPIC6C595
const int clockPin = 10; // clock
const int dataPin = 11;  // data

unsigned long previousMillis = 0; // последнее обновление дисплея
unsigned long previousMillisDiode = 0; // последнее переключение LED
const long interval = 30000; // интервал обновления дисплея (30 с)
const long intervalDiode = 500; // интервал мигания LED

const int nums[12] = {
  0b10111110, // 0
  0b00000110, // 1
  0b01111010, // 2
  0b01101110, // 3
  0b11000110, // 4
  0b11101100, // 5
  0b11111100, // 6
  0b00001110, // 7
  0b11111110, // 8
  0b11101110, // 9
  0b11001010, // индикатор °C
  0b10111000  // десятичная точка °C
};

// Переменные для разобранных цифр времени и температуры
int hour1, hour2, minute1, minute2, day1, day2, month1, month2, year1, year2, year3, year4, temp1, temp2;
int hourDecimal, minuteDecimal, dayDecimal, monthDecimal, year70, tempDecimal;

void setup() {
  pinMode(led, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  Serial.begin(9600);
  SPI.begin();
  digitalWrite(clockPin, LOW); // clock стартует низким
}

void loop() {
  tmElements_t tm; // структура из библиотеки DS1307RTC
  RTC.read(tm); // чтение текущего времени и температуры
  
  // Разбор цифр
  hourDecimal = tm.Hour / 10;
  hour1 = hourDecimal;
  hour2 = tm.Hour - 10 * hourDecimal;
  minuteDecimal = tm.Minute / 10;
  minute1 = minuteDecimal;
  minute2 = tm.Minute - 10 * minuteDecimal;
  dayDecimal = tm.Day / 10;
  day1 = dayDecimal;
  day2 = tm.Day - 10 * dayDecimal;
  monthDecimal = tm.Month / 10;
  month1 = monthDecimal;
  month2 = tm.Month - 10 * monthDecimal;
  year70 = tm.Year - 30;
  year1 = 2;
  year2 = 0;
  year3 = year70 / 10;
  year4 = year70 - 10 * year3;
  tempDecimal = rtc.getTemperature() / 10;
  temp1 = tempDecimal;
  temp2 = rtc.getTemperature() - 10 * tempDecimal;
  
  // Мигание секундного LED
  if (millis() - previousMillisDiode >= intervalDiode) {
    previousMillisDiode = millis();
    digitalWrite(led, !digitalRead(led));
  }
  
  // Обновление дисплея каждые 30 с
  if (millis() - previousMillis >= interval) {
    previousMillis = millis();
    
    // Очистка дисплея (эффект "дыхания")
    digitalWrite(clockPin, LOW);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    digitalWrite(clockPin, HIGH);
    delay(500);
    
    // Показ даты (месяц/день)
    digitalWrite(clockPin, LOW);
    SPI.transfer(nums[month2]);
    SPI.transfer(nums[month1]);
    SPI.transfer(nums[day2]);
    SPI.transfer(nums[day1]);
    digitalWrite(clockPin, HIGH);
    delay(1500);
    
    // Очистка
    digitalWrite(clockPin, LOW);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    digitalWrite(clockPin, HIGH);
    delay(500);
    
    // Показ года (YY)
    digitalWrite(clockPin, LOW);
    SPI.transfer(nums[year4]);
    SPI.transfer(nums[year3]);
    SPI.transfer(nums[year2]);
    SPI.transfer(nums[year1]);
    digitalWrite(clockPin, HIGH);
    delay(1500);
    
    // Очистка
    digitalWrite(clockPin, LOW);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    digitalWrite(clockPin, HIGH);
    delay(500);
    
    // Показ температуры (°C)
    digitalWrite(clockPin, LOW);
    SPI.transfer(0b10111000); // десятичная точка
    SPI.transfer(0b11001010); // символ °C
    SPI.transfer(nums[temp2]);
    SPI.transfer(nums[temp1]);
    digitalWrite(clockPin, HIGH);
    delay(1500);
    
    // Финальная очистка
    digitalWrite(clockPin, LOW);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    SPI.transfer(0b00000000);
    digitalWrite(clockPin, HIGH);
    delay(500);
  } else {
    // Обычный режим: время (ЧЧ:ММ)
    digitalWrite(clockPin, LOW);
    SPI.transfer(nums[minute2]);
    SPI.transfer(nums[minute1]);
    SPI.transfer(nums[hour2]);
    SPI.transfer(nums[hour1]);
    digitalWrite(clockPin, HIGH);
  }
}

Схемы

Ретро-часы на индикаторах Numitron с Arduino: просто, надёжно, экономно

Производственный процесс

  1. Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
  2. Часы реального времени на Arduino с расчётом времени намаза
  3. Создание пользовательских LED-часов с будильником — видно с 12 метров
  4. Монитор температуры и реальные часы на Arduino Due с TFT-дисплеем 3.2"
  5. Сборка вольтметра на Arduino с дисплеем Nokia 5110 — Пошаговое руководство
  6. MobBob: Самостоятельная сборка Arduino-робота под управлением Android-смартфона
  7. Сборка точного измерительного колеса на Arduino Nano и вращательном энкодере
  8. Веб-управляемый IoT-индикатор на Arduino, Yaler и IFTTT
  9. Arduino Flip Clock на матрице 8×8 LED — DIY проект реального времени
  10. Надёжные будильник на DS1302 RTC и Arduino UNO — сборка и код