Skocz do zawartości

Arduino_UNO + Adafruit_ASD1115 - problem


sroxy86

Pomocna odpowiedź

Witam,
Znów zwracam się z pomocą do was po rozwiązanie kolejnego problemu jakim jest przetwornic ADC 16bit z czterema kanałami analogowymi. Zakupiłem sobie tę płytkę z myślą zwiększenia dokładności pomiaru i zbadania jak zachowa się regulator PID który opracowuję.

I niestety pierwszy problem napotykam w momencie próby odczytania wartości z sensora w przerwaniu.

void controller(){

Input = ads.readADC_SingleEnded(0);
   myPID.Compute();
   val = map(Output, 0, 255, 22, 52 );     // scale it to use it with the servo (value between 0 and 180)
   myservo.write(val);   // sets the servo position according to the scaled value

}

Ten powyższy podprogram działa w przerwaniu od Tiemr2 wywoływany co 0,1s.

Niestety całość się zawiesza i nie można nic zrobić.

Ktoś coś wie w temacie - jest jakaś rada.

P.S. nie mogę używać pętli głównej programu ponieważ jest to regulator procesowy. w głównej pętli mam zdeklarowaną obsługę wyświetlacza oraz podprogramy do nastawiania regulatora.

Link do komentarza
Share on other sites

A czy ta sama sekwencja funkcji zawiesza się również wtedy, gdy wołasz ją co 100ms z prostej pętli while{} umieszczonej w programie głównym?

Czy wiesz na pewno, że zwisa właśnie odczyt ADC? Czy gdy go wykomentujesz, to reszta pracuje poprawnie? W przerwaniu?

EDIT: Upewnij się, że przerwanie przychodzi rzeczywiście co 100ms. Wywal cały kod z jego obsługi i wstaw np. zmianę stanu jakiegoś LEDa co 5 wywołań. Powinieneś dostać mruganie 1Hz. I pokaż schemat połączeń tego modułu z Arduino.

Link do komentarza
Share on other sites

DO: marek1707

A czy ta sama sekwencja funkcji zawiesza się również wtedy, gdy wołasz ją co 100ms z prostej pętli while{} umieszczonej w programie głównym?

odp: nie zawiesza się - delay ustawiłem na 10ms - otrzymałem odczyt

Czy wiesz na pewno, że zwisa właśnie odczyt ADC? Czy gdy go wykomentujesz, to reszta pracuje poprawnie? W przerwaniu?

odp: Jeżeli stworzę flagę w pętli głównej to nie mam problemów z odczytem. Natomiast po dodaniu odczytu w przerwanie - kompletnie zawiesza się płytka. Nie mogę wejść w menu które mam w pętli głównej. Na wyświetlaczu mam 0 wartość.

Upewnij się, że przerwanie przychodzi rzeczywiście co 100ms.

odp: przychodzi w 100% co 100ms sprawdzałem przez oscyloskop.

I pokaż schemat połączeń tego modułu z Arduino.

odp: Schemat jest taki sam jak przedstawia producent - jeżeli jest tak bardzo istotny ( myślę ze nie) mogę podesłać. Jeżeli otrzymuje odczyty w normalnym stanie to możemy przyjąć że jest poprawnie podłączony.

Link do komentarza
Share on other sites

Której biblioteki używasz do obsługi tego ADC? Np. ta:

https://github.com/adafruit/Adafruit_ADS1X15

używa zwykłej funkcji delay() podczas oczekiwania na wynik konwersji (lekka zgroza, rozwiązanie z przedszkola, nieprawdaż?). Popatrz na tekst funkcji readADC_SingleEnded() w pliku Adafruit_ADS1015.cpp.

Arduinowe liczenie czasu bazuje na przerwaniach od timera 0 a samo delay na przyrostach 32-bitowego licznika programowego, inkrementowanego w obsłudze przerwania od tego timera. Gdy przerwania są zablokowane, czas w Arduino nie płynie a obsługa Twojego przerwania ma z definicji przerwania wyłączone. Wołasz więc (bezwiednie) delay() a ono zamiera czekając aż zablokowany licznik nabierze odpowiedniej wartości 🙁

Rozwiązaniem jest:

- skorzystanie z innej, lepiej napisanej biblioteki,
- ustawianie w przerwaniu jedynie flagi upłynięcia czasu i testowanie jej w programie głównym,
- wywalenie przerwań, samodzielne liczenie upływu czasu (przed odpytywanie millis()) i odpalanie konwersji w programie głównym,
- może jeszcze jakieś inne?

W takich tajemniczych sytuacjach wiele się wyjaśnia po zajrzeniu do kodu używanej biblioteki. Masz ją przecież w postaci źródłowej, nie ma tam żadnej magii. Wtedy przynajmniej wiesz co procesor naprawdę robi po wywołaniu co ciekawszych funkcji. Napisz jak sobie poradziłeś.

BTW: Ta chyba aktywnie czeka na ADS-a przez odpytywanie I2C, ale ja nie używałem żadnej dla ADS1115 więc to tylko uwaga z czytania kodu:

https://github.com/addicore/ADS1115

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Wydaje mi się, chociaż pewności nie mam, że Arduinowa implementacja I2C też używa przerwań (dokładniej moduł twi).

Ogólnie wykonywanie czasochłonnych operacji, w tym komunikacja przez i2c, wywoływane z przerwań to zły pomysł. Proponuję nie szukać innej biblioteki, ale raczej zmienić podejście.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.