Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 25 lip 2025, o 20:49


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 23 ] 
    Autor Wiadomość
    PostNapisane: 24 sie 2019, o 17:55 
    Offline
    Nowy

    Dołączył(a): 03 sty 2014
    Posty: 19
    Pomógł: 0

    Cześć,

    Pewnie znowu się zbłaźnię głupim pytaniem - ale czasami utykam w martwym punkcie, a pomoc od Was pomaga mi ruszyć dalej.

    Problem jest następujący. Używam NRF24L01 oraz bibliotek NRF24L01 oraz SPI.
    Udało mi się po wielu próbach uruchomić komunikację.

    Problemem jest natomiast (tak mi się wydaje) nie zrozumienie przeze mnie funkcji parse_nrf_data.
    Nie za bardzo wiem jak dużo mogę kodu zawierającego tą bibliotekę udostępniać, dlatego dam tylko wycinki.

    W miejscu przykładu wstawiłem: (odbiornik)

    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    i co zabawne - działa tylko np. 97 (a), lub 98 (b).
    target przyjmuje poprawną wartość zgodnie z konkretnym ifem.

    W przypadku gdy wyślę np. 95 - program przeskakuje po ifach, jakby losowo (pewnie nie losowo, ale ja nie mogę zauważyć prawidłowości).

    kod nadajnika:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    I tu znowu dziwna rzecz:
    Pobieram dane z UART - wpisuje je do rData i wysyłam przez NRF.
    Jak wysyłam a(97), b(98) wszystko jest ok.
    Gdy wyślę c(99) - układ się zawiesza (przestaje nadawać, pisać na UART) - muszę zresetować zasilanie. Wszystko potem wraca do normy.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 18:21 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 24 mar 2012
    Posty: 72
    Pomógł: 5

    Cześć,

    odniosę się, przynajmniej na razie, do tego zdania:
    "W przypadku gdy wyślę np. 95 - program przeskakuje po ifach, jakby losowo (pewnie nie losowo, ale ja nie mogę zauważyć prawidłowości)."

    Co to znaczy losowo ? Korzystasz z debuggera rozumiem ? Używasz tego na stmie ? nie masz przypadkiem włączonej optymalizacji przy kompilacji ?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 18:50 
    Offline
    Użytkownik

    Dołączył(a): 09 lip 2019
    Posty: 121
    Pomógł: 12

    goslawen napisał(a):
    [...]
    Problemem jest natomiast (tak mi się wydaje) nie zrozumienie przeze mnie funkcji parse_nrf_data.
    Nie za bardzo wiem jak dużo mogę kodu zawierającego tą bibliotekę udostępniać, dlatego dam tylko wycinki.

    W miejscu przykładu wstawiłem: (odbiornik)

    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    [...]
    W/g dokoumentacji "The strcmp_P() function is similar to strcmp() except that s2 is pointer to a string in program space."

    Jeśli dobrze rozumiem - następujący zapis
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    prawdopodobnie porównuje bufor 'buf' z przypadkową zawartością pamięci programu

    Czy liczba 98 nie powinna być przypadkiem w "ciapkach"? (tzn. w cudzysłowach).
    Najlepiej chyba jakby te stringi były zdeklarowane gdzieś jako progmem.

    czyli coś w tym stylu

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    a w ifach
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    i tak dalej. Na początek można też spróbować ze zwykłym strcmp np.
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    co do kodu nadajnika - to niestety nie mam doświadczenia :-)


    PS. Jeśli faktycznie porównanie miałoby być z pojedynczym znakiem o kodzie 95, to wtedy dla tego kodu string nie powinien być "95" tylko odpowiedni znak ASCII, ale zokończony terminującym zerem, czyli w "ciapkach"
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    lub trzeba by użyć funkcji strncmp_P z podaną długością 1
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 19:45 
    Offline
    Nowy

    Dołączył(a): 03 sty 2014
    Posty: 19
    Pomógł: 0

    banita 17 napisał(a):
    Cześć,

    odniosę się, przynajmniej na razie, do tego zdania:
    "W przypadku gdy wyślę np. 95 - program przeskakuje po ifach, jakby losowo (pewnie nie losowo, ale ja nie mogę zauważyć prawidłowości)."

    Co to znaczy losowo ? Korzystasz z debuggera rozumiem ? Używasz tego na stmie ? nie masz przypadkiem włączonej optymalizacji przy kompilacji ?



    Cześć,
    Dziękuję za odpowiedź.
    Tak, używam debuggera ( Atmel-ICE). To niejako samoczynnie odpowiada na kolejne pytanie - używam tego w AVR- konkretniej ATmega 32u4.
    Pracuję w AVR studio. Nie wiem czy mam włączoną optymalizację - faktycznie sprawdzę i przetestuję.

    ------------------------ [ Dodano po: kilkunastu sekundach ]

    moscow napisał(a):
    goslawen napisał(a):
    [...]
    Problemem jest natomiast (tak mi się wydaje) nie zrozumienie przeze mnie funkcji parse_nrf_data.
    Nie za bardzo wiem jak dużo mogę kodu zawierającego tą bibliotekę udostępniać, dlatego dam tylko wycinki.

    W miejscu przykładu wstawiłem: (odbiornik)

    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    [...]
    W/g dokoumentacji "The strcmp_P() function is similar to strcmp() except that s2 is pointer to a string in program space."

    Jeśli dobrze rozumiem - następujący zapis
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    prawdopodobnie porównuje bufor 'buf' z przypadkową zawartością pamięci programu

    Czy liczba 98 nie powinna być przypadkiem w "ciapkach"? (tzn. w cudzysłowach).
    Najlepiej chyba jakby te stringi były zdeklarowane gdzieś jako progmem.

    czyli coś w tym stylu

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    a w ifach
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    i tak dalej. Na początek można też spróbować ze zwykłym strcmp np.
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    co do kodu nadajnika - to niestety nie mam doświadczenia :-)


    PS. Jeśli faktycznie porównanie miałoby być z pojedynczym znakiem o kodzie 95, to wtedy dla tego kodu string nie powinien być "95" tylko odpowiedni znak ASCII, ale zokończony terminującym zerem, czyli w "ciapkach"
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    lub trzeba by użyć funkcji strncmp_P z podaną długością 1
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



    Dziękuję za obszerną poradę, chwilę mi zajmie jej przeanalizowanie. Wrócę mam nadzieję z rozwiązaniem problemu lub co mniej optymistyczne z prośbą o kolejne rady.
    Postaram się odpowiedzieć jeszcze dzisiaj.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 20:03 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 24 mar 2012
    Posty: 72
    Pomógł: 5

    Nie wiem jak jest w TrueStudio niemniej w konsoli podczas kompilacji powinieneś mieć jakieś logi (tylko się domyślam) i tam w opcjach kompilatora gdzieś powinien być zapis "-O0" jeżeli jest inny tzn. np -O1 to może być przyczyną 'dziwnie' zachowującego się debuggera. Przykładowy link z konsoli w którym widać wybraną optymalizację:

    Obrazek

    a co do reszty problemów to tak jak mówił użytkownik 'moscow' powinieneś porównywać stringi co znaczy ciągi znaków. Zakładam, że wiesz czym różni się taki zapis:
    char string[] = "a";

    od takiego zapisu:
    char znak[1];
    znak[0] = 'a'

    W tym przypadku string przechowuje dwa znaki: znak litery 'a' oraz znak końca łańcucha znaków tzn NULL natomiast znak[0] przechowuje jedynie znak litery 'a'.

    Ponadto funkcja "strcmp_P" porównuje dwa ciągi znaków przy czym zakłada, że jeden z nich znajduje się w pamięci Flash (PROGMEM) myślę, że na to również powinieneś zwrócić uwagę



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 20:10 
    Offline
    Nowy

    Dołączył(a): 03 sty 2014
    Posty: 19
    Pomógł: 0

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    W taki użyciu niestety zawsze mi wchodzi do każdego IFa.
    Zadeklarowałem:
    const char str_95 PROGMEM = '_';
    const char str_97 PROGMEM = 'a';
    const char str_98 PROGMEM = 'b';

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 20:16 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 24 mar 2012
    Posty: 72
    Pomógł: 5

    Bo funkcja strcmp_P() porównuje stringi tzn ciągi znaków. Brakuje jej znaku NULL na końcu. Spróbuj tak:

    const char str_95[] PROGMEM = "_";
    const char str_97[] PROGMEM = "a'';
    const char str_98[] PROGMEM = "b";


    Jeszcze jedna sprawa. Przy Twoich wcześniejszych próbach tzn:

    const char str_95 PROGMEM = '_';
    const char str_97 PROGMEM = 'a';
    const char str_98 PROGMEM = 'b';

    powinieneś użyć dodatkowo znaku '&' przy wywołaniu funkcji strcmp_P() tzn: if (!strncmp_P(buf, &str_97, 1)); z uwagi na to, że funkcja strcmp_P przyjmuje wskaźniki. tzn adres do komórki pamięci gdzie się znajduje ciąg znaków.

    w przypadku zmiennej 'buf' znaku '&' nie trzeba używać bo jest to tablica a w języku C nazwa tablicy bez żadnych innych znaków jest adresem na jej pierwszy element. (buf oraz &buf[0] jest tożsame)



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 20:30 
    Offline
    Nowy

    Dołączył(a): 03 sty 2014
    Posty: 19
    Pomógł: 0

    Faktycznie miałem włączoną optymalizację.
    Ustawia się ją w drzewku "solution explorer" -> "properties -> toolchain -> optimalizer -> None (-O0).
    Niestety niewiele to zmieniło.

    Po wprowadzeniu zmian w
    const char str_95[] PROGMEM = "_";
    const char str_97[] PROGMEM = "a'';
    const char str_98[] PROGMEM = "b";

    nadal debugger "odwiedza" każdy z IFów.
    Zakładam, że teraz jest poprawnie po stronie odbiornika, więc może jakiś podobny problem jest z nadajnikiem?

    Przyznam szczerze, że do tej pory wydawało mi się, że rozumiem różnice pomiędzy większością zapisów dotyczących np. char[1] itp, ale gdy przyszło do praktyki zaczęło mi się strasznie wszystko mieszać.

    ------------------------ [ Dodano po: 14 minutach ]

    Dla sprawdzenia i upewnienia się:

    char znak[1]; // tablica 1 "miejscowa"
    znak[0] = 'a' // "miejsce" zerowe w tablicy

    'a' -> to po prostu a
    "a" -> to a + \0
    string[] "a" - > a+\0

    Zgadza się?



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 20:48 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 24 mar 2012
    Posty: 72
    Pomógł: 5

    Optymalizacja zmieniła teraz tyle, że podczas debugowania nie ma problemów ze 'skaczącym' debuggerem ale nie mogła ona mieć wpływu na sposób wykonywania się programu. Nie mniej polecam debugować programy bez optymalizacji :P

    Jest możliwość, żebyś sprawdził co znajduje się w zmiennej buf ? za pomocą debuggera oczywiście.

    Bo szczerze mówiąc to wydaje się, że powinno to działać. Ewentualnie skompiluj sobie prosty/pusty program w w którym zrobisz coś takiego:


    char str_97[] PROGMEM = "a";
    char buf[] = "a"

    if (!strncmp_P(buf, str_97, 1));
    {
    // zrób coś np zapal diodę
    }
    else
    {
    //zalap inną diodę
    }

    Powinna się zapalić dioda z pierwszej klamerki jeżeli wszystko działa tak jak sobie wyobrażamy. Jeżeli nie zadziała zgodnie z oczekiwaniami no to wtedy trzeba będzie to dalej szlifować :D

    ------------------------ [ Dodano po: 4 minutach ]

    goslawen napisał(a):
    Faktycznie miałem włączoną optymalizację.
    Dla sprawdzenia i upewnienia się:

    char znak[1]; // tablica 1 "miejscowa"
    znak[0] = 'a' // "miejsce" zerowe w tablicy

    'a' -> to po prostu a
    "a" -> to a + \0
    string[] "a" - > a+\0

    Zgadza się?


    Zgadza się. Aczkolwiek prawdę mówiąc to jak spojrzysz sobie na funkcję int strncmp_P(const char * s1,const char * s2, size_t n ) to ona sprawdza określoną liczbę znaków - określasz to parametrem size_t n. Wiec w tym przypadku nie ma wielkiego znaczenia czy porównujesz string do stringa czy string do tablicy ze znakami ale bez nulla na końcu. Ale gdybyś nie miał tutaj parametru size_t n to byłoby to niebezpieczne porównywać string do tablicy ze znakami/znakiem()bez nulla (w niektórych przypadkach mogłoby działać w innych by się wykrzaczyło z hukiem)


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 20:56 
    Offline
    Nowy

    Dołączył(a): 03 sty 2014
    Posty: 19
    Pomógł: 0

    banita 17 napisał(a):

    Jest możliwość, żebyś sprawdził co znajduje się w zmiennej buf ? za pomocą debuggera oczywiście.



    W zmiennej buf aktualnie znajduje się:

    0x0103 // wysyłam b

    i teraz żeby było śmieszniej

    0x0103 // wysylam a

    teraz juz zdębiałem...

    str_95 =0x00ac
    str_97 =0x00ae
    // debugger wydaje się działać poprawnie...



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 21:07 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 24 mar 2012
    Posty: 72
    Pomógł: 5

    Jesteś pewien, że na debuggerze podglądasz wartość zmiennej a nie adres w pamięci pod jakim zmienna się znajduje ?
    Jak patrzysz na to:

    str_95 =0x00ac
    str_97 =0x00ae

    to wcale nie wydaje mi się, żeby to był dobry wynik. Jak włączysz sobie tablicę ASCII to okaże się, że litera 'a' ma w decu wartość 97 a w hexie wartość 0x61 co nijak ma się do wartości 0x00ae. Upewnij się więc, że sprawdzasz faktycznie wartości zmiennych a nie adresy w pamięci pod jakimi te zmienne się znajdują



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 21:10 
    Offline
    Nowy

    Dołączył(a): 03 sty 2014
    Posty: 19
    Pomógł: 0

    Nie wiedziałem, że mogę wykonać to źle :)
    Po prostu nakierowuję myszkę na zmienną i wyświetla się wartość.
    W przypadku innych zmiennych tak to właśnie działa.
    Można to podejrzeć inaczej?

    watch 1:

    name | Value | Type
    buf | 0x0103 | char*{data}@0x0acb ([R28]+1)



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 21:18 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 24 mar 2012
    Posty: 72
    Pomógł: 5

    heheheh.. No tak. Śmieszna sprawa. Czym jest wskaźnik ? Wskaźnik to jest adres w pamięci programu. Czyli jednym słowem wartości wskaźnika to jest adres w pamięci. Czyli jak doczytujesz debuggerem zmienną 'buf' która jest zdefiniowana jako tablica np char buf[5] to debugger poda ci wartość czyli adres. Jeżeli chcesz podejrzeć jakie znaki znajdują się w tym buforze to musisz zrobić tak:

    char pierwszyZnakBufora = buf[0];
    char drugiZnakBufora = buf[1];

    i teraz dopiero debuggerem/myszką najechać na zmienne 'pierwszyZnakBufora ' i 'drugiZnakBufora ' i wtedy dowiesz się jakie znaki faktycznie tam się znajdują. Analogicznie ze zmiennymi w pamięci PROGMEM.

    Mam nadzieję, że rozumiesz ? Jeżeli za słabo to wytłumaczyłem to śmiało mów bardziej się wysilę :D


    Autor postu otrzymał pochwałę


    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 21:28 
    Offline
    Nowy

    Dołączył(a): 03 sty 2014
    Posty: 19
    Pomógł: 0

    znak0 = buf[0]; - wartość 192
    znak1 = buf[1]; - wartość 10
    znak2 = buf[2]; - wartość 148
    znak3 = buf[3]; - wartość 110
    znak4 = buf[4]; - wartość 200

    Przez przypadek zauważyłem też, że zdarza się "wylecieć" programowi z powrotem do main().

    Po chwili - nadajnik ciągle wysyła -> f

    znak0 = buf[0]; - wartość 192
    znak1 = buf[1]; - wartość 7
    znak2 = buf[2]; - wartość 12
    znak3 = buf[3]; - wartość 148
    znak4 = buf[4]; - wartość 108



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 21:39 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 24 mar 2012
    Posty: 72
    Pomógł: 5

    Hmmm... czyli jednym słowem w zmiennej buf znajduje się coś czego zupełnie się nie spodziewamy. Wydaje mi się, że musisz 'pójść' z debuggerem wcześniej tzn przed wywołanie funkcji: void parse_nrf_data ( char * buf, uint8_t len ) i sprawdzić czy tam w którejś ze zmiennych które później przekazujemy do tablicy buff jest to czego byśmy się spodziewali. Bo liczba 192 jest poza zakresem tablicy ASCII.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 22:04 
    Offline
    Nowy

    Dołączył(a): 03 sty 2014
    Posty: 19
    Pomógł: 0

    W związku z tym, że sprawdzenie mojego problemu rozbija się o miejsca w kodzie Mirka napisałem wiadomość prywatną, żeby nie udostępniać wycinków biblioteki.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 22:46 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27416
    Lokalizacja: Szczecin
    Pomógł: 1043

    No i tak to bywa - debuger nie załatwi sam pewnych spraw za programistę ... Tak poczytałem ten wątek ... i aż troszkę strach bierze gdy kolega autor wątku pisze np takie coś:

    Cytuj:
    char str_95 PROGMEM = '_';
    strncmp_P(buf, str_95, 1);


    Po prostu tragedia - proponuję jednak wrócić do podstaw i zastanowić się co to jest C-String, czyli string w C ... bo to nigdy w życiu nie jest stringiem, i jeśli korzystanie z funkcji strncmp_P() lub podobnych powoduje wykładanie się procka do góry nogami i jak kolega pisze powrót do main() ;) albo losowe działanie IF'ów to - .... to panie kochany ....

    1. to nie jest żaden powrót do main tylko "pierdyknięcie stosu" bo próbujesz porównywać nie stringa tylko np pół pamięci FLASH zanim funkcja porównująca dojdzie do końca tego rzekomego stringa czyli do zera

    2. to nie jest żadne losowe działanie IFów tylko mega PASKUDNY niestety czy tego chcesz czy nie babol programisty, który nie wie co to jest STRING w języku C

    i na to nie pomoże żaden DEBUGER jak widać - bo już od dłuższego czasu widzę walczysz z debugerem i wciąż ten sam efekt.

    ---------------------------------

    Przypominam już w Bluebooku masz napisane co to jest C-String .... otóż taki STRING MUSI być Qurczę zakończony znakiem NULL czyli zerem

    to:

    Cytuj:
    char str_95 PROGMEM = '_'; // to zajmie JEDEN koci bajt !!!


    nie jest żaden Qurdę string tylko jakaś definicja stałej dosłownej - w tym wypadku jednego znaku i nie ZAKOŃCZONA zerem rozumiesz ? Już pomijam że brakuje specyfikatotra const

    TO jest STRING

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    no to są PODSTAWY PODSTAW z Bluebooka i bardzo dobrze tam opisane. Jeśli się tego nie zrozumie - to się będzie miało do czynienia z GIGANTYCZNYMI KASZANAMI w kodzie i dlatego tak dużo miejsca temu poświęciłem. W języku C - trzeba zrozumieć co to jest STRING.

    ------------------------ [ Dodano po: 3 minutach ]

    Stałe dosłowne, literały są często umiejscawiane w pamięci FLASH przez kompilator na samym początku przed kodem programu. Przez co za takim literałem nie zakończonym zerem mogą być kolejne znaki i kolejne aż w końcu kod programu i długo może nie być zera ... próba używania funkcji do operacji na stringach - którym daje się do jedzenia TAK NIESTRAWNE danie w postaci sztucznych zatrutych stringów - spowoduje, że procek dostanie niestrawności i wymiotów

    a na poważnie to i stos może się przekręcić aby na końcu zresetować procka - a tobie się wydaje, że program wraca w jakiś dziwny tajemniczy sposób do main(). Nie - nie wraca tylko następuje najzwyklejszy okrutny restart

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 24 sie 2019, o 23:16 
    Offline
    Nowy

    Dołączył(a): 03 sty 2014
    Posty: 19
    Pomógł: 0

    Mirku,

    Jak wcześniej możesz zauważyć w moim kodzie nie było zupełnie

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    czy

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Pisząc te kody koledzy wyjaśniali mi jakie mogą być potencjalne problemy.

    Dziękuję bardzo, bo trochę mi się to wszystko poukładało, a takie przykłady pozwalają dopiero to zrozumieć. Bez prób, często tych najgłupszych nigdy nie jestem w stanie czegoś zrozumieć do końca.

    Niestety mimo użycia

    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    program dalej zachowuje się dziwnie, czego nie jestem w stanie zrozumieć.

    Jak zauważysz wyżej, po sugestii kolegi w buf[x] pojawiają się dziwne wartości, więc albo coś mocno sknociłem w kodzie w innym miejscu albo mam np.wadliwe nrf.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 25 sie 2019, o 05:09 
    Offline
    Moderator
    Avatar użytkownika

    Dołączył(a): 03 paź 2011
    Posty: 27416
    Lokalizacja: Szczecin
    Pomógł: 1043

    goslawen napisał(a):
    program dalej zachowuje się dziwnie, czego nie jestem w stanie zrozumieć.

    No to twoim zadaniem jest WYIZOLOWAĆ problem. Czyli ? ...

    Skróć go tak jak się da - pokaż tylko ten fragment który ci nie działa i opisz co to znaczy, że zachowuje się dziwnie - bo wybacz ale to bez sensu - zadawać pytanie na forum typu:

    "Panowie program zachowuje mi się dziwnie - pomożecie?"

    Po tym co robisz widać, że nie ma to nic a nic wspólnego z jakimś NRF ... porzuć zatem ten projekt na chwilę, załóż nowy i wymyśl sobie prosty test do porównywania stringów - bo widać, że zdaje się z tym masz największy problem.

    Do tego wystarczy kawałek wyświetlacza LCD a zdaje się masz zestawik ATB to nie powinno być kłopotu napisać jakiś mały fragment kodu do przetestowania .... i zamiast też pisać, że

    " ... mimo użycia czegoś tam - nadal mi nie działa"

    Panie kod swój pokazuj jeśli wprowadzasz poprawki - mówię o tym testowym ok? No niestety tego też trzeba się nauczyć - to PODSTAWA PODSTAW jeśli chodzi o programowanie

    _________________
    zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 25 sie 2019, o 08:42 
    Offline
    Użytkownik

    Dołączył(a): 18 sie 2019
    Posty: 69
    Zbananowany użytkownik

    Pomógł: 2

    banita 17 napisał(a):
    Nie mniej polecam debugować programy bez optymalizacji :P

    Nie jest to dobry pomysł. Niektóre operacje ne peryferiach nie będą działać, bo pomiędzy zapisami będzie pauza większa niż 4 cykle zegara. Nie da się wiec zapisać EEPROM, ustawiać watchdoga, itp.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 25 sie 2019, o 09:59 
    Offline
    Użytkownik

    Dołączył(a): 09 lip 2019
    Posty: 121
    Pomógł: 12

    mirekk36 napisał(a):
    No i tak to bywa - debuger nie załatwi sam pewnych spraw za programistę ... Tak poczytałem ten wątek ... i aż troszkę strach bierze gdy kolega autor wątku pisze np takie coś:

    Cytuj:
    char str_95 PROGMEM = '_';
    strncmp_P(buf, str_95, 1);


    Po prostu tragedia - proponuję jednak wrócić do podstaw i zastanowić się co to jest C-String, czyli string w C ... bo to nigdy w życiu nie jest stringiem, i jeśli korzystanie z funkcji strncmp_P() lub podobnych powoduje wykładanie się procka do góry nogami i jak kolega pisze powrót do main() ;) albo losowe działanie IF'ów to - .... to panie kochany .... [...[

    Tak gwoli ścisłości, to akurat ta dokładnie konstrukcja zadziała (przy założeniu, że zawartość buf[] jest zgodna z oczekiwaniami) i nie spowoduje wyłożenia się procka.
    To jest strncmp (ograniczony do jednego bajtu ostatnim argumentem), a nie strcmp.
    Co prawda wygląda na to, że akurat strncmp_P jest napisane w asemblerze, ale typowa implementacja zwykłego strncmp wygląda mniej więcej tak jak niżej i sprawdzenie końca ciągu znaków odbywa się explicite tylko dla s1
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Czy jej użycie ma sens - to inna historia. Zasugerowałem ją, bo nie wiedziałem z pierwszego postu o co dokładnie chodzi... czy porównywany ma być pojedynczy znak, czy para znaków.
    Dla pojedynczego znaku i przy pewności, że chodzi porównanie będzie dotyczyło pierwszego znaku w buforze - pewnie wystarczyłoby zwykłe
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Co do pozostałych uwag - całkowicie się zgadzam :-) Niemniej z tego co Koledzy już zauważyli - problem jest raczej po stronie zawartości pamięci wskazywanej przez zmienną buf a nie samych porównań :-)



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 25 sie 2019, o 10:52 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 24 mar 2012
    Posty: 72
    Pomógł: 5

    Semi napisał(a):
    banita 17 napisał(a):
    Nie mniej polecam debugować programy bez optymalizacji :P

    Nie jest to dobry pomysł. Niektóre operacje ne peryferiach nie będą działać, bo pomiędzy zapisami będzie pauza większa niż 4 cykle zegara. Nie da się wiec zapisać EEPROM, ustawiać watchdoga, itp.


    Ciekawa teza aczkolwiek ostatecznie uważam, że nie masz racji. Masz jakieś doświadczenia z tym związane ? Jakaś opis który by to potwierdził ? (Jak coś to nie jestem złośliwy tylko ciekawy, chętnie się czegoś nowego dowiem :) )


    A co do autora wątku to nie musimy uciekać na prv. Będziesz musiał sam trochę popracować ;) Możesz wstawić linijkę z wywołaniem funkcji: void parse_nrf_data ( char * buf, uint8_t len ) oraz linijkę w której pokazałbyś skąd dane biorą się w buforze którego wskaźnik przekazujesz do funkcji parse_nrf_data do argumentu 'buf'.

    I tak jak Mirek powiedział musisz zjeść tego słonia po kawałku tzn krok po kroku analizuj co i gdzie. Masz wyświetlacz, diody + do tego debugger to naprawdę spore możliwości. Musisz iść w stronę 'źródła' danych bufora 'buf' i sprawdzić w którym kroku dysponujesz danymi których faktycznie oczekujesz



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 25 sie 2019, o 14:33 
    Offline
    Użytkownik

    Dołączył(a): 18 sie 2019
    Posty: 69
    Zbananowany użytkownik

    Pomógł: 2

    banita 17 napisał(a):
    Semi napisał(a):
    banita 17 napisał(a):
    Nie mniej polecam debugować programy bez optymalizacji :P

    Nie jest to dobry pomysł. Niektóre operacje ne peryferiach nie będą działać, bo pomiędzy zapisami będzie pauza większa niż 4 cykle zegara. Nie da się wiec zapisać EEPROM, ustawiać watchdoga, itp.


    Ciekawa teza aczkolwiek ostatecznie uważam, że nie masz racji. Masz jakieś doświadczenia z tym związane ? Jakaś opis który by to potwierdził ? (Jak coś to nie jestem złośliwy tylko ciekawy, chętnie się czegoś nowego dowiem :) )

    Skompiluj program bez optymalizacji i zobacz rozwinięcie asm.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    Wyświetl posty nie starsze niż:  Sortuj wg  
    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 23 ] 

    Strefa czasowa: UTC + 1


    Kto przegląda forum

    Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość


    Nie możesz rozpoczynać nowych wątków
    Nie możesz odpowiadać w wątkach
    Nie możesz edytować swoich postów
    Nie możesz usuwać swoich postów
    Nie możesz dodawać załączników

    Szukaj:
    Skocz do:  
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO