Stránka 1 z 1

Arduino UNO R3 + funduino budík

Napsal: 19 úno 2024, 19:58
od Matias
Ahoj kluci,
pořídil jsem mladýmu tuhle sestavu.
Snažím se na tom rozběhat budík. Ale nedaří se.
Po nahrání nalezeného programu se sepne piezo ihned po zapnutí napájení.
Nejsem v tomhle moc kovaný. Něco málo zvládnu. Ale potřeboval bych, aby to běhalo korektně. Koukl by prosím moc na kód, jestli to je dobře?
Obojí je klon. Ale mám pro sebe UNO originál. Dělá to samé. Transistor je PNP. Ten je v pořádku.

Zdroj: kabinet.fyzika

Děkuji moooc.

// Pro praci s vnitrnim casem Arduina vyuzijeme tyto funkce knihovnu TimeLib
// hour() - pocet hodin (0-23)
// minute() - pocet minut (0-59)
// second() - pocet sekund (0-59)
// day() - den (1-31)
// month() - mesic (1-12)
// year() - rok (2020, 2021...)
// setTime(hr,min,sec,day,mnth,yr) - nastavime vnitrni cas Arduina
#include <TimeLib.h>

// Nastaveni dle Multi-Shieldu nzvaneho Funduino
int latchPin = 4; // piny potrebne pro zobrazovace
int clockPin =7;
int dataPin = 8;
unsigned char Dis_table[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90}; // data pro zobrazeni cisel
unsigned char Dis_buf[] = {0xF1,0xF2,0xF4,0xF8};
unsigned char disbuff[] = {0, 0, 0, 0};

int KEY_HOD = A1; // tlacita pro ovladani
int KEY_MIN = A2;
int KEY_SET = A3;
int KEY_SET_old; // minuly stav tlacitka S3
int KEY_HOD_old; // minuly stav tlacitka S1
int KEY_MIN_old; // minuly stav tlacitka S3

int hodina; // promenne pro praci s casem Arduina
int minuta;
int sekunda;
int den;
int mesic;
int rok;

int ALARM_hod = 0; // promenne pro praci budikem
int ALARM_min = 0;
bool vstavej = true;
bool zvoni = false;
int buzzer = 3; // adresa bzucaku

//---------------------------------------------------------------------------

void setup(void)
{
pinMode(latchPin, OUTPUT); // nastaveni pro zobrazovace
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);

pinMode(buzzer, OUTPUT);

// prvotni nastaveni nastaveni hodin - pri resetu
setTime(16, 40, 00, 22, 03, 2020); // hod, min, sec, den, mesic, rok
}

void display(void)
{
for(char i = 0; i <= 3; i++) // probehne segmenty a zobrazi hodnoty
{
digitalWrite(latchPin, LOW); // zapis na latch
if ((i != 1)||(sekunda%2 == 0)) {
if ((i == 0) && (disbuff[i] == 0)) { // je to prvni segmentovka a je na ni 0
shiftOut(dataPin, clockPin, MSBFIRST, 255); // posli zhasle vsechny zobrabovace
}
else shiftOut(dataPin, clockPin, MSBFIRST, Dis_table[disbuff[i]]); // data pro zobrazovac bez tecky
}
else shiftOut(dataPin, clockPin, MSBFIRST, Dis_table[disbuff[i]] + 128); // data pro zobrazovac s teckou
shiftOut(dataPin, clockPin, MSBFIRST, Dis_buf[i] ); // adresa zobrazovace
digitalWrite(latchPin, HIGH); // zobraz zapsana data
delay(2); // cekej 2 ms
}
}

//---------------------------------------------------------------------------

void loop(void)
{
hodina = hour(); // nacteni aktualniho casu
minuta = minute();
sekunda = second();
den = day();
mesic = month();
rok = year();

if ((hodina == ALARM_hod)&&(minuta == ALARM_min)) // nastal cas buzeni
{
if (vstavej) // je ale buzeni dovolene
{
tone(buzzer, 440);
zvoni = true;
vstavej = false;
}
}
else {
noTone(buzzer);
zvoni = false;
vstavej = true;
} // cas uz nesedi, tak mlc

// A jdeme na testovani tlacitel

// NASTAVENI BUDIKU
if (digitalRead(KEY_SET) == LOW) // pokud neni treti sktisknute nic se nastavovat nebude
{ // nastavovani budiku
disbuff[0]= ALARM_hod/10; // pocet desitek hodin
disbuff[1]= ALARM_hod%10; // zbytek po delelni deseti = pocet jednotek hodin
disbuff[2]= ALARM_min/10; // totez pro minuty
disbuff[3]= ALARM_min%10;
display(); // zobrazovani
if (zvoni) { // zamacknuti
noTone(buzzer);
zvoni = false;
}

if ((digitalRead(KEY_HOD) == LOW)&&(KEY_HOD_old == HIGH)) { // stisknute S1
ALARM_hod = (ALARM_hod+1)%24;
} else
if ((digitalRead(KEY_MIN) == LOW)&&(KEY_MIN_old == HIGH)) { // pokud je k tomu stisnute i tlacitko MIN
ALARM_min = (ALARM_min+1)%60;
}
//----------
} else { // neni stiskle tlacitko S3 tak to bezi jako hodiny
disbuff[0]= hodina/10; // pocet desitek hodin
disbuff[1]= hodina%10; // zbytek po delelni deseti = pocet jednotek hodin
disbuff[2]= minuta/10; // totez pro minuty
disbuff[3]= minuta%10;
display(); // zobrazovani

// NASTAVENI HODIN
if ((digitalRead(KEY_HOD) == LOW)&&(KEY_HOD_old == HIGH)) {
hodina = (hodina+1)%24;
setTime(hodina, minuta, sekunda, den, mesic, rok);
} else
if((digitalRead(KEY_MIN) == LOW)&&(KEY_MIN_old == HIGH)) { // pokud je k tomu stisnute i tlacitko HOD pridej hodinu
minuta = (minuta+1)%60;
setTime(hodina, minuta, 00, den, mesic, rok);
}
}

KEY_SET_old = digitalRead(KEY_SET);
KEY_HOD_old = digitalRead(KEY_HOD);
KEY_MIN_old = digitalRead(KEY_MIN);
}

Napsal: 19 úno 2024, 20:13
od Cowley
Já nikde nevidím v SETUPu výchozí stav pro výstup 3/buzzer.
Alespoň to stejné noTone(Buzzer);
Hned za definici typu výstupu.

A ještě odkazy na funkci Tone() na internetu říkají, že tam má být NPN tranzistor, spínající Piezo.

Edit: Funduino má opravdu piezo spínané pomocí PNP.

Napsal: 19 úno 2024, 20:29
od Matias
Zkoušel jsem i změnit tón zvuku ze 440, na jinou hodnotu a to, co slyším z pieza se nemění.
Jak myslíš výchozí stav. Jako za definicí:

int buzzer = 3; // adresa bzucaku
by ještě mělo být že defaultně buzzer off?
Ale nevím jak napsat. :-)
Nakopne mně někdo? Já už si to pak doladím pokusama.

Napsal: 19 úno 2024, 20:33
od Cowley

Kód: Vybrat vše

digitalWrite(buzzer, HIGH);


Nebo dát do setupu hned za buzzer, output do dalšího řádku

Kód: Vybrat vše

noTone(buzzer);


Edit: je třeba zjistit, jaký typ piezo je na desce osazen.

Napsal: 19 úno 2024, 20:46
od Cowley
Pokud je výstup 3 definován jako OUTPUT a není mu dál přidělena žádná činnost, může "natvrdo sepnout tranzistor a tím i piezo.
Můžeš jej na začátek otestovat přepnutím do HIGH, aby se zavřel tranzistor.
V setupu hned za definici buzzer, output dát řádek

digitalWrite (buzzer, HIGH);


A měnit frekvenci je zbytečný, zatím se program nedostal do fáze shody času a nastaveného času budíku.

A tak bych v programu nahradil původní tone a noTone příkazy
digitalWrite (buzzer, HIGH); //pro nepískej
digitalWrite (buzzer, LOW); // pro pískej

V modulu je totiž "aktivní" piezo a ne reproduktor.

Napsal: 19 úno 2024, 20:54
od Matias
Jasan,
super. Díky Ti.
Testnu zítra.
Já už v nedůvěře ve výrobce shieldu. Když nebylo psáno shield, ale shiedl. :-)
Jsem viděl zradu jinde. Proto jsem řešil i ten transistor.
Dám vědět. Zatím díky moc.

Napsal: 19 úno 2024, 21:12
od Cowley
Návod na Drátku.

Jestli je tam opravdu pasivní piezo, tak při příkazu:
digitalWrite (buzzer, LOW); // musí jenom "lupnout".

Možná tam Číňan osadil aktivní piezo namísto pasivního.

Napsal: 21 úno 2024, 18:11
od Matias
Super Cowley.
Neradil Ti Doyle? nebo Boddie? :-)
Už to reaguje správně na čas. Budí.
Je tam opravdu pasiv piezo.
ještě potřebuju zkulturnit zvuk. A asi dám jinou sedmisegmentovku. Ale jsem rád, že to běží.
Tak ještě jednou díky.

Napsal: 21 úno 2024, 18:32
od Cowley
To já radím jim :)
Dobrá zpráva, rádo se stalo...

Edit: co plánuješ s displejem?

Napsal: 21 úno 2024, 20:08
od Matias
No. Měl jsem v plánu původně budík s Attiny2313. Měl jsem připravenou desku s velkou sedmisegmentovkou. Ale nejsem časově schopný si k tomu sednout a zkoušet a pak udělat PCB.
Tak jsem koupil tohle. Když odladím zvuk. Chci dát větší čísla. Ještě musím kouknout co to je za typ a jaký má odběr. Případně to posílit tranzistorama.


BTW. Škoda že už profíky nedávají v pátek večer. :-)

Napsal: 21 úno 2024, 20:17
od Cowley
Displej je řízený multiplexně mezi dvěma 74HC595.
Jeden tam cpe + do anod, druhej mínus do segmentů.
Omezení je dáno proudovým omezením na pin.
V reálu vždy svítí jen jedna číslice.

Při posílení výstupu tranzistory se budou muset upravit pole s uloženými HEXA hodnotami jednotlivých číslic nebo negovat hodnotu až při vysílání dat v příkazu obsluhy SHIFTOUT sériového komunikace.

Anebo třeba takhle velké? (Video z YouTube).