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

Часы на 7-сегментном дисплее с Arduino Nano, DS3231 RTC и автояркостью от LDR

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

Arduino Nano R3 (подходит Uno или Elegoo Uno) ×1
Adafruit 7-Segment Backpack — 1.2″ Tall Digits ×1
Adafruit 1.2″ 4-Digit 7-Segment Display w/I2C Backpack — Green ×1
Adafruit DS3231 (или DS1307) ×1
Резистор 100 кОм ×1
Фоторезистор (LDR) ×1
Макетная плата ×1
Перемычки (10-14 шт.) ×1
Элемент питания CR1220 (для RTC) ×1

Приложения и сервисы

О проекте

Введение

В эпоху смартфонов и умных часов обычные Arduino-часы могут показаться скучными. Но этот проект создает автономные часы без Wi-Fi — идеально для спальни, где нежелательны беспроводные сети.

История

Друг отказался от устройств с Wi-Fi в спальне, поэтому я собрал часы на отдельном RTC-модуле.

Выбор компонентов

Adafruit предлагает много вариантов: дешевый DS1307 и более точный DS3231. Оба подходят. Для DS1307 обратите внимание на распиновку и отключите функцию отображения температуры (закомментируйте displayTemp() в loop()). DS3231 умеет измерять температуру, чего у DS1307 нет.

Адаптация скетча

Базовый скетч взят из сообщества, переработан, сохранены чешские комментарии с добавлением английских. Выбран 7-сегментный индикатор максимального размера для лучшей читаемости.

Инициализация часов

Если есть батарея CR1220, настройте время по краткому руководству Adafruit: время берется с компьютера при загрузке скетча.

Функции

При ошибке чтения температуры на дисплее показывается BEEF (см. код).

Расширение

Планируется добавить будильник и, возможно, Bluetooth-модуль с Blynk.

Обновление 01.02.2019

Перенос с макетной платы на монтажную завершен. Фото в галерее. Доступен обновленный код v1.1 и исправленная схема в Fritzing.

Код

MyClock v1.0 (C/C++)

// MyClock v1.0
// Ingo Lohs
// Hardware: tested with Arduino Uno and Arduino Nano (ATmega328P [Old Bootloader]) by using Arduino IDE v1.8.8
/* Theory for the Matrix ht16k33 ... */
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

#define DS3231_I2C_ADDRESS 0x68
int ldr_sensor = A0;
int ldr_value = 0;
int brightness_matrix;
int threshold_brightness = 400;
int blinkrate_value = 0;
int delay_matrix_time = 20;
int delay_matrix_temp = 2000;
int blinky_dot = 2;
Adafruit_7segment matrix = Adafruit_7segment();

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

void setup() {
  Serial.begin(9600);
  Wire.begin();
  matrix.begin(0x70);
}

void loop() {
  lightBrightness();
  matrixBlinkrate();
  displayTime();
  displayTemp();
}

void lightBrightness() {
  ldr_value = analogRead(ldr_sensor);
  Serial.print("LDR: "); Serial.println(ldr_value);
  if (ldr_value <= threshold_brightness) {
    brightness_matrix = 0; // ярко днем
  } else {
    brightness_matrix = 15; // темно ночью
  }
}

void matrixBlinkrate() {
  matrix.blinkRate(blinkrate_value);
}

void displayTime(){
  matrix.setBrightness(brightness_matrix);
  matrix.clear();
  for (uint16_t i = 0; i < delay_matrix_time; i++) {
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    getDateDs3231(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    byte se = second, mi = minute, ho = hour, we = dayOfWeek, dm = dayOfMonth, mo = month, ye = year;

    // Переход на летнее время - последнее воскресенье марта в 2:00
    if ((dayOfWeek == 7) && (dayOfMonth >= 25) && (month == 3) && (hour == 2)) {
      setDS3231time(se, mi, 3, we, dm, mo, ye);
    }
    // Переход на зимнее время
    if ((dayOfWeek == 7) && (dayOfMonth >= 25) && (month == 10) && (hour == 1) && (year != 1)) {
      setDS3231time(se, mi, ho, we, dm, mo, 1);
    }
    if ((dayOfWeek == 7) && (dayOfMonth >= 25) && (month == 10) && (hour == 3) && (year == 1)) {
      setDS3231time(se, mi, 2, we, dm, mo, 0);
    }

    // Управление левыми точками (blinky_dot)
    // ... (подробные комментарии в коде)

    if (hour > 9) {
      matrix.writeDigitNum(0, (hour / 10), false);
      matrix.writeDigitNum(1, (hour % 10), false);
    } else {
      matrix.writeDigitNum(1, hour, false);
    }

    if (se <= 30) blinky_dot = 10; else blinky_dot = 6;
    matrix.writeDigitRaw(2, blinky_dot);
    matrix.writeDigitNum(3, (minute / 10), false);
    matrix.writeDigitNum(4, (minute % 10), false);
    matrix.writeDisplay();
    delay(500);
    matrix.drawColon(false);
    matrix.writeDisplay();
    delay(500);
  }
}

void displayTemp(){
  matrix.setBrightness(brightness_matrix);
  matrix.clear();
  byte temp = get3231Temp();
  int abs_temp = abs(temp);
  matrix.writeDigitNum(1, (abs_temp % 10), false);
  if (temp < 0) matrix.writeDigitRaw(0, 64);
  if (temp <= -10) matrix.writeDigitRaw(2, 12);
  if (temp >= 10) matrix.writeDigitNum(0, (abs_temp/10), false);
  if (temp <= -10) matrix.writeDigitNum(0, (abs_temp/10), false);
  matrix.writeDigitRaw(3, 99); // °
  matrix.writeDigitRaw(4, 57); // C
  matrix.writeDisplay();
  Serial.print("Temperatur in C: "); Serial.println(get3231Temp());
  delay(delay_matrix_temp);
}

void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year){
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

void getDateDs3231(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) {
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}

float get3231Temp(){
  byte tMSB, tLSB; float temp3231;
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0x11);
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 2);
  if (Wire.available()) {
    tMSB = Wire.read();
    tLSB = Wire.read();
    temp3231 = (tMSB & B01111111);
    temp3231 += ((tLSB >> 6) * 0.25);
    return temp3231;
  } else {
    Serial.println("DS3231 Sensor Error - cant read temperature");
    matrix.print(0xBEEF, HEX);
    matrix.writeDisplay();
    delay(5000);
  }
}

MyClock v1.1 (C/C++) — исправлен расчет воскресенья для перехода на летнее/зимнее время

Изменение: dayOfWeek == 1 вместо 7 в функции displayTime() для корректного определения воскресенья. Полный код аналогичен v1.0 с этим исправлением.

Исходники на GitHub: https://github.com/ILohs/MySketches

Схемы

Исправленная схема подключения LDR:
Часы на 7-сегментном дисплее с Arduino Nano, DS3231 RTC и автояркостью от LDR
Часы на 7-сегментном дисплее с Arduino Nano, DS3231 RTC и автояркостью от LDR

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

  1. Arduino POV-часы: сборка дисплея на эффекте сохранения образа
  2. Ретро-часы на индикаторах Numitron с Arduino: просто, надёжно, экономно
  3. Стильные настенные часы на четырех кольцах Adafruit Neopixel 60 LED и Arduino
  4. Часы реального времени на Arduino с расчётом времени намаза
  5. Создание пользовательских LED-часов с будильником — видно с 12 метров
  6. Монитор температуры и реальные часы на Arduino Due с TFT-дисплеем 3.2"
  7. Управление двумя шаговыми двигателями через джойстик на Arduino Nano — простой урок (Visuino)
  8. DIY Arduino Smartwatch: самодельные умные часы в стиле Apple Watch
  9. Точные 7-сегментные часы на Arduino Pro Mini и DS1302 RTC
  10. Надёжные будильник на DS1302 RTC и Arduino UNO — сборка и код