11. 12. 2016

Arduino projekt: Hodiny, část 1

Jak už jsem psala minule. Pustila jsem se i já do prvního projektu s Arduinem. A, ostatně jako vždy, i tentokrát mám velký cíl. To jest, vyrobit si nástěnné hodiny s extra funkcí navíc.


Ale to bych nebyla já abych se spokojila jen tak s něčím obyčejným jako vyrábí kde kdo. Budou to velké hodiny se segmentovým displejem které budou umět stlumit svit číslic když bude v místnosti tma a navíc budou ukazovat čas jenom v případě když to bude relevantní. Ne jako všechny ostatní hodiny, které ukazují čas po většinu dne jen pro prázdnou místnost. A nebo duchům...

Nejprve je potřeba stáhnout a nainstalovat program IDE. Po připojení arduina přes kabel USB si v menu "Nástroje" > "Vývojová deska" vyber typ Arduina který máš. Potom port na kterém je připojeno. "Nástroje" > "Port" (u mě je to COM5)

Co jsem se to rozhodla použít:

  1. Arduino Nano V3.0 ATmega328
  2.  propojovací kabel USB - USB mini (na propojení s počítačem)
  3. modul RTC DS3231 - modul času
  4. segmentový display TM1637 (pro finální hodiny budu pravděpodobně displej vyrábět pokud neseženu vhodný)

A jak můj experiment vlastně probíhal?
První jsem si zapojila modul reálného času (RTC) na sběrnici I2C, rozchodila nastavení času a výpis na sériovou linku.
K ovládání hodin potřebujeme knihovnu DS3231. Ke stažení je tady. A knihovnu Wire, ta je součástí IDE.

Další krok je připojit segmentový displej a rozběhat kód pro čtení času z RTC a zobrazení na displej. Potřebná knihovna ke stažení tady.

Po pár hodinách experimentování a šťourání se v kódu se mi podařilo všechno rozběhnout. Pro zkušeného programátora by to jistě byla otázka hodinky? Možná ani ne. Jenže já nad tím strávila hodiny asi 4. Nakonec s pozitivním výsledkem.

Schéma zapojení hodiny v1

Přidám ještě obrázek s rozpisem pinů Arduina které jsem použila.
schéma vývodů Arduino Nano V3.0 ATmega328
A konečně je na řadě samotný kód.
Pozor na řádku 50 je nastavení času do RTC:
Mimochodem, ten řátek je označený tlustě a pod ním je hromada hvězdiček, takže je nepřehlédnutelný.

Před prvním nahráním kódu odkomentuj, nastav si správně hodnoty času podle řádku 49 a odešli kód do arduina.
Zakomentuj nastavení času a opět pošli kód aby nedocházelo k opakovanému přepsání času po každém spuštění obvodu nebo po resetu.


// Zobrazení času na displeji

// Zapojení pinů:
/*** RTC DS3231 > Arduino Nano v3.0
GND > GND
Vcc > 3V3
SCL > SCL A5
SDA > SDA A4
*/

/*** TM1637 Display > Arduino Nano v3.0
GND > GND
Vcc > 5V
CLK > D4
DIO > D5
*/

#include "Wire.h"
#include

//*** nastavení displeje
#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"

// nastavení čísel pinů pro propojení s Arduinem
const byte PIN_CLK = 4; // define CLK pin (any digital pin)
const byte PIN_DIO = 5; // define DIO pin (any digital pin)
SevenSegmentExtended display(PIN_CLK, PIN_DIO);
//***

// ***Modul RTC
#define DS3231_I2C_ADDRESS 0x68
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val) {
return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val) {
return ( (val / 16 * 10) + (val % 16) );
}


//***
void setup() {
Serial.begin(9600);
//*** modul RTC
Wire.begin();
// set the initial time here:
// sec, min, hod, č. dne v týdnu (ne=0,po=1...so=6), den, měs, rok
// setDS3231time(0, 10, 16, 5, 25, 11, 16); //************************************** nastaví čas
//***
//*** Display
display.setBacklight(50); // set the brightness to 100 %
display.begin();
//***
}


// sets time and date data to DS3231
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year) {
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();
}
// read time and date from DS3231
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());
}

void loop() {
//*** čas na display
//čtení z RTC DS3231
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

// výpis časuí na displej
display.printTime(hour, minute, true);

//*** kontrolní výpis času a datumu na seriovou linku
/*
Serial.print(hour);
Serial.print(":");
Serial.print(minute);
Serial.print(":");
Serial.print(second);
Serial.print(" ");
Serial.print(dayOfMonth);
Serial.print(".");
Serial.print(month);
Serial.print(".20");
Serial.println(year);
*/
delay(1000);
}


Příklad kódu ke stažení tady.

Pokračování příště.

Žádné komentáře:

Okomentovat