Hodiny s ukazatelem dnů v týdnu a datem

Tvoříte zajímavý projekt? Pochlubte se s ním.
Pravidla fóra
Vkládejte prosím jen HOTOVÉ projekty, které chcete představit ostatním.
Odpovědět
Uživatelský avatar
SkullKeep
Příspěvky: 290
Registrován: 23 srp 2017, 18:51
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Hodiny s ukazatelem dnů v týdnu a datem

Příspěvek od SkullKeep » 28 črc 2019, 10:24

Chtěl bych představit moje Hodiny s RTC modulem a BT připojením pro nastavení hodin. Diody ukazují den v týdnu Po-Ne plus svátek a narozeniny. Do budoucna uvažuji o zmenšení na 60x60 a výměnu Arduino Nano za AtTiny84 plus napájení z Li-Ion batery akumulatoru.
Pohled z boku
Obrázek
Pohled z vrchu
Obrázek
Pohled ze předu
Obrázek
Tu je schéma zapojení
Obrázek

Tu je program pro Arduino

Kód: Vybrat vše

// inicializace zakladnich knihoven
#include <Wire.h> // inport knihovny I2C piny SDA PA6, SCL PA4
#include <LedControltiny.h>
#include <TaskScheduler.h>
const static byte digit[] = {126, 48, 109, 121, 51, 91, 95, 112, 127, 123};
const static byte narozky_den[] = {9, 23, 5, 12, 24, 7, 2};
const static byte narozky_mesic[] = {3, 3, 4, 5, 6, 8, 9};
byte svatek_den[] = {1, 10, 13, 1, 8, 5, 6, 28, 28, 17, 24, 25, 26};
const static byte svatek_mesic[] = {1, 4, 4, 5, 5, 7, 7, 9, 10, 11, 12, 12, 12};
const static byte den[] = {127, 1, 3, 7, 15, 31, 63};
//------------------------------------------------------------------
LedControl Eigth_led = LedControl(10, 6, 9, 2); //DIN,CLK,CS
void t1displayTimeDate();
Scheduler runner;
//------------------------------------------------------------------
//task
Task t1(10000, TASK_FOREVER, &t1displayTimeDate, &runner, true); // cas v milisekundach, jak dlouho
// promenne pro zobrazeni casu
#define DS3231_I2C_ADDRESS 0x68
byte second;
byte minute;
byte hour;
byte dayOfWeek;
byte dayOfMonth;
byte month;
byte year;
byte den_old = 0;
bool nastav = false;
bool nastav_sv = false;
bool svatek = false;
bool narozky = false;
byte data[] = {0, 0, 0, 0, 0, 0, 0};
// spusteni programu

void setup() {
  Eigth_led.shutdown(0, false);
  Eigth_led.clearDisplay(0); // vymaz ledky
  Eigth_led.setIntensity(0, 4);
  Eigth_led.shutdown(1, false);
  Eigth_led.clearDisplay(1); // vymaz ledky
  Eigth_led.setIntensity(1, 3);
  Serial.begin(115200);
  Wire.begin(); // inicializace knihovny I2C
  // spusteni tasku
  runner.startNow();
}
//------------------------------------------------------------------
// hlavni smycka
void loop() {
  runner.execute();// spusteni taskmanageru
  if (nastav == true) {
    nastav = false;
    if (nastav_sv == true) {
      Serial.println("Velikonoce nastaveny.");
      nastav_sv = false;
    } else {
      BT();
      Serial.println("Cas nastaven.");
    }
  }
}
//------------------------------------------------------------------
// ulozeni casu
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year) {
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}
//------------------------------------------------------------------
// cteni casu
void readDS3231time(byte * second, byte * minute, byte * hour, byte * dayOfWeek, byte * dayOfMonth, byte * month/*, byte * year*/) {
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *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());
}
//------------------------------------------------------------------
// zobraz data z hodinoveho modulu
void t1displayTimeDate() {
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month/*, &year*/);
  if (den_old != dayOfWeek) {
    den_old = dayOfWeek;
    RGBled();
  }
  Eigth_led.setRow(0, 4, digit[hour / 10]);
  Eigth_led.setRow(0, 5, digit[hour % 10] + 128);
  Eigth_led.setRow(0, 6, digit[minute / 10]);
  Eigth_led.setRow(0, 7, digit[minute % 10]);
  Eigth_led.setRow(0, 0, digit[dayOfMonth / 10]);
  Eigth_led.setRow(0, 1, digit[dayOfMonth % 10] + 128);
  Eigth_led.setRow(0, 2, digit[month / 10]);
  Eigth_led.setRow(0, 3, digit[month % 10]   + 128);
}
//------------------------------------------------------------------
// prevod jednotek pro ulozeni dat do hodinoveho modulu
byte decToBcd(byte val) {
  return ((val / 10 * 16) + (val % 10));
}
//------------------------------------------------------------------
// prevod jednotek pro cteni dat z hodinoveho modulu
byte bcdToDec(byte val) {
  return ((val / 16 * 10) + (val % 16));
}
//------------------------------------------------------------------
void serialEvent() //čtení z BT modulu
{
  String dataS;
  while (Serial.available()) {
    dataS = Serial.readString();
  }
  if (dataS[0] == 'N') {
    for ( byte i = 1; i < dataS.length() + 1 ; i++) {
      data[i - 1] = byte(dataS[i]);
    }
    Serial.println("Prijato.");
    nastav = true;
  } else if (dataS[0] == 'S') {
    svatek_den[1] = byte(dataS[1]);
    svatek_den[2] = byte(dataS[2]);
    Serial.println("Prijato.");
    nastav_sv = true;
    nastav = true;
  } else nastav = false;
}
//------------------------------------------------------------------
void BT()//nastaveni času
{ // DS3231 seconds, minutes, hours, day, date, month, year
  setDS3231time(data[2], data[1], data[0], data[3], data[4], data[5], data[6]);
}
//------------------------------------------------------------------
void RGBled() {//nastaveni RGB světel
  for ( byte i = 0 ; i < sizeof(narozky_mesic) - 1; i++) {//prohledani pole narozek
    if ((narozky_den[i]) == dayOfMonth && (narozky_mesic[i]) == month) {
      narozky = true;
      break;
    } else {
      narozky = false;
    }
  }
  for ( byte i = 0 ; i < sizeof(svatek_mesic) - 1; i++) {//prohledani pole svatku
    if ((svatek_den[i]) == dayOfMonth && (svatek_mesic[i]) == month) {
      svatek = true;
      break;
    } else {
      svatek = false;
    }
  }
  if (svatek == true) {
    Eigth_led.setRow(1, 0, den[dayOfWeek - 1] + 128);
  } else {
    Eigth_led.setRow(1, 0, den[dayOfWeek - 1]);
  }
  if (narozky == true) {
    Eigth_led.setRow(1, 1, 128);
  } else {
    Eigth_led.setRow(1, 1, 0);
  }
}
//------------------------------------------------------------------
Použité knihovny:
TaskScheduler
LedControltiny

Program pro nastavení hodin je napsán v programu Processing. Chybí tam dodělat nastavení Svátku, kvůli proměnlivosti datumu velikonoc.
Program pro nastavení Hodin:

Kód: Vybrat vše

import processing.serial.*;
import java.util.Calendar;
Serial port;
StringList usb = new StringList();
String OS[] = {"WINDOWS", "LINUX"};
String Chip_id[] = {"PL2303", "CH340G", "CP2102"}; //PL2303 idProduct=2303 idVendor=067b CH340g idProduct=7523 idVendor=1a86 CP2102 idProduct=ea60 idVendor=10c4
byte Os, Port;
int delka;
int delka_pom = 1;
boolean detect;
boolean reclik = false;
boolean posli = false;
boolean click = false;
String Idvendor, Usb, props;
boolean device_detected = false;
String Text ;
String[] port_list;
String[] Id;
String BTod = "";
String detected_port = "";
int[] time = {0, 0, 0, 0, 0, 0, 0};
//*************************************
void setup() {
  size(500, 500);
  fill(0);
  //USB_informace();
}
//*************************************
void draw() { // telo programu
  background(237, 240, 241);
  fill(20, 160, 133); // Green Color
  stroke(33);
  strokeWeight(1);
  rect(20, 10, 180, 50, 10);  // Turn ON Button
  rect(20, 70, 180, 50, 10);  //port button
  rect(250, 10, 150, 50, 10); // Turn OFF Button
  rect(365, 440, 80, 50, 10); // Exit Button
  fill(255);
  textSize(32);
  text("Získej cas", 30, 45);
  if (posli == true) {
    text("Pošli cas", 260, 45);
  }
  if (reclik == true) {
    text("Zavri port", 25, 105);
  } else {
    text("Otevri port", 25, 105);
  }
  text("Exit", 375, 475);
  if (click) {    
    fill(33);
    textSize(32);
    text(time[0]+":", 5, 160);
    text(time[1]+":", 53, 160);
    text(time[2], 101, 160);
    text(time[3], 149, 160);
    text(time[4]+".", 175, 160);
    text(time[5]+".", 235, 160);
    text(time[6], 266, 160);
  }
  textSize(22);
  fill(33);
  text("################################", 5, 200);
  if (device_detected == false) {
    text("BT PC: OFF Port: None", 5, 240);
  } else {
    text("BT PC: ON Port:"+detected_port, 5, 240);
  }
  if (BTod != null) {    
    text("BT msg:"+BTod, 5, 270);
  } else {  
    text("BT msg:", 5, 270);
  }
}
//*************************************
void mouseReleased() {
  if (mouseButton == LEFT ) {
    if ( mouseX>50 && mouseX<200 && mouseY>10 && mouseY<50) {//ziskani aktualniho casu
      click = true;
      Calendar cal = Calendar.getInstance();
      time[0] =cal.get(Calendar.HOUR_OF_DAY);
      time[1] =cal.get(Calendar.MINUTE);
      time[2] =cal.get(Calendar.SECOND);
      time[3] =cal.get(Calendar.DAY_OF_WEEK);
      time[4] =cal.get(Calendar.DATE);
      time[5] =cal.get(Calendar.MONTH)+1;
      time[6] =cal.get(Calendar.YEAR)-2000;
    }
    //#########################################################
    if ( mouseX>50 && mouseX<200 && mouseY>70 && mouseY<120) {//otevreni COM-USB portu
      reclik = !reclik;
      delay(1000);
      if (reclik == false) {
        port.stop();
        posli = false;
        device_detected = false;
      } else { 
        USB_informace();
      }      
      if (device_detected == false) {
        reclik=false;
      }
    }
    //#########################################################
    if ( mouseX>250 && mouseX<400 && mouseY>10 && mouseY<50) {//poslani nastaveni hodin
      if (posli == true) {
        port.write('N');
        port.write(time[0]);
        port.write(time[1]);
        port.write(time[2]);
        port.write(time[3]);
        port.write(time[4]);
        port.write(time[5]);
        port.write(time[6]);
        delay(100);
        port.clear();
      }
    }
  }
  //#########################################################
  if ( pmouseX>365 && pmouseX<440 && pmouseY>440 && pmouseY<490) {//ukonceni programu
    if (detect) port.stop();
    exit();
  }
}
//**************************************
void serialEvent (Serial port) { // Checks for available data in the Serial Port
  BTod =   port.readStringUntil('\n'); 
  port.clear();//Reads the data sent from the Arduino (the String "LED: OFF/ON) and it puts into the "ledStatus" variable
}
//**************************************
void USB_informace() {
  detect = false;
  usb = new StringList();
  usb.append(Serial.list());
  if (usb.hasValue("/dev/ttyS0")) { //jestli LINUX
    Os = 1;
  } else if (usb.hasValue("COM")) {// jestli Windows
    Os = 0;
  }
  //***************************************
  if (Os == 1) { // linux USB
    delka = usb.size();
    if (usb.size() > 1) {
      for (byte i=0; i < usb.size(); i++) { 
        //Map<String, String> 
        props = (Serial.getProperties(usb.get(i))).toString();
        Idvendor = trim(props);
        Id = match(Idvendor, "idVendor=1a86");
        if (Id != null) {
          detect = true;
          Usb = usb.get(i);
        } else {
          Id = match(Idvendor, "idVendor=067b");
          if (Id != null) {
            detect = true;
            Usb = usb.get(i);
          } else {
            Id = match(Idvendor, "idVendor=10c4");
            if (Id != null) {
              detect = true;
              Usb = usb.get(i);
            }
          }
        }
      }
    }
  } 
  //***************************************
  else if (Os == 0) { // Windows USB
    delka = Serial.list().length;
    if (delka == 1) {
      device_detected = false;
      posli = false;
    } else {
      delka = Serial.list().length;
    }
    port_list = new String[delka];
    for (int i = 0; i < delka; i++) {
      port_list[i] = Serial.list()[i];
    }
    // kontrola jestli pribylo dalsi zarizeni
    if ((Serial.list().length > delka_pom) && !device_detected) {
      device_detected = true;
      // na kterem protu pribylo
      if (delka == 0) {
        detected_port = Serial.list()[0];
      } else {
        // proxhazeni vypisu COMu
        for (int i = 0; i < Serial.list().length; i++) {
          // zjisteni posledniho COMu
          for (byte j = 0; j < delka; j++) {
            if (Serial.list()[i].equals(port_list[j])) {
              Port = j;
              detect = true;
              break;
            }
          }
        }
      }
    }
    if ( device_detected ) {// prideleni COMu
      detected_port = Serial.list()[Port];
      port = new Serial(this, detected_port, 115200); // spusteni komunikace
      port.clear();
      port.bufferUntil('\n');
      posli = true;
    }
  }
}
//**************************************
Použitý materiál:
USB na TTL
BlueTooth Modul
MAX7219
RTC modul
Arduino Nano
LED diody 5MM 5 barev
Univerzální PCB
Propojovací konectory
Odpory
USB konektor
4 Pin konekotry
:twisted: :?: :arrow: :geek: P. Q. M.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 6 hostů