Zainstaluj sobie bibliotekę EasyButton i spróbuj użyć z tymi przyciskami, to Ci wrzucę na bazie tego potem jakiś przykład.
Kod:
#include <EasyButton.h>
#define BUTTON_UP 2
#define BUTTON_DOWN 3
EasyButton buttonUP(BUTTON_UP);
EasyButton buttonDOWN(BUTTON_DOWN);
void onPressedUP() {
Serial.println("ButtonUP has been pressed!");
}
void onPressedDOWN() {
Serial.println("ButtonDOWN has been pressed!");
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);
digitalWrite(A4, LOW);
digitalWrite(A5, LOW);
buttonUP.begin();
buttonUP.onPressed(onPressedUP);
buttonDOWN.begin();
buttonDOWN.onPressed(onPressedDOWN);
}
void loop() {
buttonUP.read();
buttonDOWN.read();
}
Jak masz ogarnięte przyciski, to ja sobie zawsze dodaję formatkę czas, można to zrobić na wiele sposobów by zarządzać czasem, mi to pozwala obserwować, czy program się coś tam rusza, czy się nie zresetował, czy czas w nim płynie, jest zliczany i ciągle rośnie:
Kod:
#include <EasyButton.h>
#define BUTTON_UP 2
#define BUTTON_DOWN 3
EasyButton buttonUP(BUTTON_UP);
EasyButton buttonDOWN(BUTTON_DOWN);
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 napis[10];
void onPressedUP() {
Serial.println("ButtonUP has been pressed!");
}
void onPressedDOWN() {
Serial.println("ButtonDOWN has been pressed!");
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
digitalWrite(A4, LOW);
digitalWrite(A5, LOW);
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);
buttonUP.begin();
buttonUP.onPressed(onPressedUP);
buttonDOWN.begin();
buttonDOWN.onPressed(onPressedDOWN);
}
void loop() {
czas();
if (fnTik)
{
buttonUP.read();
buttonDOWN.read();
}
if(fsekundy) {
sprintf(napis,"%03d:%02d:%02d",godziny,minuty,sekundy);
Serial.println(napis);
}
}
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++;
}
}
}
}
}
}
Tu są te flagi, to po prostu zmienne, które sobie w każdym loop zeruje, ale w wybranych, gdy od poprzedniego ustawienia minęło 10ms (taką sobie ustawiłem tu najmniejszą rozdzielczość i to wystarcza do sprawdzania stanu przycisków), 1s, 1m, 1h. W tym konkretnym obiegu loop, gdy jest nowa sekunda, minuta, flaga ma wartość 1 i coś z tym można zrobić. Prostymi operacjami można też sobie też to dalej rozwijać, gdy jest np. nowa sekunda, ale co czwarta, albo tylko 37 w każdej minucie.
Ze zmiennymi do napięcia, to można oczywiście użyć float, ale lepiej w takim małym uC użyć zmiennej, która tak nie zamula. Napięcie można określić jako 2.345V, albo jako 2345mV, a do max 5V wystarcza zmienna int16, czyli o zakresie +/-32 tysiące. Niestety zakres przy obliczeniach by się przekręcił, więc trzeba dać int32, ale i tak jest szybciej niż z float. W Arduino to zresztą nie ma dużego znaczenia, tu wszędzie się wstawia floaty w bibliotekach, czasem to kuleje, ale nie ma musu z tego korzystać. Dodalem parę funkcji dla zaciemnienia całości i teraz by wystartować silnik wystarczy wcisnąć UP, nazwałem, że silnik ruszy w prawo przy takim ustawieniu pinów, bo nie pokazałeś schematu i tak to wygląda:
Kod:
#include <EasyButton.h>
#define BUTTON_UP 2
#define BUTTON_DOWN 3
EasyButton buttonUP(BUTTON_UP);
EasyButton buttonDOWN(BUTTON_DOWN);
uint32_t napiecieWylaczenia=3456,napiecieMierzone; //mV
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 napis[10];
bool fButtonUP, fButtonDOWN, fSilnikStart,fSilnikStop;
void onPressedUP() {
Serial.println("ButtonUP has been pressed!");
fSilnikStart=1;
}
void onPressedDOWN() {
Serial.println("ButtonDOWN has been pressed!");
}
void silnikRunR ()
{
digitalWrite(A4, LOW);
digitalWrite(A5, HIGH);
}
void silnikRunL()
{
digitalWrite(A4, HIGH);
digitalWrite(A5, LOW);
}
void silnikStop ()
{
digitalWrite(A4, LOW);
digitalWrite(A5, LOW);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
digitalWrite(A4, LOW);
digitalWrite(A5, LOW);
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);
buttonUP.begin();
buttonUP.onPressed(onPressedUP);
buttonDOWN.begin();
buttonDOWN.onPressed(onPressedDOWN);
}
void loop() {
czas();
if (fnTik)
{
buttonUP.read();
buttonDOWN.read();
}
// skoro mierzyles napiecie co 500ms, to zakladam, ze co 100ms bedzie jeszcze lepiej
if(fnTik and nTik%10==0) //czyli co nowy tik i gdy jednoczesnie liczba tikow jest podzielna przez x bez reszty, co x*fnTik ms
{
napiecieMierzone = 5000UL*analogRead(A0) /1023;
Serial.println(napiecieMierzone);
}
if(fsekundy) {
sprintf(napis,"%03d:%02d:%02d",godziny,minuty,sekundy);
Serial.println(napis);
}
if( fSilnikStart and napiecieMierzone<napiecieWylaczenia) //jesli zostal wcisniety przycisk i napiecie jest ponizej
{
silnikRunR();
}
else //zatrzymanie silnika i wyzerowanie flagi startu
{
silnikStop();
fSilnikStart = 0;
}
}
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++;
}
}
}
}
}
}
Ale skoro nie umiesz programować to nie przewidziałeś wszystkiego i to nie jest wszystko co powinien robić program, sterownik jest na kilkadziesiąt amperów, takiego silnika nie powinno się ot tak zatrzymać, raczej hamować, nie można zmienić kierunków obrotów w każdej chwili, raczej trzeba najpierw zatrzymać silnik. Powinno się też dać wyłączyć silnik również przyciskiem, może być ten sam, raz się wciska to silnik rusza, drugi raz zatrzymuje, teraz z tą biblioteką nie ma też problemu, że będą drgania styków i że silnik dostanie czkawki co ma robić tysiąc razy/s po jednym dotknięciu przycisku. Powinien być WDT, by w razie zawieszenia zrobił reset i wystartował program od nowa.