logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Rozwiązano] Jak zmodyfikować kod Arduino, aby przycisk sterował trzema wyjściami?

Grzegorz Markowski 23 Lut 2019 17:48 1479 18
REKLAMA
  • #1 17799410
    Grzegorz Markowski
    VIP Zasłużony dla elektroda
    Posty: 5322
    Pomógł: 900
    Ocena: 751
    Cześć.

    Postanowiłem zastosować Arduino nano w roli wyłącznika uruchamiającego przekaźnik po naciśnięciu przycisku monostabilnego.
    Ponieważ z programowania jestem noga totalna, ściągnąłem kod, który włącza i wyłącza diodę LED przy naciskaniu przycisku.
    Po mozolnych modyfikacjach, działa on tak, że po uruchomieniu programu dioda stbyLED świeci. Po naciśnięciu przycisku gaśnie.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Problem polega na tym, że nie mam najmniejszych szans na to, aby ten kod przystosować do takiego działania.
    Dioda stbyLED świeci po uruchomieniu programu. Naciśnięcie przycisku powoduje wyłączenie diody stbyLED, włączenie diody onLED i włączenie przekaźnika rel.
    Ponowne naciśnięcie przycisku odwraca sytuację.
    Czyli przycisk ma działać na trzy wyjścia jednocześnie.

    Proszę o łopatologiczną pomoc.
  • REKLAMA
  • #4 18173795
    Grzegorz Markowski
    VIP Zasłużony dla elektroda
    Posty: 5322
    Pomógł: 900
    Ocena: 751
    Cześć.

    Program, który udało mi się sklecić działa jak potrzeba, ale ma jedną niedogodność związaną z właściwościami Raspberry Pi, do którego włączania i wyłączania służy. Włączenie jest OK. Ale wyłączenie już nie za bardzo, bo program odcina natychmiast zasilanie Raspberry, a to nie jest zalecane, bo w takim przypadku nie następuje właściwe zamknięcie systemu operacyjnego, mogą wystąpić błędy na karcie pamięci, a nawet uszkodzenie samej karty.
    Tak więc przy wyłączaniu RPi, program powinien najpierw wystawić sygnał wysoki na jednym z pinów Arduino, który posłuży do uruchomienia procedury zamykania systemu operacyjnego, a po odpowiedniej zwłoce czasowej potrzebnej do zamknięcia systemu, wyłączy zasilanie RPi.
    Proszę o wskazówki jak zmodyfikować załączony program? Stałe i inicjalizacje już dopisałem. Mam nadzieję, że dobrze. 😊

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #5 18173926
    kaczakat
    Poziom 34  
    Posty: 1748
    Pomógł: 317
    Ocena: 230
    Żeby odliczyć wyznaczony czas zamiast ustawiać od razu relay ustaw tryb pracy na wyłączanie i zapisz sobie stan millis, potem w loop jeśli tryb pracy jest wyłączanie odliczasz czas, gdy warunek się spełni ustawiasz zmienną stanu przekaźnika na low i zerujesz zmienną wyłączanie.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Z tym zapamiętaniem stanu przycisku previous raczej też jest coś nie tak, to powinno być ustawiane tam gdzie wykorzystujesz aktualny stan. Lub użyj gotowej biblioteki do drgań styków - bounce2 czy easy button.
    Lepiej byłoby odczytywać stan jakiegoś pinu z Raspberry, jeśli zakończy procedurę zamykania systemu odczytać z tego pinu 0 lub 1 (ustawić ten pin od strony Rb) i od tego momentu odliczyć jeszcze z 5s, po czym zamknąć.
    Pomogłem? Kup mi kawę.
  • REKLAMA
  • #6 18174013
    Grzegorz Markowski
    VIP Zasłużony dla elektroda
    Posty: 5322
    Pomógł: 900
    Ocena: 751
    Bardzo dziękuję za wskazówki. Czas zamykania systemu mogę dość precyzyjnie określić, bo pracuje na Raspberry system operacyjny, który zamyka się praktycznie zawsze w takim samym czasie. Po dołożeniu marginesu bezpieczeństwa powinno się obyć bez komunikacji RPi w stronę Arduino.
    Spróbuję wkomponować Twój kod do istniejącego i zobaczymy co z tego wyjdzie. :-)
  • #7 18174052
    simw
    Poziom 27  
    Posty: 757
    Pomógł: 94
    Ocena: 288
    Grzegorz Markowski napisał:
    Postanowiłem zastosować Arduino nano w roli wyłącznika uruchamiającego przekaźnik po naciśnięciu przycisku monostabilnego.
    Ponieważ z programowania jestem noga totalna, ściągnąłem kod, który włącza i wyłącza diodę LED przy naciskaniu przycisku.

    Do takiego projektu nie potrzebujesz arduino, przekaźnika ani mikrokontrolera.
    Wystarczy parę elementów RC, tranzystor CMOS oraz skrypt w linuksie.
    Tutaj:
    http://www.mosaic-industries.com/embedded-sys...projects/raspberry-pi/on-off-power-controller
    znajdziesz gotowy projekt włącznika/wyłącznika z symulacją działania takowego, na zasadzie podobnej z płyt ATX.
    No chyba, że tym projektem chcesz wejść w programowanie, to moja rada nie będzie na miejscu :)
  • REKLAMA
  • #8 18174353
    Grzegorz Markowski
    VIP Zasłużony dla elektroda
    Posty: 5322
    Pomógł: 900
    Ocena: 751
    Cytat:
    Z tym zapamiętaniem stanu przycisku previous raczej też jest coś nie tak, to powinno być ustawiane tam gdzie wykorzystujesz aktualny stan. Lub użyj gotowej biblioteki do drgań styków - bounce2 czy easy button.


    Jest nie tak, bo zamieściłem poprzednio nie ten kod programu co trzeba. :-( To znaczy, nie było to kod, którym zaprogramowałem Arduino, które obsługuje teraz RPi. Wstawiłem już właściwy.

    Odnośnie http://www.mosaic-industries.com/embedded-sys...projects/raspberry-pi/on-off-power-controller to nie chcę przerabiać istniejącego sterowania, przyciskiem i przez IR, bo działa to poprawnie.
    Wystarczy mi dołożenie funkcji w programie i jednego połączenia Arduino z RPi.

    Jak zmodyfikować kod Arduino, aby przycisk sterował trzema wyjściami?
  • REKLAMA
  • #10 18174654
    Grzegorz Markowski
    VIP Zasłużony dla elektroda
    Posty: 5322
    Pomógł: 900
    Ocena: 751
    Super! Bardzo dziękuję za kod. Skompilowałem, wgrałem do Arduino i działa, ale... odwrotnie. Włączenie przekaźnika, z pilota i przycisku, następuje po zwłoce czasowej, a wyłączenie natychmiast. Nie sprawdzałem jeszcze stanu na pin 7, a nie 6, bo 6 jest zajęty pod wejście sygnału z odbiornika podczerwieni.
    Teraz jest w kodzie:
    const int offPin = 7; // the number of the Off pin

    Próbowałem odwrócić działanie programu poprzez zmiany 1 na 0 w wylaczanie=1 i false na true w wylaczanie = false, ale to było zupełnie po omacku. :-( I nic nie dało.
  • #11 18174698
    kaczakat
    Poziom 34  
    Posty: 1748
    Pomógł: 317
    Ocena: 230
    Faktycznie, w oba miejsca przełączania skopiowałem !statestbyLED - digitalWrite(relPin, !statestbyLED); po prostu w zależności jaki stan włącza/wyłącza przekaźnik powinno być w z lub bez !. Zakładam, że led stbyLED jest włączona gdy ma się uruchomić i wyłączona gdy odlicza do wyłączenia zasilania.
    Pomogłem? Kup mi kawę.
  • #12 18174729
    Grzegorz Markowski
    VIP Zasłużony dla elektroda
    Posty: 5322
    Pomógł: 900
    Ocena: 751
    kaczakat napisał:
    ... Zakładam, że led stbyLED jest włączona gdy ma się uruchomić i wyłączona gdy odlicza do wyłączenia zasilania.


    Tak jest. stbyLED gaśnie w momencie włączenia przekaźnika i włącza się po wyłączeniu przekaźnika. Jej stan jest odwrotny do stanu przekaźnika.
  • #14 18174831
    Grzegorz Markowski
    VIP Zasłużony dla elektroda
    Posty: 5322
    Pomógł: 900
    Ocena: 751
    Jest jeszcze inaczej.
    Po wgraniu programu i restarcie Arduino, następuje natychmiastowe włączenie przekaźnika i diody stbyLED. To samo dzieje się po włączeniu napięcia zasilania Arduino.
    Naciśnięcie przycisku sprzętowego lub na pilocie po zwłoce czasowej wyłącza przekaźnik, ale dioda stbyLED wyłącza się od razu po naciśnięciu przycisku i również od razu włącza się dioda onLED. Diody włączają się odwrotnie niż poprzednio.
  • #15 18175075
    kaczakat
    Poziom 34  
    Posty: 1748
    Pomógł: 317
    Ocena: 230
    Po uruchomieniu/resecie jest włączony bo zmiennej statestbyLED przy deklaracji nadałeś stan HIGH, więc w kodzie od razu włącza podążający za jego stanem przekaźnik. Dioda led ma się wyłączać natychmiast, przekaźnik po opóźnieniu. Możesz sobie przenieść wyłączenie leda za wyłączenie przekaźnika (lub tylko statestbyLED = LOW; i wyłączy się w następnym obiegu loop), wtedy właśnie trzeba również odwrócić logikę dla przekaźnika !.
    Skompilowałem to u siebie, ale z drobnymi zmianami tak by na stykówce działało z dwoma ledami - 13 i 4, po naciśnięciu przycisku działa OK. Ja mam przycisk wewnętrznie podciągnięty do VCC, więc odwróciłem mu logikę:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    Pomogłem? Kup mi kawę.
  • #16 18175977
    Grzegorz Markowski
    VIP Zasłużony dla elektroda
    Posty: 5322
    Pomógł: 900
    Ocena: 751
    Kod z postu #9 z małymi zmianami i wszystko działa jak oczekiwałem. :-)

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Było: int statestbyLED = HIGH;
    Jest: int statestbyLED = LOW;

    Było:
    digitalWrite(stbyledPin, statestbyLED);
    digitalWrite(onledPin, !statestbyLED);

    Jest:
    digitalWrite(stbyledPin, !statestbyLED);
    digitalWrite(onledPin, statestbyLED);

    Teraz tylko wykoncypować jak wstawić funkcję, która przez 2 - 3 sekundy wystawi stan wysoki na pin 7 czyli offPin, zaraz po tym jak zostanie naciśnięty przycisk sprzętowy lub na pilocie, w celu wyłączenia RPi.
  • #17 18176173
    kaczakat
    Poziom 34  
    Posty: 1748
    Pomógł: 317
    Ocena: 230
    Wewnątrz tego ifa "if (wylaczanie)" wystarczy dodać kolejnego, który tym razem odliczy te 2-3 sekundy i zmieni stan z powrotem na niski. Ustawienie na stan wysoki trzeba wstawić tam, gdzie zaczyna się odliczanie, zaraz po odliczanie = millis();
    Pomogłem? Kup mi kawę.
  • #18 18176288
    Grzegorz Markowski
    VIP Zasłużony dla elektroda
    Posty: 5322
    Pomógł: 900
    Ocena: 751
    Poszedłem po najmniejszej linii oporu czyli zrezygnowałem z impulsu 2 - 3s na pin offPIN i:

    statestbyLED = LOW;
    wylaczanie=1;
    odliczanie = millis();
    digitalWrite(offPin, HIGH);

    oraz

    if( (uint32_t)(millis()-odliczanie)>=czasWylaczenia)
    {
    wylaczanie = false;
    digitalWrite(relPin, statestbyLED); //*edit2 - usunąłem !
    digitalWrite (offPin, LOW);

    Pełny kod

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Bardzo dziękuję za pomoc. Teraz dorobię jakiś klucz tranzystorowy do zwierania pinów RPi, zainstaluję skrypty i sprawdzę jak to będzie działać.

Podsumowanie tematu

✨ Użytkownik poszukiwał pomocy w modyfikacji kodu Arduino Nano, aby przycisk monostabilny mógł sterować trzema wyjściami: diodą LED, przekaźnikiem oraz dodatkowym pinem. Po wprowadzeniu zmian, kod działał, ale występowały problemy z logiką działania, w tym odwrotne stany diod i przekaźnika. Użytkownicy forum sugerowali poprawki, takie jak dodanie opóźnienia przy wyłączaniu zasilania Raspberry Pi oraz użycie zmiennych do kontrolowania stanów wyjść. Ostatecznie, po kilku iteracjach i wskazówkach, użytkownik zdołał dostosować kod, aby działał zgodnie z oczekiwaniami, w tym implementując odpowiednie opóźnienia i logikę dla przekaźnika.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA