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

Biblioteks do SPI - MK SPI oraz dla MkNRF24L01 M. Kardasia

Bluzman 07 Sty 2023 12:08 777 12
  • #1 20372596
    Bluzman
    Poziom 4  
    Zakupiłem biblioteki Pana Mirka Kardasia do obsługi SPI oraz dla modułu MkNRF24L01. Chcę używając ich skonstruować pojazd/zabawkę zdalnie sterowany.
    Myślę że bardziej doświadczeni będą potrafili odpowiedzieć na pytania. Skupię się początkowo na samym SPI.

    Korzystam z tutoriala




    Nie posiadam zestawów ATB więc używając ATmega32 i ATmega16 zrobiłem na płytkach stykowych MASTER i SLAVE. Oszczędzę miejsca na opis jak to wszystko wygląda więc załączam fotki całej konstrukcji. Wszystko jest teraz w fazie testów tylko biblioteki dla SPI. Płytki połączone jedynie przewodami. Procki taktowane 8MHz, zasilanie z przetwornic - 5V (zasilacze).
    Kod programu nie jest bardzo zmieniony, zostały wyrzucone linijki dotyczące obsługi diod LED no i konfiguracja pinów.
    Po wysłaniu informacji z MASTERa otrzymuję z powrotem string z temperaturą (jak na filmiku). Tylko wygląda to tak, że przychodzi czasem cały tekst, po kolejnym naciśnięciu przycisku połowa lub jedna literka a innym jakieś śmieci. Sprawdzałem to na HW i SOFT SPI. Zmieniałem czas na przygotowanie odpowiedzi z stringiem z temperaturą, jak w tutorialu w ustawieniu "MASTER_SPI_DELAY_US".
    Nic się nie poprawia. Nie wiem czy co jest przyczyną. Może to wina tych badziewnych przewodów łączących MOSI, MISO, SCK, SS + przewody na płytkach stykowych i coś tam na nich "sieje". Tutaj bym prosił o jakieś sugestie bo podejrzewam, że w przyszłości może mieć to wpływ na cały projekt.

    Druga sprawa to sterowanie silniczkiem. Do SLAVE podpiąłem mostek H (L293D, patrz foto) z motorkiem TT D65, bez PWM, zasilany z tej samej przetwornicy co SLAVE. Tutaj chcę zrobić tak, że silnik obraca się tylko przy wciśniętym cały czas przycisku na MASTErze. Bo jak wyślę przy tej konfiguracji bajt który uruchomi silniczek to działa on non-stop a zatrzymać go można wciskając inny klawisz z bajtem który go zatrzymuje.
    Tego raczej nie można umieścić w przerwaniu bo będzie zabierało czas z resztą sam Mirek to podkreśla a w pętli głównej nie za bardzo to wychodzi. Czasem obraca się szybciej, czasem wolniej a po usunięciu delayów z kodu (filmik) stoi i buczy. Tutaj też proszę o jakieś rozwiązania żeby ogarnąć to ciągłe wysyłanie informacji z MASTERa przy wciśniętym przycisku.

    Biblioteks do SPI - MK SPI oraz dla MkNRF24L01 M. Kardasia
    Biblioteks do SPI - MK SPI oraz dla MkNRF24L01 M. Kardasia
  • #2 20372628
    tmf
    VIP Zasłużony dla elektroda
    Skoro KUPIŁEŚ ten kod, to chyba najlepszym adresatem tych pytań jest producent/sprzedawca. Przecież autor najlepiej zna kod, skoro to sprzedaje to pewnie jest jakiś support.
  • #3 20372791
    kaczakat
    Poziom 34  
    Pewnie kupiłeś jedną licencję, a używasz w dwóch uC, może to jest Master/Slave ale tylko na jeden uC.
    A na serio to na fotce widać 4 przewody między płytkami, powinno być MOSI, MISO, SCK, SS, GND.
    Jeśli błąd jest w bibliotece to i tak nic nie można zrobić, bo one są przecież tajne i nie wolno ich tu pokazać :D.
    Dlatego ktoś tak wali gromy w Andruino, bo to co kupiłeś jest u innych za darmo i działa lepiej. Ale są też darmowe biblioteki do znalezienia i do C AVR.
    Sterowanie silniczkiem i przycisk to już Twoja wina, umawiasz się sam ze sobą, że sygnał między urządzeniami wysyłasz co 20ms, timeout 10ms, jak dostaniesz komunikat że przycisk jest wciśnięty to realizujesz to przez kolejne 20ms, jak dostaniesz inny komunikat to zmieniasz, jak nie dostaniesz komunikatu przez 20 +10ms to obsługujesz zerwanie transmisji. Jak coś jeździ szybko to czas można skrócić, jak wolno to wydłużyć. Ustawiasz sobie timer, w pętli zliczasz czas i program ma żyć w rytmie jakiegoś tiku systemowego, dopasowanego do tego co robisz.
    Pomogłem? Kup mi kawę.
  • #4 20373314
    kamyczek
    Poziom 38  
    No tak ale ten pan sam nie wie dlaczego to działa i czy aby na pewno działa. Nie pamiętam tam programu ,który działa od początku do końca ... Tam jest zawsze albo będzie , ale po 5 latach dalej nie ma ... ITP ITD...
  • #5 20373492
    kaczakat
    Poziom 34  
    Program z którym walczysz to sztuka dla sztuki, nie ma sensownej wartości użytkowej, PWM i silnik, czujnik, LCD ogarniesz jednym uC. Jak chcesz sterować jakimś oddalonym układem to SPI i tak się do tego nie nadaje, na metr czy dwa to UART, dalej RS485, czyli też jakiś UART. Po zamianie kabla na NRF24 napotkasz zupełnie inne wyzwania i problemy. Im dalej w las tym więcej drzew, bez podstaw szybko się robi ciemno.
    Jesteś w kropce, bo jak nie pokażesz kodu, to nikt nie domyśli się co tam masz źle.
    Nie odpisałeś też czy masz połączenie GND, to jest pierwsze źródło możliwych zakłóceń, a drugie to silnik, powinien mieć niezależne zasilanie, możesz mieć to jakimś stopniu połączone, ale uC powinien mieć osobny stabilizator i spore kondensatory. Na początkowym etapie wszystko powinieneś robić na ledach, jak program działa pewnie i responsywnie to dopiero silnik i osobne rozwiązywanie zakłóceń od niego.
    Nawet nie mogę Ci napisać, że na Andruino byś to ogarnął 10x szybciej, bo tam też poza dostępem do milionów darmowych bibliotek i przykładów swoje trzeba odrobić, program sam się nie napisze, chyba że znajdziesz coś gotowego, co tylko będziesz chciał odtworzyć w domu na swoich uC, choć akurat na model sterowany z wykorzystaniem NRF24 są spore szanse: https://www.youtube.com/watch?v=9Iu-_cIXW-c - tutorial video, linki do kodu i schematów, free of charge, a te Atmegi są w Arduino obsługiwane. Zwróć uwagę, że nawet ten biedny Azjata rzeźbiący w kartonie wie, że nie podłącza się silnika razem z VCC uC, tylko przez Vin płytki prototypowej, czyli uC ma stabilizator i filtrowanie napięcia tylko dla siebie. Nawet jak nie skorzystasz z gotowca, to przynajmniej wykorzystaj schematy, te podstawki pod NRF też są ważne, wtedy NRF tez ma swoje zasilanie o odpowiedniej wydajności i jakości.
    Pomogłem? Kup mi kawę.
  • #6 20374364
    Bluzman
    Poziom 4  
    tmf napisał:
    Skoro KUPIŁEŚ ten kod, to chyba najlepszym adresatem tych pytań jest producent/sprzedawca. Przecież autor najlepiej zna kod, skoro to sprzedaje to pewnie jest jakiś support.

    Źle mnie zrozumiałeś. Ja nie mam zastrzeżeń do biblioteki. Kod czysto napisany, elastyczny, prosta konfiguracja. Wart swojej ceny a cena nie duża, przynajmniej nie była duża bo zakupiłem jakiś czas temu. Myślę że autor zasłużył za swoją pracę takie wynagrodzenie. Support jest, zawsze można napisać do Mirka i to jest drugi plus ceny, że ma dobre wsparcie.

    kaczakat napisał:
    A na serio to na fotce widać 4 przewody między płytkami, powinno być MOSI, MISO, SCK, SS, GND.

    Fakt, sprawdzę to z GND. Nie podłączyłem bo w instrukcji wideo nie było nic o tym. Jeżeli oglądałeś to jest tam fragment o zasilaniu chociażby. Zasila jeden ATB z USB a drugi z akumulatora i mowa tylko o połączeniu portów MOSI, MISO, SCK i SS.
    Możesz tą wskazówkę o timerze precyzyjnie rozpisać albo w jakimś, krótkim przykładowym kodzie C?

    kaczakat napisał:
    Jesteś w kropce, bo jak nie pokażesz kodu, to nikt nie domyśli się co tam masz źle.

    Uporządkuję jeszcze ten kod żeby był jakoś zrozumiały dla was i myślę że autor nie będzie miał nic do tego, że wkleję kawałek z pliku main.c. Sam to pokazuje na swoim tutorialu ogólnodostępnym.

    kaczakat napisał:
    Nie odpisałeś też czy masz połączenie GND, to jest pierwsze źródło możliwych zakłóceń, a drugie to silnik, powinien mieć niezależne zasilanie, możesz mieć to jakimś stopniu połączone, ale uC powinien mieć osobny stabilizator i spore kondensatory. Na początkowym etapie wszystko powinieneś robić na ledach, jak program działa pewnie i responsywnie to dopiero silnik i osobne rozwiązywanie zakłóceń od niego.

    Kontroler zasilany z przetwornicy + na płytce kondensatory są (elektrolit i ceramiczny) no już chyba bardziej stabilnego i przefiltrowanego dodatkowo nie ma sensu robić? Faktycznie o zasilaniu całkowicie niezależnym nie pomyślałem, trochę wtopę zrobiłem. Może dlatego, że mam na uwadze na końcu zrobić zasilanie akumulatorowe w pojeździe tak jakby z wspólnych akumulatorów w koszyczku. Gdzie wszystko jest z jednej "kupy" zasilane. trzeba to będzie na końcu jakoś rozdzielić jak będzie np. 4 akumulatory w jednym koszyczku.

    Dzięki za pierwsze wskazówki, ogarnę to jeszcze raz i z pewnością jeszcze wrócę. Jeszcze jak wyżej przydałby się precyzyjniejszy opis zastosowania tego timera.
  • #7 20374393
    tmf
    VIP Zasłużony dla elektroda
    Bluzman napisał:
    Źle mnie zrozumiałeś. Ja nie mam zastrzeżeń do biblioteki. Kod czysto napisany, elastyczny, prosta konfiguracja. Wart swojej ceny a cena nie duża, przynajmniej nie była duża bo zakupiłem jakiś czas temu. Myślę że autor zasłużył za swoją pracę takie wynagrodzenie. Support jest, zawsze można napisać do Mirka i to jest drugi plus ceny, że ma dobre wsparcie.

    Skoro tak jest (a nigdzie nie sugerowałem, że nie) to chyba tym bardziej najlepszym adresatem pytania jest autor tego kodu.
    Po co tu się ktoś ma domyślać jak to działa, skoro jak sam piszesz jest dobre wsparcie i zawsze można pisać do autora. Po prostu napisz i po problemie.
  • #8 20374779
    kaczakat
    Poziom 34  
    Nie możesz bazować na jednym tutorialu do SPI, na pewno w innych wspominał o wspólnym GND, typowo każdy sygnał jest względem GND, to podstawa i wiele wyjaśnia skoro go nie było. Nie będę wskazywał filmu bo są za ciężkostrawne, przykład do SPI trwa godzinę lekcyjną, w linku ode mnie masz 7 minut filmu, podczas którego powstaje cały model RC.
    Twoje filtrowanie jest OK dla układu migającego ledami, a nie dla silnika, a jedną z zasad filtrowania jest oddzielenie zasilania.
    Jak jesteś na etapie dylematu wspólny GND tak czy nie to przykład z timerem Ci niewiele pomoże, tu jest przykładowy kod: https://maxembedded.wordpress.com/2011/06/29/avr-timers-timer2/ , są też do innych timerów odnośniki. Każdy timer ma kilka trybów pracy, są kalkulatory AVR ułatwiające dobór parametrów.
    Idea jet taka by timerem odmierzyć jakiś równy odcinek czasu, 100us, 10ms. W przerwaniu ustawiasz flagę bool czy zmienną bajt na 1, w pętli głównej wiesz że upłynął taki odcinek czasu. W przerwaniu możesz też zliczać odmierzone odcinki by oznaczyć upłynięcie sekundy, sekund dla minuty, albo tak jak w Arduino tylko licznik ms. W programie niektóre rzeczy trzeba robić w każdym obiegu pętli głównej while1, niektóre co 10ms, niektóre co 1s, niektóre raz nadzień, a przy tym super by było, by każde dodane polecenie, instrukcja czy funkcja nie zmieniała częstotliwości wykonywania zadań, by rzeczy nie były wykonywane częściej niż to jest niezbędne bo braknie czasu na inne, albo działanie programu będzie nieczytelne.
    http://mikrokontrolery.blogspot.com/2011/05/interfejs-spi-sprawa-isp.html jak nie masz żadnej książki to chociaż przeczytaj te artykuły tutaj, cały dział 'jak zacząć' to lektura obowiązkowa.
    Pomogłem? Kup mi kawę.
  • #9 20378209
    Bluzman
    Poziom 4  
    kaczakat napisał:
    Idea jet taka by timerem odmierzyć jakiś równy odcinek czasu, 100us, 10ms. W przerwaniu ustawiasz flagę bool czy zmienną bajt na 1, w pętli głównej wiesz że upłynął taki odcinek czasu. W przerwaniu możesz też zliczać odmierzone odcinki by oznaczyć upłynięcie sekundy, sekund dla minuty, albo tak jak w Arduino tylko licznik ms. W programie niektóre rzeczy trzeba robić w każdym obiegu pętli głównej while1, niektóre co 10ms, niektóre co 1s, niektóre raz nadzień, a przy tym super by było, by każde dodane polecenie, instrukcja czy funkcja nie zmieniała częstotliwości wykonywania zadań, by rzeczy nie były wykonywane częściej niż to jest niezbędne bo braknie czasu na inne, albo działanie programu będzie nieczytelne.

    Trochę się pogubiłem.
    Masz na myśli uruchomienia timera przykładowo co 20ms na MASTERze i wrzucenie w przerwanie ISR np. obsługę klawisza a jak będzie on wciśnięty to w warunku if do niego umieścić wysyłanie określonej komendy/infomracji do SLAVEa?
    Czy zrobienie timera na SLAVE i tam przerwania do niego, które co określony czas (np. 20ms) sprawdza jakie komendy od MASTERa doszły i nimi uruchamia dane piny podłączone do mostku H czy LEDa?
  • Pomocny post
    #10 20378401
    kaczakat
    Poziom 34  
    Szybko Ci poszło przeczytanie wszystkich artykułów na mikrokontrolery.blogspot.
    W każdym programie jakoś musisz obsługiwać upływ czasu, na pierwszej lekcji do zamigania led użyłeś delay, do paru innych prostych programów to też wystarczy, ale generalnie należy to robić na timerze. Jest to tak oczywiste, że w Arduino zrobili do tego gotowe funkcje, w AVR C masz sobie to napisać sam.
    Czyli w obu uC masz mieć timer wybijający rytm działania programu. W jednym wysyłasz informację o wciśniętym przycisku, w drugim odbierasz informację o wciśniętym przycisku, bez timera nie wiesz kiedy poprzednio wysłałeś stan przycisku, w drugim nie wiesz kiedy ostatnio odebrałeś stan przycisku.
    Tak samo jak bez delay do migania ledem robienie w kółko tych czynności zamuli działanie układu, a dla użytkownika nie dawałoby żadnej informacji, led się świeci zamiast migać. Różnica jest tylko taka, że zamiast zatrzymywać program by nie wykonywać poleceń za często, pomijasz ich wykonywanie jeśli nie upłynął określony czas. W nadajniku pomijasz wysyłanie stanu przycisku, w odbiorniku pomijasz zliczanie timeout.
    Przycisk nie jest na tyle istotny by jego obsługę robić w ISR.
    Pomogłem? Kup mi kawę.
  • #11 20378520
    Bluzman
    Poziom 4  
    kaczakat napisał:
    W każdym programie jakoś musisz obsługiwać upływ czasu, na pierwszej lekcji do zamigania led użyłeś delay, do paru innych prostych programów to też wystarczy, ale generalnie należy to robić na timerze. Jest to tak oczywiste, że w Arduino zrobili do tego gotowe funkcje, w AVR C masz sobie to napisać sam.
    Czyli w obu uC masz mieć timer wybijający rytm działania programu. W jednym wysyłasz informację o wciśniętym przycisku, w drugim odbierasz informację o wciśniętym przycisku, bez timera nie wiesz kiedy poprzednio wysłałeś stan przycisku, w drugim nie wiesz kiedy ostatnio odebrałeś stan przycisku.

    Wiem jaka jest różnica pomiędzy delayem a timerem, że timer działa niezależnie i nie opóźnia wykonywania programu w pętli głwnej a delay stopuje tymczasowo wszytsko. Czytałem blogi, noty aplikacyjne nawet tzw. Bluebooka mam. Rozumiem na tyle ile jestem w stanie zrozumieć. W tej kwestii chodziło mi o wskazówkę którą teraz podałeś:
    "Czyli w obu uC masz mieć timer wybijający rytm działania programu. W jednym wysyłasz informację o wciśniętym przycisku, w drugim odbierasz informację o wciśniętym przycisku, bez timera nie wiesz kiedy poprzednio wysłałeś stan przycisku, w drugim nie wiesz kiedy ostatnio odebrałeś stan przycisku. "
    Tego tak szybko nie znajdzie się w necie, napisanego wprost. Są opisywane połączenia przez SPI, timery, przerwania, zliczania, porównania, wzory jak obliczać ale "uruchamiasz timer na dwóch uC" dla zielonych w tym temacie nie ma.

    kaczakat napisał:
    Przycisk nie jest na tyle istotny by jego obsługę robić w ISR.

    Tu ja źle się wyraziłem. Nie miałem na myśli obsługi przycisku w przerwaniu tylko o przycisk, który wykonuje przerwanie w którym jest wysyłanie komendy lub odbieranie (SLAVE).
  • #12 20378724
    tmf
    VIP Zasłużony dla elektroda
    Bluzman napisał:
    Nie miałem na myśli obsługi przycisku w przerwaniu tylko o przycisk, który wykonuje przerwanie w którym jest wysyłanie komendy lub odbieranie (SLAVE).

    Nie wiem, czy dobrze to rozumiem, ale na wszelki wypadek. Nie wpadnij czasem na rozwiązanie, aby przycisk generował przerwanie. To raczej kiepskie, ale jeśli już, to pamiętaj o debouncingu przycisku - bez tego zazwyczaj pojedyncze wciśnięcie lub zwolnienie przycisku może wygenerować serię przerwań. W efekcie ten sam komunikat wyślesz wielokrotnie. Ponieważ debouncing zwykle też realizuje się w oparciu o przerwania (co ciekawe chatGPT generuje nawet poprawny kod dla AVR, więc masz gotowca), więc ma sens, aby w tym samym miejscu wysyłać komunikat przez SPI. Można to oczywiście zrobić także w pętli głównej. Po stronie slave można to wszystko zrealizować inaczej. Jeśli masz proste, komunikaty, to chyba najprościej zaprząc do roboty przerwanie SPI zgłaszane po odebraniu danych. Wetedy jeśłi master coś prześle, a slave to odbierze, to od razu wykona polecenie i nic dodatkowego nie musisz sprawdzać. Można też zrobić odbiór danych w przerwaniu do bufora, np. kołowego i potem przez pooling w pętli głównej aplikacji sprawdzać czy coś przyszła, pobrać i wykonać.
  • #13 20379370
    kaczakat
    Poziom 34  
    Nie ma czego szukać w necie, trzeba usiąść chwilę na rękach by nie robić niepotrzebnego wiatru i pomyśleć. Jak masz niebieską to miałeś cały czas taki przykład, 19_ProjektWielozadaniowy.
    Umiesz zamigać led co 1s bez delay, to umiesz zamiast słowa ledON/OFF użyć w tym miejscu, zmienna++. Czyli umiesz zliczać upływ sekund, umiesz zmienić 1000ms na 10ms, czyli umiesz zliczać upływ ms, umiesz sprawdzić czy minęło 50ms od poprzedniego sprawdzenia, zapisać nowy znacznik czasu i znowu do niego porównywać?
    Jak wygląda prosty debouce przycisku, jak wciśnięty, to delay 30 i sprawdź ponownie, jak znowu true to przycisk wciśnięty. Zamiast tego można napisać funkcję, co 10ms sprawdź stan przycisku, jak wciśnięty to przycisk++, jak nie to =0 ale tu też inne sprawdzenia, czy był przycisk>=3 to wciśnięty był 30ms, reagujesz, zliczasz dalej, może wciśnięty jest długo, jak wciśnięty >= 50 to gdzieś użyjesz zamiast zmienna++ to zmienna+=10, a jak ktoś trzyma 5s to zmienna+=100. Można mierzyć też czas między wciśnięciami, zauważyć double click czy triple.
    Jeden przycisk i led a wymyślania programów na cały miesiąc, zanim się zaczniesz martwić zakłóceniami od silnika.
    Przykład dla timera2, dla timera0 wystarczy zamienić 2 na 0, oba mają dostępny preskaler 64, Atmega16/32 16MHz:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Biblioteks do SPI - MK SPI oraz dla MkNRF24L01 M. Kardasia
    Zamiast wizualizacji tiku na pinach to mogą być cyklicznie uruchamiane funkcje programu.
    Pomogłem? Kup mi kawę.

Podsumowanie tematu

Użytkownik zakupił biblioteki do obsługi SPI oraz modułu MkNRF24L01 od Mirka Kardasia, planując stworzenie zdalnie sterowanego pojazdu. W trakcie testów z wykorzystaniem ATmega32 i ATmega16, napotkał problemy z komunikacją, gdzie dane zwracane z MASTERa były niekompletne lub zniekształcone. Uczestnicy dyskusji sugerowali, aby skontaktował się z autorem biblioteki w celu uzyskania wsparcia oraz zwrócili uwagę na konieczność wspólnego połączenia GND między urządzeniami. Podkreślono również znaczenie użycia timerów do synchronizacji komunikacji oraz debouncingu przycisków, aby uniknąć błędów w przesyłaniu sygnałów. Użytkownik potwierdził, że biblioteka jest dobrze napisana i ma dobre wsparcie, a także planuje uporządkować kod, aby ułatwić jego zrozumienie.
Podsumowanie wygenerowane przez model językowy.
REKLAMA