Skocz do zawartości

Elvis

Użytkownicy
  • Zawartość

    2431
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    169

Posty napisane przez Elvis


  1. Nie musisz testować wszystkich możliwych kolorów - potrzebujesz tak naprawdę 6 liczb, czyli minimalnej i maksymalnej wartości, która jest zwracana przez pulseIn() dla trzech kolorów w używanym przez Ciebie otoczeniu.

    Później możesz te wartości wstawić do map(). Musisz tylko doczytać jak działa ta funkcja: https://www.arduino.cc/reference/en/language/functions/math/map/

    Wykonuje ona proste skalowanie, czyli:

    long map(long x, long in_min, long in_max, long out_min, long out_max) {
      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }

    Więc jeśli wartość x, czyli wejście jest poza zakresem in_min - in_max, to i wynik jest poza zakresem out_min i out_max. Będziesz musiał więc odczytany wynik ograniczyć jeśli wyszedł poza zakres, albo jeszcze lepiej - ograniczyć wartość danej wejściowej, czyli x.

    • Pomogłeś! 1

  2. @startrek1p2p Ja też nie wiem jakie wartości będziesz odczytywał - dlatego napisałem żebyś na razie zrezygnował z funkcji map() i przetestował jaki jest zakres wartości. Bo map() przelicza zakresy, czyli jak miałeś:

    frequency = map(frequency, 25,72,255,0);

    to zakres 25-72 był przeliczany na 255-0. Jeśli dostałeś wartość spoza zakresu 25-72, to i wyniki wyszły poza 0-255. Stąd takie dziwne wartości.

    Moim zdaniem powinieneś zacząć od ustalenia jakie wartości dostajesz dla R, G i B - zaczynając od całkiem zasłoniętego czujnika, a kończąc na oświetlonym białym światłem. Co więcej warto sprawdzić, czy czujnik odpowiednio reaguje na kolory - tak żeby się upewnić że wszystko działa. Nie musisz mieć do tego oscyloskopu, wystarczy trochę się pobawić i poobserwować wyniki. Jeśli umieścisz czerwony obiekt - wartości dla czerwonego powinny maleć itd.

    Dopiero wiedząc jakie otrzymujesz "gołe" wyniki możesz dodać funkcję map() i przeskalować odczytane wartości na oczekiwany zakres. Musisz jednak pamiętać, że map może zwracać też wartości spoza oczekiwanego przedziału.

    I jeszcze jedno - zmień typ zmiennych R,G,B z powrotem na int. Teraz jest dużo gorzej niż było.

    • Lubię! 1
    • Pomogłeś! 1

  3. @startrek1p2p wyłącz na chwilę wywołania funkcji map(), będzie można wtedy zobaczyć jak wyglądają same odczyty z czujnika. Wygląda na to że, twój czujnik zwraca wartości z innego przedziału niż zakładasz - zacznij więc od sprawdzenia, jakie są to wartości i czy zmieniają się zgodnie z oczekiwaniami.

    • Pomogłeś! 1

  4. Można mieć komercyjne produkty w pełni amatorskie - jako przykład weźmy chociażby zestawy AVT. Nie wszystko za co ktoś płaci jest profesjonalne - i odwrotnie, wiele produktów typu open-source, open-hardware itd jest darmowych, a często w wiele lepszej jakości niż niejeden płatny projekt.

    Na AVR można opracować w pełni profesjonalny projekt, a na ARM mieć zupełnie skopaną amatorszczyznę - więc nie ma sensu porównywać architektur i rozwiązań, podbudowywać własne ego dopiero co poznanym mikrokontrolerem. To co zaproponował p. Kardaś o ile wiem jest rozwiązaniem skierownym do amatorów, osób które chcą się nauczyć programowania, poznać podstawy elektroniki. I chyba jest to dobry wyrób skoro wiele osób go kupuje i sobie to chwali - jak to się mówi, zagłosowali portfelami 😉

    • Lubię! 2

  5. wszystko zależy do czego i gdzie te tranzystory były dodawane. Używanie wyjścia w trybie open-collector (albo raczej open-drain) nie zawsze jest idalnym rozwiązaniem. Dodatkowe tranzystory czasem bardzo się przydają, np. kiedy potrzebne są nieco większe prądy, albo odporność na zakłócenia. Co więcej czasy przełączania dla OC są znacznie niższe niż w trybie push-pull, a zewnętrzny tranzystor dużo lepiej zadziała z małym rezystorem podciągającym - więc moim zdaniem trzeba dobierać rozwiązanie do problemu, a nie teoretyzować. Tym bardziej że w większości przypadków sterowanie napięciem 3.3V w zupełności wystarczy nawet dla wejść w logice 5V.

    • Lubię! 1

  6. Jak najbardziej może być tam 5V. Bazując na standardowej technice wytwarzania układów półprzewodnikowych można umieścić więcej niż jedno złącze pn i wtedy 5V nie stanowi problemu. Co więcej można odpowiednio domieszkując można uzyskać złącze zenera, co chyba nawet lepiej pasuje w takim przypadku - w każdym razie schemat z diodą to tylko model i ogromne uproszczenie.

    • Lubię! 1

  7. @atMegaTona stm32 i wiele innych mikrokontrolerów jest wyposażone w wyprowadzenia "tolerujące" napięcie wyższe niż zasilania samego układu - czyli powiedzmy tolerujące 5V, gdy układ jest zasilany z 3.3V. Rysunki z diodami zabezpieczającymi są oczywiście uproszczeniem, a jak faktycznie dane zabezpieczenie jest rozwiązanie to już zupełnie inna sprawa. W każdym razie w przypadku wielu wyprowadzeń stm32 podawanie 5V nie stanowi problemu - a ustawienie pinu w tryb wejścia, albo wyjścia open-colector z rezystorem podciągającym to żadna tajemnica ani czarna magia.

    • Lubię! 1

  8. Darmowe statystyki popularności języków są dostępne w sieci i co więcej są za darmo.

    Język C++ jest używany w wielu projektach opartych o uC. Zarówno kilku poprzenich projektach, jak i w mojej aktualnej pracy C++ jest wykorzystywany do pisania aplikacji działającej bez systemu operacyjnego (albo raczej używającej jedynie RTOS-a) i jakoś nikomu to nie przeszkadza. Co ciekawe akurat po linuxem pracuję więcej w czystym C, sam system też w tym języku jest napisany - więc argumenty o C++ dla linuxa, a czystym C dla uC to absolutna bzdura - chociaż nie pierwsza wygłaszana przez tego użytkownika.

    Jak chodzi o naukę, to zarówno C, jak i C++ są dobrymi kandydatami - chociaż ostatnio modne są zupełnie inne języki, więc można również pomyśleć o micropythonie, albo Rust.

    @Wloczykij555 Skoro kupiłeś zestaw z STM32, to może zacznij od kursu stm32? Jak czegoś nie będziesz wiedzał, czy rozumiał zawsze możesz zapytać na forum, na pewno pomożemy. Arduino to fajna opcja, ale skoro masz już sprzęt to bez sensu kupować kolejny - zacznij, zobacz jak Ci się będzie tym bawiło, zawsze można, a nawet należy później kupić coś kolejnego. A czy to będzie Arduino, Raspberry Pi, czy zupełnie coś innego - to się okaże 🙂

    • Lubię! 2

  9. Trochę się zastanawiałem nad tym błędem i wartością rejestru SP - bo przeglądając plik startup_stm32f103c8tx.s wszystko wygląda poprawnie (nie licząc złej wartości _estack).

    Wydaje mi się, że przyczyną problemów była nieco nietypowa konfiguracja. Ja najczęściej w przypadku bluepill używam bootloadera oraz  programowania przez usb. Tym razem, żeby uzyskać ten sam efekt co opisywany w wątku podłączyłem st-link z interfejsem SWD (właściwie to podłączyłem stlink z płytki nucleo). W każdym razie sam bluepill nadal uruchamiał bootloader, a dopiero później przez SWD wgrywany i uruchamiany był "właściwy" program.

    Normalnie po włączeniu zasilania pierwsze słowo z kodu programu jest ładowane do rejestru SP. Tam znajduje się wartość _estack i wszystko powinno działać.

    Ale jeśli zamiast programu uruchamiany jest bootloader to oczywiście rejestr SP jest kontrolerowany przez kod bootloadera. W kolejnym kroku debugger przejmuje kontrolę i uruchamia główny program. Jednak procedura jego uruchomienia nie jest identyczna z "prawdziwym" resetem. Rejestr SP powinien być więc ustawiony przez debugger, ale ktoś tego nie przewidział w skryptach dołączonych do CubeIDE... i w efekcie program startuje z wartością SP z bootloadera.

    To by również tłymaczyło wpływ grzebania przy liniach BOOTx na działanie programu. Jako ciekawostkę można spróbować skompilować oryginalny program, wgrać do flasha i wystartować bez bootloadera i debuggera. Jeśli to zadziała, to będzie potwierdzenie mojej teorii...

     

    • Lubię! 2

  10. @astex a potrafisz wysyłać i odbierać komunikaty tekstowe? Bo jeśli tak, to skonwertuj wynik z czujnika na napis i wyślij. Po pierwsze łatwiej to testować, bo na początek możesz po prostu wyświetlać co dostajesz, bez przetwarzania. Możesz też testować serwer niezależnie wysyłając mu napisy z dowolnego terminala. A jak już opanujesz wysyłanie gołych tekstów to poczytaj o formacie JSON, będziesz miał wtedy piękną możliwość przesyłania nawet całkiem skomplikowanych danych, czy wyników.

    • Lubię! 1

  11. Nie sądzę żeby zmiana BOOT1 na 1 była choćby odrobinę dobrym rozwiązaniem. To nawet ciekawe na czym polega problem, jeśli umieścisz gdzieś kompletny projekt może będzie łatwiej poszukać przyczyny problemu. Bo zarówno DMA, jak i BOOT1 to raczej leczenie objawowe.

    • Lubię! 1

  12. CPU i DMA konkurują o dostęp do pamięci - dokładniej DMA co jakiś czasu zapisuje do pamięci wyniki z przetwornika A/C. Ale skoro w programie masz:

      sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;

    to ten zapis nie następuje zbyt często. Mawet nie wnikając czy ADC jest taktowane wolniej niż CPU, na jeden zapis przez DMA masz setki cykli CPU.

    Wiec teoretycznie program działa wolniej, ale pewnie nikt tego nie zauważy.

    Natomiast w programie masz pewnie inny błąd, który daje podobne efekty. Ciężko jest tak "zdalnie" zdiagnozować przyczynę problemów, ale z tego co przychodzi mi do głowy:

    1) jesli wyłączysz ADC to funkcje arytmetyczne działają na stałych danych, może coś się psuje jak pojawią się określone wartości - coś gdzieś dzieli przez zero, liczy tangens z pi-pół itd.

    2) może po wyłączeniu DMA optymalizator usuwa jakieś fragmenty kodu i całość działa względnie poprawnie

    3) na zrzucie ekranu, który wstawiałeś wcześniej program  zatrzymywał się w procedurze obsługi przerwania. Może problem nie wynika z samego DMA, ale złego sposobu obsługi przerwania od DMA? np. nie jest zerowana jakaś flaga i przerwanie wywoływane jest "w pętli", co faktycznie może uniemożliwiać działanie programu?

    To tylko pomysły, bo jak napisałem ciężko jest diagnozować przyczynę problemu na odległość. W każdym razie DMA nie ma prawa zatrzymać programu, może go spowolnić, ale nie zatrzymać całkiem.

    • Lubię! 1

  13. DMA nie zawiesza wykonywania obliczeń, ale w pewnych warunkach może mieć wpływ na czas działania procesora oraz wykonywanie programu. O ile sam mechanizm działa niezależnie od CPU, to w przypadku dostępu do tego samego modułu jak np. pamięci RAM możliwe jest spowolnienie działania procesora. Oba moduły master, czyli w tym wypadku CPU oraz DMA konkurują o dostęp do jednego układu podrzędnego (slave). Oznacza to, że gdy np. DMA zapisuje wyniki, CPU musi poczekać. Jednak to oczekiwanie to raptem jeden, a maksymalnie kilka cykli magistrali AHB. Co więcej spowalniane są tylko dostępy do pamięci, a procesor większość operacji np. arytmetycznych i tak wykonuje na rejestrach.

    W przypadku ADC problem jest jeszcze mniejszy - DMA zapisuje wyniki dopiero po zakończeniu konwersji A/C. Więc "zatrzymanie" CPU następuje bardzo, bardzo rzadko.

    Moim zdaniem problem wynika z zupełnie innej przyczyny, natomiast wpływ DMA jest raczej pomijalny.

    Nie ma natomiast możliwości, że DMA zupełnie zablokuje działanie CPU. Program nawet w najgorszym przypadku będzie wykonywany, chociaż z nieco mniejszą prędkością - niestety nie ma nic za darmo.

    • Lubię! 1

  14. 41 minut temu, RFM napisał:

    nie znasz do końca CE! Tak? Zapraszam do lektury CE.Warto!.

    Bardzo możliwe, cały czas człowiek się uczy - możesz podać jakiś link do "lektury CE", chętnie przeczytam?

    Z tego co wiem CE to jedynie oznaczenie nadawane przez producenta na potwierdzenie zgodności z wymogami dyrektyw unijnych. Dla tego urządzenia moim zdaniem należałoby co najmniej spełnić wymagania dyrektywy niskonapięciowej (2014/35/UE)  oraz ROHS. Ale skoro nalegasz, mogę zapytać w AVT, oczywiście jak tylko urządzenie pojawi się w sprzedaży.

    • Lubię! 1
×
×
  • Utwórz nowe...