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

Jak obsługiwać błędy w funkcjach C dla Arduino? Zwracanie wyników i błędów

Adam Ś. 01 Kwi 2025 09:42 327 7
REKLAMA
  • #1 21503058
    Adam Ś.
    Poziom 12  
    Posty: 209
    Ocena: 8
    Cześć.

    Nie jestem specjalistą w programowaniu, znam język C w dość podtawowym stopniu - na tyle, że jestem w stanie pisać własne programy z pomoca informacji i przykładów znalezionych w necie. Umiem tworzyć proste funkcje, ale mam pewien problem. Próbuję stworzyć trochę bardziej skomplikowaną bibliotekę dla Arduino. Biblioteka ta, ma kilka funkcji, które coś tam przeliczają, coś tam odbierają po UART, itp. Wszystko działa, ale nie mogę sobie poradzić (a raczej pojąć jak to ma działać) z obsługą błędów pochodzącą z takich funkcji.
    Do tej pory było to dla mnie proste - miałem np. funkcję
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    tutaj dla przykładu jakaś funkcja do której przekazuję bajt danych do wysyłki po np. UART, a sama funkcja mogła mi zwracać wartości 0, 1 - gdzie 0 - udało się wysłać prawidłowo; 1 - nie wysłano bo "jakiś tam błąd".
    To jest proste.
    Ale teraz mam funkcję np.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Funkcja ta coś tam robi, operuje na danych i ma zwrócić wynik. Chciałbym móc jakoś sprawdzać czy funkcja wykonała się prawidłowo. Niby można by zrobić tak, że gdy funkcja zwraca wartości większe lub równe 0 to wtedy jest ok, a gdy zwróci np. -1 to znaczy, że jest jakiś błąd. Ale problem w tym, że wynikiem tej funkcji, może być też wartośc ujemna i wtedy ten sposób jest niemożliwy.

    No i tu jest sedno wątku - jak sobie z tym poradzić? Próbowałem, podglądać jakieś bliblioteki jak to jest rozwiązane ale się gubię w nich. Bo gdy widzę np. taką funkcję:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    która może zwrócić niewiadomo dokąd
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    to torchę zaczynam się pytać - co ja tu robię?

    Jedyne co przychodzi mi sensownego do głowy aby rozwiązać mój problem to stworzyć funkcję np. w ten sposób:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    czyli o ile dobrze myślę, to tutaj bym wartość miał nie zwracaną bezpośrednio przez funkcję, ale musiałbym podać "wskaźnik" do zmiennej w argumencie funkcji i moja funkcja zapisze wartość do tej zmiennej. A sama funkcja mogła by zwracać swój stan 0 - udało się wykonać funckję prawidłowo; 1 - "jakiś tam błąd".

    Tylko czy to jest "zgodne ze sztuką"? Zastanawiam się czy się tu nie pogubię?

    I jeszcze jedno.
    Jak poradzić sobie w przypadku gdy są dwie funkcję i jedna jest używana w drugiej, np. w ten sposób:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    i teraz wywołując PobierzStan chcę wiedzieć o tym, czy funkcja "Wyslij" wykonała się prawidłowo.
  • REKLAMA
  • #2 21503071
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1462
    Dialekt Arduino to nie C a C++, i tu możliwości są znacznie większe.
    Pozostawanie w archaicznym C 1980 to masochizm.

    Pierwsze z brzegu to referencja (inne to rozwiązania obiektowe - a na 32 bitowych nie widzę powodów nie używać)

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    enum, wiele innych technik których nie użyć jest świadomym zacofaniem
  • REKLAMA
  • #3 21503957
    gps79
    Poziom 37  
    Posty: 2190
    Pomógł: 495
    Ocena: 792
    Adam Ś. napisał:
    Tylko czy to jest "zgodne ze sztuką"?

    Samo Arduino nie jest zgodne ze sztuką, więc tym się nie przejmuj. Z czasem, jeśli będziesz kontynuował naukę programowania, będziesz pisał coraz lepiej.

    Adam Ś. napisał:
    Zastanawiam się czy się tu nie pogubię?

    Pogubisz się i to nie raz. C++ i Arduino mają w sobie tyle tajemnic, że na 10 lat zaskoczeń wystarczy.

    Funkcje w C i C++ mogą zwracać wartości. Wartości zwracane można użyć bezpośrednio lub przechwycić do zmiennej i użyć później.
    Dla przykładu:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Poczytaj lub pooglądaj jakiś kurs C++. Wiele tematów się wyjaśni.
  • #4 21504165
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1462
    gps79 napisał:
    Samo Arduino nie jest zgodne ze sztuką, więc tym się nie przejmuj. Z czasem, jeśli będziesz kontynuował naukę programowania, będziesz pisał coraz lepiej.



    Nauka ogólnego programowania na uK w tym Arduino to bardzo zła polityka.
    Po pierwsze dominacja bardzo kiepskich wzorców, szkodliwych (antywzorców). Brak refleksji "jak zrobić to naprawdę dobrze", zadowolenie że "przecież działa", dom który się nie zawalił tzn jest dobrze zbudowany.
    Po drugie staje się przed DWOMA grupami problemów, sprzętowymi (środowiskowymi) i prawdziwymi programistycznymi w mieszance 2w1.

    Do nauki tylko pecet i na niego "duże" projekty, kontakt z jednak głębszą (pod względem programistycznym) społecznością

    Dodano po 3 [minuty]:

    Samo pytanie tego wątku, mądre pytanie, jego nie stawia sobie tego 99% programujących elektroników (albo tych, którym się wydaje że programują), tak samo innych dobrych pytań architekturalnych.

    Dodano po 19 [minuty]:

    Na czymś tak słabym jak Atmega8 miałem fajne rozwiązania, jak np kolejka zdarzeń z klawiszy "hardwaru" do "poziomu aplikacji" (stała ale wystarczająca głębokość kolejki), długie wciśnięcie, krótkie wciśnięcie, KeyDown, Key Up itd...
    Coś jak daleka inspiracja kolejką zdarzeń Windows 2.0

    To nie było Arduino, tylko C++ na poziomie AVR.
    Skądinąd wbrew tępicielom diabłów C+ za pomocą święconej wody C i asemblera, sama rekompilacja na C++ dała 2 bajty oszczędności w danych i ok 10 bajtów kodu (sądzę, że wykrycie i optymalizacja "private")

    O tak, zapomnialem, już samo słowo "private" jest kochane w temacie o który pytasz.
  • REKLAMA
  • #5 21504198
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #6 21513238
    _jta_
    Specjalista elektronik
    Posty: 48919
    Pomógł: 3201
    Ocena: 4212
    Adam Ś. napisał:
    Funkcja ta coś tam robi, operuje na danych i ma zwrócić wynik. Chciałbym móc jakoś sprawdzać czy funkcja wykonała się prawidłowo. Niby można by zrobić tak, że gdy funkcja zwraca wartości większe lub równe 0 to wtedy jest ok, a gdy zwróci np. -1 to znaczy, że jest jakiś błąd. Ale problem w tym, że wynikiem tej funkcji, może być też wartośc ujemna i wtedy ten sposób jest niemożliwy.

    Jeśli funkcja może zwracać jako poprawne wszystkie możliwe wartości swojego typu, to rzeczywiście ten sposób jest niemożliwy; jeśli np. od -10000 do +10000, to dla typu wyniku int16 błąd można sygnalizować zwracając np. 0x8000 (=-32768); dla typu float są specjalne wartości, jak INF (infinity, czyli nieskończoność), czy NAN (not-a-number, czyli nie-liczba).

    Ale np. w Linux-ie (i w wielu funkcjach bibliotecznych w C) stosuje się taki sposób, że wynik funkcji tylko informuje, czy wykonała się poprawnie, a dane są przekazywane przez adres podany argument (argument jest wskaźnikiem). Choćby czytanie z pliku - dane trafiają do bufora, a funkcja zwraca liczbę przeczytanych bajtów (i -1 oznacza błąd).

    Z pewnymi funkcjami jest problem - jakieś atoi(), czy atol() - bo to są funkcje do konwersji napisu na liczbę binarną, one mają prawo zwrócić dowolną liczbę 'int', czy 'long' - jak trzeba rozpoznać, czy konwersja jest prawidłowa, to trzeba użyć innej funkcji.

    JacekCz napisał:
    Dialekt Arduino to nie C a C++, i tu możliwości są znacznie większe.

    Hm... C++ przewiduje tworzenie obiektów - ale w czym, jak Arduino ma pamięci tyle, co kot napłakał?

    A w ogóle zaczynanie od C++ nie jest dobrym pomysłem - u nas któryś wykładowca tak uczył studentów, i w rezultacie mieliśmy kilka roczników absolwentów, którzy absolutnie nie nadawali się do pisania choćby prostych programów.
  • #7 21513263
    Konto nie istnieje
    Poziom 1  
  • #8 21513396
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1462
    _jta_ napisał:
    JacekCz napisał:
    Dialekt Arduino to nie C a C++, i tu możliwości są znacznie większe.

    Hm... C++ przewiduje tworzenie obiektów- ale w czym, jak Arduino ma pamięci tyle, co kot napłakał?



    Serio ?
    Typowy argument "nigdy nie poznałem, ale na pewno jest złe"

    Zapewniam cię, ze dalece nie chodzi o powoływanie obiektów ani wyłącznie, ani najbardziej.
    W/w projekt w C++ nie alokował dynamicznie ani jednego obiektu, a na RAM miałem malutką oszczędność. Atmega8

    Dodano po 1 [minuty]:

    _jta_ napisał:
    którzy absolutnie nie nadawali się do pisania choćby prostych programów.


    Tak, twój głos w takiej ocenie jest "szczególnie cenny"

Podsumowanie tematu

✨ Dyskusja dotyczy obsługi błędów w funkcjach napisanych w języku C dla platformy Arduino, ze szczególnym uwzględnieniem zwracania wyników i sygnalizowania błędów. Poruszono problem, jak przekazywać zarówno wynik działania funkcji, jak i informację o błędzie, gdy funkcja zwraca wartości z pełnego zakresu typu (np. int16_t). Zaproponowano różne podejścia: użycie wartości specjalnych (np. najmniejsza wartość typu int16_t jako kod błędu), zwracanie statusu operacji (np. bool lub enum) i przekazywanie wyników przez wskaźniki lub referencje. Podkreślono, że Arduino używa dialektu C++, co umożliwia stosowanie bardziej zaawansowanych technik, takich jak enum class, referencje, czy obiektowe wzorce projektowe, które ułatwiają czytelną i bezpieczną obsługę błędów. Wskazano, że nauka programowania mikrokontrolerów powinna być wspierana przez solidne podstawy programowania na PC, aby unikać antywzorców i lepiej rozumieć architekturę oprogramowania. Przykłady kodu ilustrujące zwracanie statusu i przekazywanie danych przez argumenty funkcji zostały podane jako praktyczne rozwiązania. Dyskusja zawiera także refleksje na temat złożoności C++ i jego zastosowania w środowisku mikrokontrolerów, zwłaszcza na platformach o ograniczonych zasobach, takich jak Atmega8.
Wygenerowane przez model językowy.
REKLAMA