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

ESP8266(wemos d1 mini) przerwanie stale alarmowane bez przyczyny.

grankee 07 Maj 2019 21:00 3609 33
Najlepsze odpowiedzi

Dlaczego przerwanie na D4 w Wemos D1 mini wyzwala się ciągle bez widocznej przyczyny i jak to naprawić?

Przyczyną jest użycie pinu D4, który w Wemos D1 mini jest powiązany z wbudowaną diodą LED i ma specyficzne zachowanie, więc nie nadaje się do takiej obsługi przerwań — szczególnie gdy w programie używasz `Serial.print()`/`Serial.println()`, bo te funkcje próbują sterować LED-em i generują nieokreśloną liczbę przerwań [#17951976][#17953994] Najprostsze rozwiązanie to przenieść przycisk/encoder na inny pin; w wątku sugerowano, że D5–D8 są mniej kłopotliwe, a jeśli brakuje pinów, można użyć ekspandera PCF8574 [#17952001][#17955554] Warto też pamiętać, że D3 ma już zewnętrzny pull-up, więc on również może sprawiać problemy w podobnych zastosowaniach [#17952111] Jeśli chcesz całkiem pozbyć się niechcianego łączenia z Wi‑Fi po flashowaniu, można wymazać pamięć ustawień (`blank.bin`) albo wyłączyć auto-connect przez `WiFi.setAutoConnect(false)` [#17949613][#17949632]
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA
  • #1 17949097
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    Witam. Mam problem z przerwaniem, które samo się alarmuje bez powodu.
    Przerwanie to obsługuje encoder, podłączony jest do pinu D4, jako wciśnięcie knoba (kręcenie na pinach D3 i D5). Biblioteka Encoder. Wszystko działało dobrze do momentu, kiedy dołączyłem działanie wifi w trybie STA. Po wywaleniu tego kodu problem nie ustąpił, dopatrzyłem się, że esp pomimo wywalenia kodu nadal się łączy z zapamiętaną siecią, więc skompilowałem kod z linijką wifi.mode(OFF), a następnie znów mój kod. Moduł przestał się łączyć, ale dalej przerwanie alarmowane jest prawdopodobnie "co klatkę"(b. szybki spam na serial monitorze). W przerwaniu żadnego obciążenia nie ma, jedna linijka zmieniająca wartość zmiennej globalnej typu uint8_t - tyle. Przełączenie przerwania na inny pin sprawia, że nie działa ono wcale. Mam prostą funkcję, która liczy "klatki" i normalnie jest to blisko 500 000 na sekundę, ale jak dołączę do tego obsługę encodera (sprawdzanie co klatkę czy nastąpiła zmiana stanu, a następnie ignorowanie sprawdzanie jeśli nie minelo 50ms (debouncing) i ponowne sprawdzenie stanu po szumach) to spada do wartości konsolowej, czyli 30fps.
    Próbowałem zewnętrzny pullup 10kilo, dołaczyłem kondensator 1000uF, odłączyłem encoder od pinu, bez zmian. Sprawdziłem nawet za pomocą arduino, pinu analogowego i kreślarki w arduino IDE (prowizoryczny oscyloskop) jak wygląda stan pinu D4 na esp i jest ok, jak wcisnę encoder spada na ok. 60 (ok.0.29V) a jak puszczę to stan pinu trzyma się na jednym poziomie bez nawet specjalnych szumów na ok 680(3.32V) (arduino na 5V).

    Co może być przyczyną ew. jakie jeszcze dane potrzebne.
  • REKLAMA
  • #2 17949132
    Konto nie istnieje
    Poziom 1  
  • #3 17949613
    Slawek K.
    Poziom 35  
    Posty: 3020
    Pomógł: 259
    Ocena: 1303
    Aby pozbyć się łączenia z wifi, wgraj "blank.bin" który znajdziesz w sieci, u Ciebie wersja 4M. Nadpisze on obszar flash w którym zapisane są dane do obsługi połączenia z wifi. Następnie wgraj swój kod (ten bez obsługi wifi).
    To rozwiąże cześć Twojego problemu, o pozostałej napisał @khoam

    Pozdr
  • #4 17949632
    sylweksylwina
    Moderator - Komputery Serwis
    Posty: 13209
    Pomógł: 1881
    Ocena: 2349
    Nie chcesz auto łączenia z WiFi to masz funkcję WiFi.setAutoConnect(false);
    W narzędziach arduino pod pozycją Erase Flash możesz wybrać by za każdym wgraniem szkicu kasowało cały flash (jak wyżej).
    Jak masz długie pętle z dużą ilością instrukcji użyj w każdej iteracji yield(); lub delay(0); unikniesz tym wyzwolenia watchdoga. Zawsze można wyłączyć watchdoga software (nie zalecane) ESP.wdtDisable(); ale watchdog hardware dalej będzie działał.
  • #5 17949884
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    Ok wybrałem nadpisywanie całej pamięci flash przy wgrywaniu sketchu, dzięki za podpowiedź.
    khoam napisał:
    Chyba chodzi o watchdog? Musisz zatrzymać monitor szeregowy, kiedy się pojawiają logi i wkleić tutaj informację o przyczynach WD - zwykle jest to dość pomocna informacja. Pod tym linkiem masz informację na temat diagnozowania przyczyny wystąpienia WD w ESP8266:

    Popraw mnie jeśli się mylę, ale watchdog to jest to co restartuje moduł gdy ten się zawiesi albo coś. Wtedy wyskakują stack trace i restart log. Rzecz w tym, że mi się tak nie dzieje. Nie mam restartów. Chodzi o przerwanie (interrupt) zarejestrowane na pinie D4, które samo się wywołuje non stop.
    Mała poprawka, tam gdzie pisałem, że pętla śmiga 500 000 razy na sekundę śmiga 50 000 a tam gdzie pisałem że 30 tam śmiga 3.
    Ponadto jeśli zakomentuję //attachInterrupt(D4, handleKey, RISING); to wraca do swojej prędkości, ale przestaje działać i wciśnięcie encodera i kręcenie nim pomimo, że kręcenie pracuje na osobnych pinach D3 oraz D5.
    Najbardziej mnie irytuje fakt, że to wszystko działało na tym kodzie jak trzeba, a przestało działać jak tylko dołączyłem wifi, natomiast nie zaczęło działać nazad jak wifi usunąłem.
    Cały kod ma tysiące linijek (oczywiście nie w samej pętli loop), postaram się wkleić te istotne:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    [/code]
  • #6 17950187
    Konto nie istnieje
    Poziom 1  
  • #7 17950467
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    Nic to nie zmieniło. HandleEncoder jedynie sprawdza czy zmienna została zmieniona, nic tam nie wpływa na samo działanie interrupt'a. ponadto w Encoder.h obie funkcje są używane wielokrotnie więc to kiedy ja ich użyje i tak raczej zostanie nadpisane. Oto zawartość Encoder.h:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Encoder.cpp:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #8 17950521
    Konto nie istnieje
    Poziom 1  
  • #9 17950840
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    Po wyłączeniu obsługi na pinach D3 oraz D5 (kręcienie lewo prawo) nadal to samo. Mam wrażenie, że szybciej się to dzieje. Skutkiem kliknięcia jest przeskakiwanie po elementach menu widoczne na wyswietlaczu OLED, wydaje mi sie, ze szybciej przeskakuje.
    Przerwania na D3 i D5 mogą mieć wpływ na przerwanie na D4? Mi cały czas nie daje spokoju dlaczego wcześniej to działało. Przypominam sobie, że kiedyś miałem problemy ze sterowaniem pinami w ESP. Czasem było tak, że pin działał normalnie, ale jak np. zacząłem coś robić na innym pinie, to ten pierwszy przestawał działać. Tzn przykładowo jak pin D1 nie był w użyciu to z pinem D2 mogłem robić co chcę, ale jak D1 ustawiłem w stan wysoki to już nie mogłem sterować pinem D2. Takie cuda się działy, do dziś nie wiem dlaczego, oczywiście numerów pinów nie pamiętam, podałem przykładowe. Tutaj problem jest o tyle dziwniejszy, że w ogóle nic nie podłączałem ani nie odłączałem, nawet nie zmieniałem nic związanego z pinami. W arduino nic takiego sie nigdy nie działo tylko esp bzikuje.
  • #10 17950850
    Konto nie istnieje
    Poziom 1  
  • #11 17950867
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    Próbowałem inny pin, ale wtedy nie działa wcale. Wydaje mi się, że inne piny mogą nie obsługiwać przerwań.
    Rotary Encoder Module KY-040 Arduino / PIC / PI
    Nie chcę podawać linka, bo o ile pamiętam zabronione.
    Jednak nie ma to chyba znaczenia, bo nawet jak go odłącze od pinu D4 to nic nie zmienia. Tak jak pisałem wyżej, to nie stan pinu wpływa na wyzwolenie przerwania. Mierzyłem arduino + kreślarką z portu szeregowego stan pinu D4 przy odłaczonym encoderze i jest tam ciągle stan wysoki.
  • #12 17950876
    Konto nie istnieje
    Poziom 1  
  • #13 17951549
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    Niestety dalej bez zmian. Tak tak, ja wiem że odłączenie nie powoduje wyłączenia usługi, chodziło mi tylko o to, że bez znaczenia jaki mam encoder, bo to nie on powoduje problem, czego dowodem jest fakt, że jak go odłączę to nic nie zmienia.
  • #14 17951615
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #15 17951660
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    Hmmm pytasz w którym miejscu kodu a jednocześnie mówisz, że nie pytasz o ten fragment, no bo false jest przypisywane właśnie tam.
    Przerwanie na pinie ustawia wartość true, natomiast loop co obieg wykonuje funkcję HandleEncoder(), w której zawarte jest
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    i to w tym momencie jest ustawiana wartość false.
    Rozumiem, że chcesz zasugerować, że ustawianie true/false się zapętla przez błędny kod, a to wywołuje efekt spamu funkcjami, ale pozostają dwa pytania, dlaczego wcześniej działało dobrze, a przestało mimo, że tego akurat fragmentu kodu nie zmieniałem? Drugie pytanie to takie, dlaczego jak zmienię ustawianie tej zmiennej
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

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

    to oczywiście na oledzie przestaje przeskakiwać menu, bo usunąłem reakcję tego menu na przerwanie, ale serial monitor spamuje mi zmienną count w tempie ok. 800/s. W tym przypadku odciąłem jakikolwiek wpływ tej zmiennej na zachowanie przerwania. Odłączyłem też kabelek encodera od pinu D4. Teraz przerwanie wywołuje jedynie spam na serial monitorze. Dodam, że podpięcie pinu D4 do 3.3V albo masy nic nie zmienia. Z resztą, jego stan był wcześniej badany i nie widać tam żadnych zmian, ale dla pewności sprawdziłem takie dwie opcje.
    Oczywiście sprawdzałem na innym wemos i działa to tak samo.
  • #16 17951668
    Konto nie istnieje
    Poziom 1  
  • #17 17951733
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    khoam napisał:
    Zamiana zmiennej isButtonPressed na licznik count w obsłudze przerwania w niczym tu nie pomoże.

    Pewnie nie pomoże w kwestii poprawności operowania tą zmienną, ale pomoże o tyle, że w ogóle się tej zmiennej pozbywamy z zagadnienia problemu. Ponieważ nie bierze już ona udziału w przerwaniu to przyczyną problemu na pewno nie była bądź nie była jedyną. Nawiasem mówiąc zmienna isButtonPressed jest ustawiana na true tylko w tym przerwaniu, przy definicji jest ustawiana na false.
    Jeśli jednak odłączamy zmienną (której zmiana wartości nawiasem mówiąc i tak nie była przyczyną wywołania przerwania, tylko jej skutkiem), odłączymy encoder od pinu, zewrzemy pin do masy, zasilania bądź zostawimy niepodłączony (co jest niebezpieczną opcją, bo jego stan zależy teraz od masy czynników, na które nie ma wpływu) to przerwanie dalej się wywołuje nieproszone i to jest kluczowy problem.
  • Pomocny post
    #18 17951755
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #19 17951817
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    khoam napisał:
    To już trochę wygląda na voodoo

    Z rzeczami z tego świata zwykle sobie radzę :D
    khoam napisał:
    Na pewno użyłeś digitalPinToInterrupt()?

    tak
    khoam napisał:
    Próbowałeś na innym pinie niż D4?

    grankee napisał:
    Przełączenie przerwania na inny pin sprawia, że nie działa ono wcale.


    khoam napisał:
    Może lepiej przenieść ją do loop() - wtedy jest większa kontrola nad rozróżnieniem stanów włączony/wyłączony i lepiej panuje się nad bouncingiem.

    To było pierwsze rozwiązanie, jakie próbowałem zastosować w ogóle, ale wystąpił tam opisywany wyżej problem, tj. odczyt stanu pinu w programie nie był prawdziwy. Stan był ciągle LOW albo HIGH, już nie pamiętam, mimo że fizyczny odczyt stanu pinu mówił co innego. Był też ten problem co wyżej opisywałem, że jak zacząłem robić coś na kolejnym pinie to ten co do tej pory działał- przestawał działać i nie dało się albo ustawić stanu albo odczytać go prawidłowo. Obsługa encodera w taki sposób jak teraz była jedynym działającym rozwiązaniem, teraz już nie jest.
    khoam napisał:
    Czy obsługa tego przycisku jest wyjątkowo krytyczna tzn. reakcja na naciśniecie musi następować błyskawicznie?

    Ciężko powiedzieć, wiesz, encoder służy do poruszania się po menu i zmiany ustawień więc musi działać na tyle szybko, żeby to odbywało się płynnie. W obsłudze ds18b20 w bibliotece są delaye kilkadziesiąt ms i musiałem to przeprogramować, żeby je wywalić, bo dawało się to odczuć, że czasem przekręcenie encodera nie zatrybiło. Nie pamiętam czy klikanie też. Teraz ds18 działa na podobnej zasadzie jak debouncing, odlicza x czasu od ostatniej akcji i wykonuje nastepna jesli minelo to x czasu, w ten sposob pozbylem sie delaya w ogole.
  • Pomocny post
    #20 17951854
    Konto nie istnieje
    Poziom 1  
  • #21 17951925
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    Ok, co prawda na pinie D4 nie działa, ale przełączyłem na pin D7 i działa naciśnięcie. Teraz pojawia się problem z kręceniem lewo prawo. Kręcenie encoderem nie działa jak przycisk, tylko porównuje się stan jednego pinu podczas zmieny stanu drugiego, zatem najlepiej byłoby zarejestrować oba piny od kręcenia jako buttony i porównywać stan jednego podczas zmiany stanu drugiego z nich, aby ustalić czy kręcę w lewo czy w prawo, czy masz jakiś lepszy pomysł jak mogę to zrobić?

    //edit poczekaj bo niby nie działa, ale działa 1/1000 przekręceń, muszę posprawdzać gdzie jest problem.
    //edit dobra, tym razem problem jest w moim kodzie, bo jak na sucho wklepie serial.println do kazdego wykrycia przekrecenia to spamuje ladnie, zatem będę z tym walczył. Problem naciśnięcia encodera wydaje się być na razie rozwiązany, chociaż jeszcze wątek zostawię do momentu aż uruchomię wifi nazad i upewnię się że dalej działa.
    Problemem pozostaje nadal niedziałający jak należy pin D4, nie działał mi na nim easybutton, w ogóle nie wykrywa zmiany stanu pinu. Nie da się też odczytać jego stanu, bo ciągle pokazuje HIGH. Co ciekawe, jako że to pin wbudowanego LEDa to mogę stwierdzić, że stan faktycznie się zmienia co sygnalizuje zapalanie i gaśnięcie LEDa. Ponadto digitalWrite nie jest w stanie zmienić stanu pinu. Ciągle high. rzecz jasna używam funkcji pinMode
  • Pomocny post
    #22 17951976
    Slawek K.
    Poziom 35  
    Posty: 3020
    Pomógł: 259
    Ocena: 1303
    Pin D4 to chyba najgorszy mozliwy pin jaki mogłeś wybrać. Na tym pinie jest TX1 i jest w stanie wysokim, rowniez podczas bootowania, i do tego jest na nim led.
    Tu masz tabele prawdy dla GPIO na esp8266 https://www.letscontrolit.com/wiki/index.php?title=Configuration

    Pozdr
  • #24 17952001
    Slawek K.
    Poziom 35  
    Posty: 3020
    Pomógł: 259
    Ocena: 1303
    Poniewaz z zainteresowaniem sledze merytoryczna dyskusje w tym watku, wiec bede wdzieczny za feedback czy pomogło. W swoich projektach generalnie poruszam sie w pinach D5-D8, chyba ze potrzebuje wiecej to wybieram dodatkowe z tych najmniej klopotliwych.

    Pozdr
  • #25 17952006
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    wygląda na to, że d3 odmówił posłuszeństwa razem z d4. D5 i D7 używam dla encodera i jednego pinu mi brakuje jeszcze. D6 obsługuje termometr ds18b20, D1 i D2 I2C. Brak pinów :( mam podłączony PFC, ale nie udało mi się odczytać faktycznego stanu pinu, używam tylko jaki wyjść. Any ideas?
  • #26 17952024
    Slawek K.
    Poziom 35  
    Posty: 3020
    Pomógł: 259
    Ocena: 1303
    Spróbuj D11 lub D12, ew. D8 do wykrywania zbocza narastajacego czyli pin zwierany do vcc, bo ma pulldown.

    Pozdr
  • #27 17952111
    Konto nie istnieje
    Poziom 1  
  • #28 17952211
    Slawek K.
    Poziom 35  
    Posty: 3020
    Pomógł: 259
    Ocena: 1303
    Spróbuj DS18B20 przepiąć pod D3, a na D6 odpal button.

    Pozdr
  • #29 17952654
    grankee
    Poziom 9  
    Posty: 56
    Ocena: 4
    khoam napisał:
    Jaki parametr przekazujesz do pinMode() dla D3 i D4?

    pinMode(D4,INPUT);
    INPUT_PULLUP też nie działa.
    khoam napisał:
    Jak zdefiniowałeś konstruktor EasyButton dla pinu D4?

    EasyButton leftEnc(LEFT_PIN,35,false);

    Tu chodzi o to, że nawet jak nie użyję easybutton tylko po prostu w loop sprawdzam stan pinu to się on nie zmienia. Raz tylko przy włączeniu wypluwa jedyneczkę, potem cisza, a zwieram go na przemian do masy i vcc
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Slawek K. napisał:
    Spróbuj D11 lub D12

    nawet nie są wyciągnięte
    Slawek K. napisał:
    Spróbuj DS18B20 przepiąć pod D3, a na D6 odpal button.

    nie działa na pinie d3
    khoam napisał:
    Ten sam problem, co z D4. Patrz wyżej. D3 też ma już zewnętrzny rezystor podciągający do zasilania.

    Ok, ale nie mogę zrozumieć dlaczego to przeszkadza w działaniu. Przecież np. w arduino wszystkie piny mają wbudowany wewnętrzny pullup i można go zawsze użyć, a jednak piny działają. Myślałem, że zadaniem pullup'u jest ustawienie stanu na konkretny, wysoki, po to żeby nie był losowy pod działaniem zakłóceń, a nie całkowite wyłączenie pinu z użytku. Gdyby tak miało być to kto i po co wyprowadzałby go na zewnątrz? Dlaczego one wcześniej działały? Dlaczego skoro pin D4 ma pullup to przerwanie było wykrywane non stop, przecież przerwanie miało zostać zaalarmowane przez zbocze narastające, a nie stan wysoki, a tam był stan wysoki ciągle.

    //edit udało mi się odczytywać stan pinów w PFC, problem jest jednak taki, że odczyt stanu pinu co 1 obieg loopa spowalnia ESP z 37000 wykonań na sekundę do 3500 czyli ok 11razy. Wszystkie nieużywane piny nie działają.
    //edit Doszukałem się pinu interrupt w PFC, i nawet działa, problem w tym że jak zwieram do masy jakiś pin to OLED zaczyna wypluwać przez chwilę krzaki (działa na ten samej magistrali I2C do PFC).
    //edit ok wygląda na to, że jak odczytuję po prostu stan na d5 i reaguję na jego zmianę to wyswietlacz nie swiruje (wczesniej probowalem interruptem)

    //edit działa encoder na pfc razem z siecią.

    Dodano po 17 [godziny] 2 [minuty]:

    Podsumowanie:
    pinów D3,D4 (mimo, że wcześniej działały) oraz D0 i D8, a przy okazji również A0 nie udało mi się doprowadzić do działania. Stan na nich jest ustawiony taki a nie inny i nie idzie z tym nic zrobić :( jak ktoś ma jeszcze jakieś pomysły to zamieniam się w słuch.

    Encoder podłączony do PFC, jakby komuś było trzeba to napisałem mini bibliotekę, pewnie nie jest perfekcyjna, ale działa. Skoro już temat założony, to może ktoś inny skorzysta.
    https://github.com/grankee/Encoder_pfc8574

    Jak nie dokręcisz encoderem w jedną stronę pełnego skoku i cofniesz to zadziała jak przekręcenie w drugą stronę. Nie miałem czasu ani potrzeby analizować wszystkich 4 kroków encodera, żeby ten efekt wyeliminować, bo jak się używa normalnie to jest ok.
  • Pomocny post
    #30 17953994
    Konto nie istnieje
    Poziom 1  

Podsumowanie tematu

✨ Użytkownik zgłasza problem z nieustannym wywoływaniem przerwania na pinie D4 w module ESP8266 (Wemos D1 Mini), które jest podłączone do enkodera. Po dodaniu funkcji WiFi w trybie STA, przerwanie zaczęło działać nieprawidłowo, mimo usunięcia kodu WiFi. Użytkownicy sugerują różne rozwiązania, w tym użycie funkcji `WiFi.setAutoConnect(false)`, nadpisanie pamięci flash za pomocą "blank.bin", oraz zastosowanie `digitalPinToInterrupt(D4)` w funkcji `attachInterrupt`. Wskazano również, że pin D4 jest problematyczny z powodu podłączenia do diody LED oraz interakcji z funkcjami `Serial.print()`, co może generować niepożądane przerwania. Użytkownik rozważa również użycie innych pinów, takich jak D7, oraz alternatywnych mikrokontrolerów z większą liczbą dostępnych pinów.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA