Skocz do zawartości

Elvis

Użytkownicy
  • Zawartość

    2431
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    170

Elvis wygrał w ostatnim dniu 17 listopada

Elvis ma najbardziej lubianą zawartość!

Reputacja

934 Mistrz

2 obserwujących

O Elvis

  • Ranga
    8/10

Informacje

Ostatnio na profilu byli

Blok z ostatnio odwiedzającymi jest wyłączony i nie jest wyświetlany innym użytkownikom.

  1. Moim zdaniem warto przetestować jak zachowa się program i czujnik przy maksymalnych wartościach - ale nie musisz się nimi szczególnie przejmować. Jak będziesz znał zakres, który Cię interesuje wystarczy wpisać go do funkcji map(), ale przed jej użyciem wywołać funkcję constrain() https://www.arduino.cc/reference/en/language/functions/math/constrain/ Wtedy wszystko powinno działać jak należy
  2. 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.
  3. @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.
  4. @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.
  5. Dla mikrokontrolerów są biblioteki np. od ST: https://www.st.com/en/embedded-software/x-cube-ai.html Cały trening sieci wykonuje się "jak zwykle" za pomocą narzędzi opartych o Pythona, ale nauczoną sieć można skonwertować na zminimalizowaną postać dopasowaną do mikorokontrolera, którą obsługują biblioteki napisane w C.
  6. Powiedziałbym bardziej że widziałem przykłady użycia sieci neuronowych na STM32 podczas szkolenia. Były to faktycznie małe sieci, ale stm całkiem sprawnie sobie radził. Moim zdaniem w przypadku mikrokontrolerów mogłoby być ciekawe użycie sieci neuronowych do wstępnego przetwarzania mniejszych zbiorów danych niż w przypadku obrazu - np. analizować dane z akcelerometru, czy żyroskopu. Z ciekawostek - w sieci są przykłady używania ML do nauki "chodzenia" przez roboty. Planowałem więcej się tym pobawić, ale jak zwykle - brakuje czasu
  7. 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
  8. Panie Skrzyński, to bardzo nieładnie czepiać się tego co robi ktoś inny, szczególnie jeśli wymienia się go z nazwiska. Rozumiem że ma pan ogromny żal i przemawia przez pana ogromna zawiść, że prace p. Kardasia, które nie tylko są przez wiele osób lubiane, ale jeszcze wspierane znacznymi kwotami. Jednak to forum nie jest miejscem na terapię i leczenie kompleksów - prosiłbym o unikanie takiej krytyki. Oczywiście można napisać że nie powinno się używać układów poza zakresami wskazanymi przez producenta, ale pamiętajmy, że zarówno konstrukcje pojawiające się na tym forum, kursy p. Kardasia, jak i artykuły w EP, czy EdW to wszystko amatorskie i hobbistyczne zastosowania.
  9. 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.
  10. 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.
  11. @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.
  12. 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
  13. C++ jest jak najbardziej używany w świecie mikrokontrolerów. Więc argument o 90% softu w C można spokojnie między bajki włożyć - no chyba że @RFM przytoczy jakieś sprawdzone statystyki, a nie tylko własne opinie. Zarówno w "świecie" Linuxa, jak i programowania mikrokontrolerów bez systemu operacyjnego jest miejsce zarówno dla języka C, jak i C++.
  14. 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...
  15. Faktycznie, kod źródłowy sporo pomaga. Problem okazał się dużo ciekawszy niż w pierwszej chwili wyglądało, więc w końcu odnalazłem zakurzone blue pill, podłączyłem programator i postanowiłem sprawdzić o co w tym chodzi. Najpierw wersja skrócona - lepiej na razie nie używać CubeIDE... to nowe środowisko, powiedziałbym że wersja beta. Więc jest w nim dużo więcej błędów niż w starych i sprawdzonych. A teraz pełna wersja: Na początek faktycznie - błąd się pojawia, występuje w dość przypadkowych momentach, nie ma najmniejszego sensu... Chociażby podczas inicjalizacji DMA, HardFault jest wynikiem dereferencji wskaźnika NULL, który pojawia się magicznie. Więc typowe debugowanie niewiele daje oraz wskazuje na problemy ze stosem. I tutaj niestety musimy zejść do poziomu samego procesora. Po uruchomieniu mamy: Jak widzimy po prawej stronie wskaźnik stosu, czyli rejestr sp ma wartość 0x200001fc, czyli od początku pamięci SRAM dzieli go 0x1fc = 508 bajtów. To za mało na skomplikowany program działający na liczbach zmiennopozycyjnych. Teoretycznie wielkość stosu ustawiamy w pliku linkera, czyli STM32F103C8TX_FLASH.ld: Tutaj znajdziemy dwie ważne wartości. _estack to adres "końca" stosu, czyli najwyższego adresu zajmowanego przez stos. Widzimy tutaj pierwszy błąd, bo adresy powinny być podzielne przez 4, a często i przez 8. W każdym razie powinniśmy zmienić deklarację na: /* Highest address of the user mode stack */ _estack = 0x20005000; /* end of "RAM" Ram type memory */ Teraz to czego szukamy, czyli wielkość stosu: _Min_Stack_Size = 0x400 ; /* required amount of stack */ Domyślna wartość 0x400 oznacza 1024 bajty. Mikrokontroler STM32F103C8 ma 20 KiB pamięci SRAM, więc nie musimy być aż tak oszczędni - można ustawić stos na nieco większy. Okazuje się jednak, że zmiana _Min_Stack_Size nie wpływa na wartość rejestru SP, czyli faktyczny wskaźnik stosu... Mamy 508 bajtów bo coś się komuś pozajączkowało. Nie jestem pewien, czy to najlepsze rozwiązanie, ale można poprawić problem zmieniając plik startup_stm32f103c8tx.s, który znajdziemy w katalogu Startup. Teoretycznie rdzeń Cortex-M3 ustawia wartość rejestru SP podczas uruchamiania programu - ale to jak widać nie działa poprawnie. Możliwe że wynika to ze sposobu działania debuggera i po wgraniu do pamięci flash byłoby poprawnie, ale możemy zastosować "obejście" i sami ten rejestr ustawić. Do wspomnianego pliku wystarczy dodać jedną instrukcję: ldr sp, =_estack Program wygląda wówczas tak: I u mnie działa...
×
×
  • Utwórz nowe...