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

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.