Arduino ura in koledar s pomočjo Arduino NANO strong, RTC DS3231 in TM1637 LED display-ev

Simpatičen in preprost projekt ure in koledarja. Krmilnik Arduino Nano Strong je ozbran zaradi svojih fizičnih dimenzij. Modul, ki skrbi za uro je RTC DS3231 “Real time clock” z baterijo. Za prikaz vrednosti pa uporabljamo 3 module s po 4x 7 segmentni LED.

Slika ure

Elektronska shema:

Fritzing shema

STL datoteke za 3D tisk:

https://www.thingiverse.com/thing:4103139

Arduino koda prvega dela programa, ki ob priklopu na USB iz računalnika prebere uro in datum.

/*
 * deluje OK 29.11.2019
 * 
 * Krmilnik naloži točni čas na RTC DS3231 modul!
 * Mega, Nano, Strong
 * 
 * 
 */

#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>

const char *monthName[12] = {
  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

tmElements_t tm;

void setup() {
  bool parse=false;
  bool config=false;

  // get the date and time the compiler was run
  if (getDate(__DATE__) && getTime(__TIME__)) {
    parse = true;
    // and configure the RTC with this info
    if (RTC.write(tm)) {
      config = true;
    }
  }

  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor
  delay(200);
  if (parse && config) {
    Serial.print("DS1307 configured Time=");
    Serial.print(__TIME__);
    Serial.print(", Date=");
    Serial.println(__DATE__);
  } else if (parse) {
    Serial.println("DS1307 Communication Error :-{");
    Serial.println("Please check your circuitry");
  } else {
    Serial.print("Could not parse info from the compiler, Time=\"");
    Serial.print(__TIME__);
    Serial.print("\", Date=\"");
    Serial.print(__DATE__);
    Serial.println("\"");
  }
}

void loop() {
}

bool getTime(const char *str)
{
  int Hour, Min, Sec;

  if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
  tm.Hour = Hour;
  tm.Minute = Min;
  tm.Second = Sec;
  return true;
}

bool getDate(const char *str)
{
  char Month[12];
  int Day, Year;
  uint8_t monthIndex;

  if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
  for (monthIndex = 0; monthIndex < 12; monthIndex++) {
    if (strcmp(Month, monthName[monthIndex]) == 0) break;
  }
  if (monthIndex >= 12) return false;
  tm.Day = Day;
  tm.Month = monthIndex + 1;
  tm.Year = CalendarYrToTm(Year);
  return true;
}

Druga koda je koda, ki bo ostala v krmilniku. S pomočjo nje iz RTC beremo podatke in jih izpisujemo na LED prikazovalnike.

//
//  deluje OK 04.12.2019
//
// - uporaba RTC DS3231 modula
// - Arduino Strong
// - 3x 4x7segLED
//
// display 1: sekunde
// display 2: ura, minute
// display 3: dan, mesec
//
//
// RTC prikop:
// SDA > pin A4
// SCL > pin A5
//
//

#include <DS3231.h>
#include <Wire.h>
#include <TM1637Display.h>

// for TM1637 display 1
// fizično zgornji display 
#define CLK1 3
#define DIO1 2
#define TEST_DELAY   500

// for TM1637 display 2
#define CLK2 5
#define DIO2 4

// for TM1637 display 3
#define CLK3 7
#define DIO3 6

// instance modulov
DS3231 Clock;
TM1637Display display1(CLK1, DIO1);
TM1637Display display2(CLK2, DIO2);
TM1637Display display3(CLK3, DIO3);


bool Century=false;
bool h12;
bool PM;
byte ADay, AHour, AMinute, ASecond, ABits;
bool ADy, A12h, Apm;
boolean toggle = true;

void setup() {
  pinMode(A0, OUTPUT); //LED on pin 13
	// Start the I2C interface
	Wire.begin();
  //svetlost: min=8 - max=15  
  display1.setBrightness(15); 
  display2.setBrightness(12);     
  display3.setBrightness(12);  
	// Start the serial interface
	//Serial.begin(9600);
 
}

void loop() {

  // kreiranje podatkov
  uint8_t data1[] = { 
    data1[0] = 0b00000000,
    data1[1] = 0b00000000,
    display1.encodeDigit(Clock.getSecond()/10), 
    display1.encodeDigit(Clock.getSecond()%10)};    
  uint8_t data2[] = { 
    display1.encodeDigit(Clock.getHour(h12, PM)/10),
    display1.encodeDigit(Clock.getHour(h12, PM)%10)+128,   // +128 je dvopičje
    display1.encodeDigit(Clock.getMinute()/10), 
    display1.encodeDigit(Clock.getMinute()%10)};
  uint8_t data3[] = { 
    display1.encodeDigit(Clock.getDate()/10),
    display1.encodeDigit(Clock.getDate()%10)+128,          // +128 je dvopičje
    display1.encodeDigit(Clock.getMonth(Century)/10), 
    display1.encodeDigit(Clock.getMonth(Century)%10)};    


  // prikaz podatkov na display
  display1.setSegments(data1);
  display2.setSegments(data2);
  display3.setSegments(data3);

  

}