Problem z watchdogiem

Masz problem z Raspberry Pi? Tutaj możesz szukać pomocy.
ODPOWIEDZ
Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Problem z watchdogiem

Post autor: Cristiano1989 » 15 lut 2016, 22:48

Witam,

Niestety napotkałem problem przy zabawie z Watchdogiem. Chciałem go wywołać w momencie gdy dostanie przerwanie. Wszystko według mnie powinno działać lecz niestety arduino resetuje się cały czas :-/

Mój problem polega na tym że nie jestem w stanie teraz wgrać do niego poprawek po na etapie wgrywania arduino resetuje się do chwile wywołując błąd wgrywania.

Proszę o jakieś sugestie jak mogę rozwiązać ten problem

Pozdrawiam

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Re: Problem z watchdogiem

Post autor: Cristiano1989 » 16 lut 2016, 09:05

a jakim przerwaniem?
Ogólnie to łącze dwa arduino za pomocą seriala. Wszystko działa fajnie do pewnego momentu w którym arduino wysyłające wpada w jakiś dziwny stan i przestaje wysyłać. Gdy na arduino odbierającym wykrywam ten stan (przez 30 sekund nic nie dostaje) ustawiam pin w arduino odbierającym na wysoki. Ten pin jest wpięty do pinu 2 (przerwanie 0) na arduino wysyłającym co według zamysłu miało wywołać przerwanie i aktywować funkcję watchdoga. Niestety coś zrobiłem nie tak (mogłem ustawić żeby przerwanie uruchamiało się przy stanie wysokim, a użyłem opcji żeby przerywał gdy stan się zmieni). Niestety efekt tego jest taki że arduino resetuje się w kółko uniemożliwiając mi zaprogramowanie poprawek :-/

Czy jest jakiś sposób żeby przyzerować pamięć flash arduino tak żeby został sam bootloader?
Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Re: Problem z watchdogiem

Post autor: Cristiano1989 » 16 lut 2016, 10:19

no a pomysl, zeby na sztywno podac na pin 2 stanu niskiego (w tym przypadku) nie dziala?
Jest to dobry pomysł i będę próbował go zastosować po powrocie do domu :) Mam nadzieję że to pomoże...

A gdyby to nie zadziałało to jest jakiś inny sposób na zatrzymanie watchdoga?

Czysto teoretycznie czy gdyby ktoś ustawił reset watchdoga w pętli głównej programu i wgrał go to byłoby już po arduino czy jest jakiś sposób na wgranie programu?
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Problem z watchdogiem

Post autor: stiven » 16 lut 2016, 11:30

Reset watchdoga daje się właśnie w pętli głównej. Ty źle zrozumiałeś jak działa watchdog, reset watchdoga jest po to, żeby nie doszło do resetu mikrokontrolera, dlatego daje się go do pętli głównej. Najpierw (w setup) ustawia się czas, po jakim watchdog ma zrobić reset mikrokontrolera i jeśli przed tym określonym czasem watchdog nie będzie resetowany, to watchdog zresetuje mikrokontroler. Jak dałeś ten reset do przerwania, to nie ma resetów watchdoga, więc watchdog resetuje mikrokontroler. Żeby teraz udał się ten pomysł z przerwaniem, to stan niski nic nie da, musiałby to być przebieg zmieniający się częściej niż czas jaki był ustawiony dla watchdoga. Wgraj do tego drugiego arduino taki program i połącz te dwa arduino pinami 2.

Kod: Zaznacz cały

void setup()
{
  pinMode(2, OUTPUT);
}

void loop()
{
  digitalWrite(2, LOW);
  digitalWrite(2, HIGH);
}


Jak się to nie uda, to może zewnętrzny programator by pomógł, bo innego pomysłu nie mam.


A żeby stworzyć takie resetowanie jednego arduino przez drugie, to można było to zrobić na pinie reset po prostu. Drugie arduino podawałoby stan niski na pin reset, żeby je zresetować. Jest też możliwość programowego resetu, więc zamiast użyć watchdoga, co było bez sensu w tym przypadku, to w momencie przerwania, a nawet nie musiałoby to być przerwanie, tylko zwykłe wykrycie stanu na pinie, wywołać funkcję resetującą. http://www.instructables.com/id/two-way ... /?ALLSTEPS

A z doświadczenia wiem, że przy połączeniu dwóch arduino najlepszą funkcją do odbierania jest Serial.readStringUntil(). Jak się używa funkcji odczytującej pojedyncze znaki, to właśnie po jakimś czasie przestaje to działać. Ja w arduino wysyłającym po wysłaniu danych, wysyłam jeszcze przecinek ',' i w arduino odbierającym odbieram przez Serial.readStringUntil(',') do stringa i mam w tym stringu zapisane wszystko, co było wysłane przed przecinkiem ','. Można też w ten sposób wysłać kilka danych/zmiennych oddzielonych przecinkami i dla każdej danej osobno wywołać Serial.readStringUntil(','), dzięki czemu te dane będą w osobnych stringach.

EDIT
W internecie znalazłem takie rozwiązanie
http://stackoverflow.com/questions/5286 ... inite-loop
Remove the USB connection, close the IDE, open the IDE, open BareMinimum, hold the reset button, plugin the USB connection, click the upload button 1/2 a second after removing your finger from the reset button.
BareMinimum to program składający się tylko z pustej funkcji setup i pustej pętli loop, pewnie chodzi o to, że najszybciej się wgra taki kod.
https://www.arduino.cc/en/Tutorial/BareMinimum

Kod: Zaznacz cały

void setup() {
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:
}
Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Re: Problem z watchdogiem

Post autor: Cristiano1989 » 16 lut 2016, 13:19

Dziękuję za propozycje naprawy mojego problemu.

Wieczorem będę miał okazje sprawdzić czy uda się zaprogramować cokolwiek.
Drugie arduino podawałoby stan niski na pin reset, żeby je zresetować
Bawiłem się z tym pinem ale w mimo że na starcie ustawiałem stan tego pinu na wysoki to program się jakby nie rozpoczynał. Dopiero odłączenie tego pinu uruchamiało program. Nie wiem być może trzeba by to przez jakiś rezystor podłączyć?

Znalazłem też gdzieś w internecie jakiś jump napisany w assemblerze który rzekomo ma restartować arduino. Czy to faktycznie działa?
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Problem z watchdogiem

Post autor: stiven » 16 lut 2016, 13:30

Dałem Ci linka, gdzie jest prosty kod, właściwie jedna linia kodu do programowego resetowania Arduino, ten drugi sposób co tam jest po sposobie z pinem reset. Piszę z telefonu, to samego kodu nie wkleję.
Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Re: Problem z watchdogiem

Post autor: Cristiano1989 » 16 lut 2016, 21:32

Zasiadłem do sprawdzenia waszych propozycji ale nie zdążyłem tego zrobić ponieważ problem niejako sam się rozwiązał :)

Podpiąłem samo arduino z zapętlonym Watchdogiem i o dziwo nie resetował się(arduino sterujące nie było podłączone przez co nie wywoływało przerwania które wyzwalało Watchdoga.) Rozwiązanie było tak banalne że aż mi trudno uwierzyć że na to nie wpadłem od razu :)

Niemniej dziękuję chłopaki za każdą wskazówkę i teraz napewno będę uważał z Watchdogami :)
Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Re: Problem z watchdogiem

Post autor: Cristiano1989 » 17 lut 2016, 10:32

przeciez i tak musialbys odlaczyc oba arduiono od siebie z pinow RX i TX bo nic bys nie wgral...
Zgadza się ale oprócz tego oba arduino są podłączone wspólną masą i zasilaniem a dodatkowo pin wywołujący przerwanie również jest podpięty poprzez inny pin więc odłączając RX i TX w celu wgrania programu to zasilanie oraz sterowanie przerwaniem były podłączone (Tym bardziej przy odłączonym TX i RX bo na podstawie czy w danym czasie otrzymuje dane czy nie wykrywam czy resetować arduino czy nie). No ale w gruncie rzeczy problem był łatwiejszy do rozwiązania niż się na początku wydawało.

Na podstawie przykładu z linku który podesłał stiven udaje mi się resetować arduino pinem reset, jednak moje arduino po kilku wysłaniach poprzez RX i TX wpada w bardzo dziwny stan powiedziałbym nawet całkowitego zawieszenia. Nie działa nawet impuls przerwania i wywołanie w nim funkcji resetującej. Ktoś spotkał się z czymś takim? Niestety Arduino IDE nie jest stworzone do debugowania kodu (przynajmniej ja nie mogę znaleźć takiej opcji). Ustawiłem prymitywne debugi w postaci drukowania na Serial monitorze określonego teksu i ustawiłem je we wszystkich wrażliwych miejscach z myślą że zawieszenie związane jest z jakąś pętlą lub długim odczytem danych z NRF, ale arduino się zawiesza a na serialu nic się nie drukuje. Na dodatek niemożliwość wejścia w funkcje odpalaną podczas przerwania obaliła totalnie moją teorię.

Macie może jakieś pomysły?

Na obecną chwilę przychodzi mi jeden aby sterować zasilaniem z jakiegoś pinu cyfrowego w drugim arduino. Działało by to na zasadzie pin np.5 w pierwszym arduino podłączony do pinu Vin drugiego arduino dający cały czas wysoki sygnał. W przypadku wykrycia zawieszenia nadać na pinie 5 sygnał niski co skutkowałoby odcięciem zasilania po czym ponownie ustawiałbym pin 5 na stan wysoki. Mam jednak wątpliwości czy ten pomysł zdałby egzamin. Co o nim myślicie?
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Problem z watchdogiem

Post autor: stiven » 17 lut 2016, 10:47

Mówię Ci, spróbuj tą funkcją Serial.readStringUntil(',') odbierać dane. Ja kiedyś coś takiego przerabiałem, też mi się tak zawieszało i próbowałem z dodatkowym pinem resetującym, ale nic z tego nie wyszło. Tamta funkcja rozwiązała problem. Możesz pokazać jak robisz tą transmisję, to może coś podpowiem.
Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Re: Problem z watchdogiem

Post autor: Cristiano1989 » 17 lut 2016, 11:48

Ogólnie znalazłem taką fajną bibliotekę w której jako argument podaję wskaźnik do struktury i leci sobie cała struktura. Być może będę musiał zmodyfikować tą bibliotekę. Ta funkcja Serial.readStringUntil(',') jest standardową funkcją dla seriala?

A ten mój pomysł z zasilaniem drugiego arduino poprzez pin drugiego miałoby szanse powodzenia?
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Problem z watchdogiem

Post autor: stiven » 17 lut 2016, 12:46

Cristiano1989 pisze:Ta funkcja Serial.readStringUntil(',') jest standardową funkcją dla seriala?
Tak.
Cristiano1989 pisze:A ten mój pomysł z zasilaniem drugiego arduino poprzez pin drugiego miałoby szanse powodzenia?
Czyli chcesz zrobić reset przez wyłączenie zasilania. Bezpośrednio z pinu nie, musiałoby to być zrobione przez tranzystor.
Cristiano1989 pisze:Ogólnie znalazłem taką fajną bibliotekę w której jako argument podaję wskaźnik do struktury i leci sobie cała struktura.
A nie masz przypadkiem tak zrobione, że arduino wysyłające wysyła za często i to drugie arduino się w końcu zawiesza, bo bufor seriala się przepełnia? Jak nie masz w programie użytego jakiegoś opóźnienie w wysyłaniu, na przykład wykorzystując delay() albo millis(), to tak może się dziać.
Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Re: Problem z watchdogiem

Post autor: Cristiano1989 » 17 lut 2016, 13:03

A nie masz przypadkiem tak zrobione, że arduino wysyłające wysyła za często i to drugie arduino się w końcu zawiesza, bo bufor seriala się przepełnia?
Zawiesza się arduino wysyłające a odbierające działa bez problemu
Jak nie masz w programie użytego jakiegoś opóźnienie w wysyłaniu
Dane wysyłane są co 30 sekund.

Z działań jakie wykonuje arduino wysyłające jest wysłanie zapytania do jednego NRF i odczyt danych, wysłanie do drugiego NRF zapytania i odczyt danych i wysłanie zgromadzonych danych przez serial do arduino z wyświetlaczem. Wszystkie operacje wykonują się co 30 sekund.

Czy można jakoś zerować bufor transmisji po serialu?
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Problem z watchdogiem

Post autor: stiven » 17 lut 2016, 13:22

Jest taka funkcja Serial.flush(), ona opróżnia bufor danych wychodzących, a właściwie zatrzymanie do czasu, aż dane zostaną wysłane.
Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Re: Problem z watchdogiem

Post autor: Cristiano1989 » 19 lut 2016, 20:01

Witam ponownie po kilku dniach przerwy.

Mam pytanie:

Chciałbym co minutę resetować arduino watchdogiem. W tym celu wykonuję takie działania:

Kod: Zaznacz cały

void setup()
{
  wdt.disable();
  timer = millis();
}

Kod: Zaznacz cały

void loop()
{
  if (millis() - timer >= 60000)
  {
     wdt.enable(WDTO_1S);
     while(1); 
  }
}
To w takim dużym skrócie. Domyślnie watchdog jest wyłączony. Ustwaienie go następuje po 60 sekundach a następnie w pętli nieskończonej oczekuje na reset. Według mnie powinien się resetować i się resetuje ale w kółko. Domyślam się, że przez to że nie odświeżyłem mojego timera i wchodzi do ifa co obrót pętli, ale czy nie powinno być tak, że arduino po resecie rozpocznie program od nowa i wyzeruje sobie wszystkie liczniki?
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Problem z watchdogiem

Post autor: stiven » 20 lut 2016, 12:19

A pierwszy reset po włączeniu zasilania jest po 60 sekundach?
Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Re: Problem z watchdogiem

Post autor: Cristiano1989 » 20 lut 2016, 12:54

A pierwszy reset po włączeniu zasilania jest po 60 sekundach?
Tak. Przez pierwsze 60 sekund wszystko działa normalnie a po upływie tego czasu resetuje się co chwile. Wygląda to tak jakby siedział w pętli nieskończonej i resetował się co obrót bo nie ma resetu watchdoga. Chyba że ten watchdog działa tak, że resetuje sam procesor a działanie programu kontynuuje od momentu wystąpienia resetu?
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Problem z watchdogiem

Post autor: stiven » 20 lut 2016, 13:16

No ciekawe czemu to tak. Zobacz może takie coś pomoże w setup. A tej zmiennej timer od razu przy deklaracji ustaw wartość.

Kod: Zaznacz cały

unsigned long timer = millis();

void setup()
{
  wdt.enable(WDTO_1S);
  wdt_reset();
  wdt.disable();
}
A z tą funkcją resetującą nie działa?

Kod: Zaznacz cały

void(* resetFunc) (void) = 0;//declare reset function at address 0

void loop()
{
  if (millis() - timer >= 60000)
  {
     resetFunc(); //call reset 
  }
}
Cristiano1989
Młodszy majsterkowicz
Posty: 37
Rejestracja: 7 lis 2015, 21:05

Re: Problem z watchdogiem

Post autor: Cristiano1989 » 20 lut 2016, 15:00

Kod: Zaznacz cały


void(* resetFunc) (void) = 0;//declare reset function at address 0

void loop()
{
  if (millis() - timer >= 60000)
  {
     resetFunc(); //call reset
  }
}
Ten reset zadziałałi jestem w sumie zadowolony z rezultatu.

Mam jeszcze pytanie nie związane z watchdogiem: Miałem połączone masy dwóch arduino, a oprócz tego każdy podłączony po USB. W pewnym momencie poczułem że coś się grzeje i okazało się że to procesor. Dlaczego tak się stało jak to tylko masa?
Awatar użytkownika
Marhef
Złota rączka
Posty: 1236
Rejestracja: 18 lis 2011, 02:18

Re: Problem z watchdogiem

Post autor: Marhef » 22 lut 2016, 10:00

A co miałeś podłączone do jednego i drugiego arduino? Na samych masach nie powinno być takiego problemu
ODPOWIEDZ

Strony partnerskie: