Pomoc w dopisaniu sterowania przyciskami ustawienia godzin minut i sekund w zegarze - ALIBABA-125 - 04-08-2022
Witam.
Szukam osoby chętnej która dopisze mi do programu sterowanie i ustawienie przyciskami godzin minut i sekund.
Zegar zrobiony na bazie arduino nano, DS3231, MAX1719 i sześciu wyświetlaczy 7 segmentowych.
Poniżej kod programu
Kod: #include <DS3231.h>
// define pins attached to MAX7219 (and also see notes above)
#define MAX7219_DIN 12
#define MAX7219_CS 10
#define MAX7219_CLK 11
// enumerate the MAX7219 registers
// See MAX7219 Datasheet, Table 2, page 7
enum { MAX7219_REG_DECODE = 0x09,
MAX7219_REG_INTENSITY = 0x0A,
MAX7219_REG_SCANLIMIT = 0x0B,
MAX7219_REG_SHUTDOWN = 0x0C,
MAX7219_REG_DISPTEST = 0x0F
};
// enumerate the SHUTDOWN modes
// See MAX7219 Datasheet, Table 3, page 7
enum { OFF = 0,
ON = 1
};
// create an instance of the DS3231 called 'rtc',
// and specify the hardware interface PINS
DS3231 rtc(SDA, SCL);
const static byte charTable [] PROGMEM =
{
B01111110, B00110000, B01101101, B01111001, B00110011, B01011011, B01011111, B01110000,
B01111111, B01111011, B01110111, B00011111, B01001110, B00111101, B01001111, B01000111,
};
// ... setup code here, to run once
void setup()
{
// initialize the serial port:
Serial.begin(115200); // initialize serial communication
// define type of pin
pinMode(MAX7219_DIN, OUTPUT); // serial data-in
pinMode(MAX7219_CS, OUTPUT); // chip-select, active low
pinMode(MAX7219_CLK, OUTPUT); // serial clock
digitalWrite(MAX7219_CS, HIGH);
resetDisplay(); // reset the MAX2719 display
rtc.begin(); // init. the DS3231 RTC interface
// Uncomment the following lines to set the RTC
// rtc.setTime(13, 43, 0); // Set the time to 4:20pm
}
void loop()
{
String str; // scratch or working string
// ... display Time, hh-mm-ss
for ( int i = 0; i < 6; i++ )
{
// read the time as a string from the RTC
str = rtc.getTimeStr(FORMAT_LONG);
Serial.println(str); // debug
displayTime(str); // display on the 7-segment
delay(1000);
}
}
// ... write a value into a max7219 register
// See MAX7219 Datasheet, Table 1, page 6
void set_register(byte reg, byte value)
{
digitalWrite(MAX7219_CS, LOW);
shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, reg);
shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, value);
digitalWrite(MAX7219_CS, HIGH);
}
// ... reset the max7219 chip
void resetDisplay()
{
set_register(MAX7219_REG_SHUTDOWN, OFF); // turn off display
set_register(MAX7219_REG_DISPTEST, OFF); // turn off test mode
set_register(MAX7219_REG_INTENSITY, 0x0A); // display intensity
}
// ... display the TIME on the 7-segment display
void displayTime(String timeString)
{
set_register(MAX7219_REG_SHUTDOWN, OFF); // turn off display
set_register(MAX7219_REG_SCANLIMIT, 7); // scan limit 8 digits
set_register(MAX7219_REG_DECODE, 0b11111111); // decode all digits
set_register(5, timeString.charAt(6)); //sekundy
set_register(6, timeString.charAt(7)); //dziesiątki sekund
set_register(4, timeString.charAt(4)); //minuty
set_register(3, timeString.charAt(3)); //dziesiątki minut
set_register(2, timeString.charAt(1)); //godziny
set_register(1, timeString.charAt(0)); //dziesiątki godzin
// set_register(3, timeString.charAt(2)); //minus po godzinach
// set_register(6, timeString.charAt(5)); //minus po minutach
set_register(MAX7219_REG_SHUTDOWN, ON); // Turn on display
}
RE: Pomoc w dopisaniu sterowania przyciskami ustawienia godzin minut i sekund w zegarze - kaczakat - 05-08-2022
Zacznij od zastąpienia delay millis, nie musisz sprawdzać czasu z zegara co 1s, można z niego wziąć przerwanie zewnętrzne, albo mierzyć czas millis, synchronizować czas co np. 1h, chyba, że sam zegar to wszystko co ma robić ten układ.
Tu masz przykład jak przy pomocy klawiatury analogowej ustawić godzinę, w kilka sekund ustawiasz dowolną z dokładnością minuty (zmienna 24x60 1440), zegar w układzie 24h.
Podobnie można zrobić ustawienie daty, zmienna na 40 lat zmieści się w int16.
Kod: #include <AnalogKeypad.h>
// the following table is for this Banggood Analog Keypad
// https://www.banggood.com/AD-Analog-Keyboard-Module-Electronic-Building-Blocks-5-Keys-For-Arduino-DIY-p-1374279.html
// see the AnalogKeypad_CreateConfig.ino sketch example on how to create this table by Makuna
const int KeypadMap[] = {0, 50, 100, 200, 400};
const uint16_t KeypadHoldTimeMs = 1000;
const uint8_t KeypadAnalogPin = A0;
int16_t czasDobowy, czasWduszenia; //int by dalo sie krecic licznikiem przez 0
uint8_t lastbutton;
bool wduszony,update1;
//dla funkcji czas()
uint32_t czasTeraz,czasPoprzedni,tik=10; //tik musi byc mniejszy niz 1000 i dzilic 1000ms na rowne czesci
uint8_t nTik,sekundy,minuty,godziny,dni; //liczniki tikow, sekund, itd.
bool fnTik,fsekundy,fminuty,fgodziny,fdni; //flagi zdarzen nowy tik, nowa sekunda,minuta, godzina, dzien
char napis16[17];
AnalogKeypad keypad(KeypadAnalogPin, KeypadMap, countof(KeypadMap), KeypadHoldTimeMs);
// the button event callback
// this will be called when buttons are pressed and released
void ButtonHandler(const ButtonParam& param)
{
// Serial.print(param.button);
// Serial.print(" ");
//
lastbutton=param.button+1;
switch (param.state)
{
case ButtonState_Up:
// Serial.print("Up");
wduszony=0;
break;
case ButtonState_Down:
// Serial.print("Down");
break;
case ButtonState_Click:
// Serial.print("Click");
if(lastbutton==2) czasDobowy++;
else if (lastbutton==3) czasDobowy--;
update1=1;
break;
case ButtonState_DoubleClick:
// Serial.print("Double Click");
break;
case ButtonState_Hold:
// Serial.print("Hold");
wduszony=1;
break;
}
// Serial.println();
}
void setup() {
Serial.begin(115200);
// while (!Serial); // wait for serial attach
// Serial.println();
Serial.println("Initialized");
}
void loop() {
czas();
if(fnTik) //zamiast dely 10 to mozna sprawdzac stan przyciskow co 10ms
{
keypad.loop(ButtonHandler); //
keypadAction();
}
if(fsekundy or update1)
{
update1=0;
//tylko minuty
sprintf(napis16,"%02d:%02d",czasDobowy/60,czasDobowy%60); // jak zaminiec liczbe 0-1440 na godziny i minuty
Serial.println(napis16);
//sekundy w 10
// sprintf(napis16,"%02d:%02d:%02d",czasDobowy/(60*6),(czasDobowy%(60*6))/6,10*(czasDobowy%(6)) ); // jak zaminiec liczbe na godziny minuty sekundy w piatkach
// Serial.println(napis16);
}
// simulate other work happening
// it also should avoid long delays so loop above can be called
// at least every 10-20ms
// delay(10);
}
//wersja dla minut
void keypadAction()
{
//funkcja jest wywolywana co 10ms, ale chcę coś zrobic co 100ms
if(nTik%10==0) {
if (wduszony)
{ update1=1;
czasWduszenia++;
switch (lastbutton)
{
case 2:
if(czasWduszenia<30)czasDobowy++;
else if (czasWduszenia<120)czasDobowy+=10;
else czasDobowy+=60;
break;
case 3:
if(czasWduszenia<50)czasDobowy--;
else if (czasWduszenia<130)czasDobowy-=10;
else czasDobowy-=60;
break;
}
} else czasWduszenia=0;
}
if (czasDobowy>1440-1) czasDobowy=0;
if (czasDobowy<0) czasDobowy=1440-1;
//if (czasDobowy>(1440*6)-1) czasDobowy=0;
//if (czasDobowy<0) czasDobowy=((1440*6)-1);
}
void czas()
{
czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik) //tan napisany warunek jest odporny na "klątwe 50 dni millis()"
{
czasPoprzedni=czasTeraz;
fnTik=1;
nTik++;
if(nTik>=(1000/tik))
{
nTik=0;
sekundy++;
fsekundy=1;
if (sekundy>=60)
{
sekundy=0;
minuty++;
fminuty=1;
if (minuty>=60)
{
minuty=0;
godziny++;
fgodziny=1;
if (godziny>=24)
{
godziny=0;
fdni=1;
dni++;
}
}
}
}
}
}
RE: Pomoc w dopisaniu sterowania przyciskami ustawienia godzin minut i sekund w zegarze - ALIBABA-125 - 08-08-2022
(05-08-2022, 16:25)kaczakat napisał(a): Zacznij od zastąpienia delay millis, nie musisz sprawdzać czasu z zegara co 1s, można z niego wziąć przerwanie zewnętrzne, albo mierzyć czas millis, synchronizować czas co np. 1h, chyba, że sam zegar to wszystko co ma robić ten układ.
Tu masz przykład jak przy pomocy klawiatury analogowej ustawić godzinę, w kilka sekund ustawiasz dowolną z dokładnością minuty (zmienna 24x60 1440), zegar w układzie 24h.
Podobnie można zrobić ustawienie daty, zmienna na 40 lat zmieści się w int16.
Kod: #include <AnalogKeypad.h>
// the following table is for this Banggood Analog Keypad
// https://www.banggood.com/AD-Analog-Keyboard-Module-Electronic-Building-Blocks-5-Keys-For-Arduino-DIY-p-1374279.html
// see the AnalogKeypad_CreateConfig.ino sketch example on how to create this table by Makuna
const int KeypadMap[] = {0, 50, 100, 200, 400};
const uint16_t KeypadHoldTimeMs = 1000;
const uint8_t KeypadAnalogPin = A0;
int16_t czasDobowy, czasWduszenia; //int by dalo sie krecic licznikiem przez 0
uint8_t lastbutton;
bool wduszony,update1;
//dla funkcji czas()
uint32_t czasTeraz,czasPoprzedni,tik=10; //tik musi byc mniejszy niz 1000 i dzilic 1000ms na rowne czesci
uint8_t nTik,sekundy,minuty,godziny,dni; //liczniki tikow, sekund, itd.
bool fnTik,fsekundy,fminuty,fgodziny,fdni; //flagi zdarzen nowy tik, nowa sekunda,minuta, godzina, dzien
char napis16[17];
AnalogKeypad keypad(KeypadAnalogPin, KeypadMap, countof(KeypadMap), KeypadHoldTimeMs);
// the button event callback
// this will be called when buttons are pressed and released
void ButtonHandler(const ButtonParam& param)
{
// Serial.print(param.button);
// Serial.print(" ");
//
lastbutton=param.button+1;
switch (param.state)
{
case ButtonState_Up:
// Serial.print("Up");
wduszony=0;
break;
case ButtonState_Down:
// Serial.print("Down");
break;
case ButtonState_Click:
// Serial.print("Click");
if(lastbutton==2) czasDobowy++;
else if (lastbutton==3) czasDobowy--;
update1=1;
break;
case ButtonState_DoubleClick:
// Serial.print("Double Click");
break;
case ButtonState_Hold:
// Serial.print("Hold");
wduszony=1;
break;
}
// Serial.println();
}
void setup() {
Serial.begin(115200);
// while (!Serial); // wait for serial attach
// Serial.println();
Serial.println("Initialized");
}
void loop() {
czas();
if(fnTik) //zamiast dely 10 to mozna sprawdzac stan przyciskow co 10ms
{
keypad.loop(ButtonHandler); //
keypadAction();
}
if(fsekundy or update1)
{
update1=0;
//tylko minuty
sprintf(napis16,"%02d:%02d",czasDobowy/60,czasDobowy%60); // jak zaminiec liczbe 0-1440 na godziny i minuty
Serial.println(napis16);
//sekundy w 10
// sprintf(napis16,"%02d:%02d:%02d",czasDobowy/(60*6),(czasDobowy%(60*6))/6,10*(czasDobowy%(6)) ); // jak zaminiec liczbe na godziny minuty sekundy w piatkach
// Serial.println(napis16);
}
// simulate other work happening
// it also should avoid long delays so loop above can be called
// at least every 10-20ms
// delay(10);
}
//wersja dla minut
void keypadAction()
{
//funkcja jest wywolywana co 10ms, ale chcę coś zrobic co 100ms
if(nTik%10==0) {
if (wduszony)
{ update1=1;
czasWduszenia++;
switch (lastbutton)
{
case 2:
if(czasWduszenia<30)czasDobowy++;
else if (czasWduszenia<120)czasDobowy+=10;
else czasDobowy+=60;
break;
case 3:
if(czasWduszenia<50)czasDobowy--;
else if (czasWduszenia<130)czasDobowy-=10;
else czasDobowy-=60;
break;
}
} else czasWduszenia=0;
}
if (czasDobowy>1440-1) czasDobowy=0;
if (czasDobowy<0) czasDobowy=1440-1;
//if (czasDobowy>(1440*6)-1) czasDobowy=0;
//if (czasDobowy<0) czasDobowy=((1440*6)-1);
}
void czas()
{
czasTeraz=millis();
fnTik=fsekundy=fminuty=fgodziny=fdni=0;
if((uint32_t)(czasTeraz-czasPoprzedni)>=tik) //tan napisany warunek jest odporny na "klątwe 50 dni millis()"
{
czasPoprzedni=czasTeraz;
fnTik=1;
nTik++;
if(nTik>=(1000/tik))
{
nTik=0;
sekundy++;
fsekundy=1;
if (sekundy>=60)
{
sekundy=0;
minuty++;
fminuty=1;
if (minuty>=60)
{
minuty=0;
godziny++;
fgodziny=1;
if (godziny>=24)
{
godziny=0;
fdni=1;
dni++;
}
}
}
}
}
}
RE: Pomoc w dopisaniu sterowania przyciskami ustawienia godzin minut i sekund w zegarze - ALIBABA-125 - 08-08-2022
Dziękuje za podpowiedź.
Ale jak to powiązać z załączonym na wstępie programem.
RE: Pomoc w dopisaniu sterowania przyciskami ustawienia godzin minut i sekund w zegarze - kaczakat - 08-08-2022
Nie napiszę Ci programu, który sobie wymarzyłeś, co najwyżej naprowadzę, czasami sprowadzę na manowce.
Jak przestaniesz używać delay, to nic nie trzeba wiązać, każdy blok programu wykonuje się czasowo niezależnie od pozostałych niepowiązanych i nie zakłóca czasu ich trwania. Wstawiasz w odpowiednie miejsca swoje zmienne, a gdy nie naciskasz przycisku przez np. 5s wysyłasz nastawę do zegara (albo jak masz więcej przycisków to przy wybraniu tego o funkcji "zapisz"). W samochodzie mam 1 przycisk i nim chodzę po całym menu, długie/krótkie naciśniecie w zależności od kontekstu wybiera opcje lub zmienia jej wartość, a pozostawienie bez działania zapisuje i wychodzi poziom wyżej.
Sprawdziłeś przykład, działa? Jak tak to już wiesz jak mierzyć czas od jakiegoś wydarzenia, jak sprawdzać czy trwało określony czas, jak to wykorzystać.
Z datą w jednej zmiennej jeszcze trzeba wmyślić jak sprawdzać rok przestępny, są o tym informacje w GOOGLE - czy jest podzielny przez 4,100,400, albo można wprowadzić ograniczenie do zakresu 2020-2060 i zostaje podzielność/4. Takie uproszczenie stworzyło "pluskwę milenijną".
|