Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Een 7-segmentklok bouwen met Arduino Nano, DS3231 RTC en LDR-automatische helderheid

Onderdelen en benodigdheden

OnderdeelAantalOpmerking
Arduino Nano R31Werkt ook met Arduino Uno of Elegoo Uno
Adafruit 7-Segment Backpack - 1,2" hoge cijfers1Optioneel als je de bundle koopt
Adafruit 1,2" 4-Digit 7-Segment Display met I2C Backpack - Groen1
Adafruit DS3231 RTC1Of DS1307 (minder nauwkeurig, geen temperatuur)
Weerstand 100k ohm1Voor LDR
Fotoweerstand (LDR)1
Breadboard1
Draadjes (jumper wires)10-14 stuks
Knopcelbatterij CR12201Voor RTC-backup

Apps en online diensten

  • Arduino IDE

Over dit project

Inleiding

In een tijd waarin je altijd een klok op je pols hebt (horloge of smartphone), lijkt een Arduino-klok misschien saai. Maar dit project biedt een zelfstandige klok zonder internetverbinding – ideaal voor een slaapkamer waar geen WiFi gewenst is.

Keuze van de RTC

Er zijn veel RTC-modules beschikbaar. De keuze viel op de DS3231 (nauwkeuriger, met ingebouwde temperatuursensor) en de goedkoper DS1307. Beide werken met deze code; voor de DS1307 moet je de temperatuurweergave uitschakelen (commentarieer displayTemp() in de loop).

Aanpassing van de sketch

De oorspronkelijke code is herstrukturiseerd en uitgebreid met Engelse commentaren. Het grote 7-segmentdisplay toont tijd en temperatuur afwisselend. De helderheid past zich automatisch aan aan de omgevingslichtsterkte via de LDR. Ook is zomer-/wintertijdomschakeling geïmplementeerd.

Initialiseren van de klok

Met een CR1220-batterij kun je de RTC instellen via de korte Adafruit-tutorial. De tijd wordt niet via internet gesynchroniseerd, maar via de lokale PC-tijd bij het uploaden van de sketch.

Functies

  • Tijd- en temperatuurweergave: Wisselinterval instelbaar via variabelen.
  • Knipperende punten: De linker puntjes knipperen met de seconden (boven/onder).
  • Zomer-/wintertijd: Automatische omschakeling op de laatste zondag van maart en oktober.
  • Automatische helderheid: LDR meet omgevingslicht; display dimt 's nachts.
  • Foutafhandeling: Bij communicatiefout met DS3231 verschijnt "bEEF" op het display.

Uitbreiding

Toekomstige uitbreidingen: alarmfunctie, Bluetooth/Blynk-besturing. De printplaatversie (v1.1) is voltooid en getest.

Code

MyClock v1.0 (C/C++)

// MyClock v1.0
// Ingo Lohs
// Hardware: getest met Arduino Uno en Nano (ATmega328P [Old Bootloader]) via Arduino IDE v1.8.8

#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; // helder bij daglicht
  } else {
    brightness_matrix = 15; // dim in het donker
  }
}

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;

    // Zomertijd: laatste zondag maart om 02:00
    if ((dayOfWeek == 7) && (dayOfMonth >= 25) && (month == 3) && (hour == 2)) {
      setDS3231time(se, mi, 3, we, dm, mo, ye);
    }
    // Wintertijd: laatste zondag oktober
    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);
    }

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

    // Knipperende linker puntjes
    if (se <= 30) blinky_dot = 10; // onder + dubbele punt
    else if (se > 30) blinky_dot = 6; // boven + dubbele punt
    matrix.writeDigitRaw(2, blinky_dot);

    // Minuten
    matrix.writeDigitNum(3, (minute / 10), false);
    matrix.writeDigitNum(4, (minute % 10), false);
    matrix.writeDisplay();

    // Dubbele punt knippert per halve seconde
    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); // minteken
  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("Temperatuur 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++)

Update: correctie zomer-/wintertijdlogica (dag van week 1 = zondag ipv 7). Volledige code op GitHub.

Schema

Een 7-segmentklok bouwen met Arduino Nano, DS3231 RTC en LDR-automatische helderheid Een 7-segmentklok bouwen met Arduino Nano, DS3231 RTC en LDR-automatische helderheid

Productieproces

  1. Arduino POV-klok: Bouw een Persistence-of-Vision LED-display
  2. Bouw een retro Numitron-klok met Arduino: Eenvoudig, betrouwbaar en energiezuinig
  3. Een stijlvolle wandklok bouwen met Adafruit 60-LED Neopixel Ring & Arduino
  4. Bouw een Arduino Real-Time Clock voor Islamitische Gebedstijden
  5. Bouw een Aangepaste LED Hoofdklok met Alarm – Zichtbaar vanaf 12 Meter
  6. Arduino Temperatuurbewaking & Realtime Klok met 3.2" TFT-display
  7. Twee Stappenmotors Sturen met Arduino Nano & Joystick – Simpele Tutorial
  8. DIY Arduino Smartwatch: Bouw Je Eigen Apple Watch-stijl Tijdwijzer
  9. Bouw een Precieze 7-Segment Klok met Arduino Pro Mini & DS1302 RTC
  10. Bouw een handgehoude Geiger-teller met Arduino Nano
  11. Bouw een betrouwbare wekker met DS1302 RTC en Arduino UNO