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



Teraz jest 7 lut 2025, o 23:01


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 6 ] 
Autor Wiadomość
 Tytuł: Odbiór stringa
PostNapisane: 26 kwi 2019, o 16:38 
Offline
Użytkownik

Dołączył(a): 13 paź 2015
Posty: 303
Lokalizacja: Rybnik
Pomógł: 10

Cześć,

Mam problem, którego nie umiem na tą chwilę rozwiązać.

Jaki mam cel?
Mam w projekcie czujniki temperatury DS18B20 i żeby było wiadomo, który jest od czego to są odpytywane po adresie ID. Chcę teraz mieć możliwość zmianę tego adresu (w przypadku wymiany uszkodzonego czujnika) bez wgrywania nowego wsadu z nowym adresem ID (np. z aplikacji w telefonie).

Co już mam?
Narazie dwa czujniki - standardowe adresy czujników zapisane są w pamięci flash oraz zdefiniowałem sobie pamięci ram, eeprom

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


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


W programie wywołuję prze pętlą while mam z poradników Pana Mirka funkcję:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


DO TEJ PORY WSZYSTKO DZIAŁA

Problem mam z wpisaniem do pamięci EEPROM odebranego innego adresu, a w zasadzie to mam problem z odebraniem nowego adresu...

Wysyłam adres z aplikacji w telefonie tak:
Składnia: [ Pobierz ] [ Ukryj ]
język vb
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


W jednym polu tekstowym w aplikacji wpisuję np.: 0x28, 0xe, 0x53, 0xf6, 0x15, 0x00, 0x00, 0xce
a w drugim, np to samo niech będzie.

Chcę wysłać stringa w postaci: AT+CZUJ={0x28, 0xe, 0x53, 0xf6, 0x15, 0x00, 0x00, 0xce};{0x28, 0xe, 0x53, 0xf6, 0x15, 0x00, 0x00, 0xce} czyli powinienem uzyskać taką samą temperaturę w "z dwóch czujników w projekcie"

Jak odebrać takiego stringa?
ja to robię w ten sposób:

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


No i teraz nie mam żadnych odczytów temperatury. Przedstawiłem wszystko, żeby było wiadomo o co mi chodzi. Wydaje mi się, że jest problem z odebraniem tego stringa, czy dobrze w ogóle to robię?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 kwi 2019, o 14:03 
Offline
Użytkownik

Dołączył(a): 13 paź 2015
Posty: 303
Lokalizacja: Rybnik
Pomógł: 10

Odczytuję tak bo wziąłem przykład z YellowBooka, tam właśnie tak są odbierane komendy AT.

Wydaje mi się, że tutaj mam problem z typami zmiennych.

Mam zmienną tablicową typu unsigned char[8], która przechowuje adres czujnika DS18B20. Ja odbieram po UDP stringa (w postaci dwóch adresów) np.:
AT+CZUJ={0x28, 0x86, 0x6f, 0xcb, 0x08, 0x00, 0x00, 0xb0};{0x28, 0xe, 0x73, 0xf5, 0x05, 0x00, 0x00, 0xeb}

Teraz prawdopodobnie jest problem z zapisem odebranego po UDP stringa do zmiennej tablicowej typu unsigned char[8]. Wyczytałem gdzieś, że muszę zrobić konwersję z char na unsigned char za pomocą funkcji memcpy czyli w moim przypadku chyba powinno być:

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


temp_in - zmienna tablicowa unsigned char temp_in[8]
adres1 - zmienna przechowująca odebrany string
49 - ilość znaków w stringu + znak 0

jeszcze nie sprawdzałem tego bo nie jestem u siebie i nie mam tej możliwości, ale czy dobrze w ogóle myślę?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 kwi 2019, o 19:12 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Tom92 napisał(a):
Wyczytałem gdzieś, że muszę zrobić konwersję z char na unsigned char za pomocą funkcji memcpy...

Nie wiem, gdzie to wyczytałeś, ale funkcja memcpy() niczego nie konwertuje, ona tylko kopiuje dane z jednego miejsca pamięci RAM do innego. Obawiam się, że nie znajdziesz funkcji standardowej języka C, która przetworzy ciąg znaków w użytym przez Ciebie formacie "{0x28, 0x86, 0x6f, 0xcb, 0x08, 0x00, 0x00, 0xb0}" na wartości binarne i umieści w tablicy docelowej. Będziesz musiał sobie napisać taką funkcję sam.

Moim zdaniem lepiej byłoby pominąć te nawiasy klamrowe, prefiksy 0x oraz jeden ze znaków separatora (spację lub przecinek), aby ułatwić sobie zadanie. Te rzeczy potrzebne są w przypadku definiowania tablic stałych liczbowych i są potrzebne kompilatorowi do prawidłowej interpretacji wartości. W Twoim przypadku (zakładając, że ta komenda AT będzie zawsze zawierała 2x8 wartości w formacie heksadecymalnym) są to rzeczy zbędne, które tylko skomplikują Ci konwersję.

Przykładowy format mógłby wyglądać:

"AT+CZUJ=28,86,6f,cb,08,00,00,b0|28,0e,73,f5,05,00,00,eb"

W łatwiejszy sposób będzie można wyłowić dwucyfrowe podciągi znaków i przetworzyć je na odpowiadające im wartości liczbowe.

Tom92 napisał(a):
49 - ilość znaków w stringu + znak 0

Nie jestem pewien, czy na końcu ciągu wysyłasz znak '\0' (Null), czy raczej '\r' (Carriage Return). Chyba, że funkcja odbierająca to w jakiś sposób zmienia.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 kwi 2019, o 11:02 
Offline
Użytkownik

Dołączył(a): 13 paź 2015
Posty: 303
Lokalizacja: Rybnik
Pomógł: 10

andrews napisał(a):
Nie wiem, gdzie to wyczytałeś, ale funkcja memcpy() niczego nie konwertuje, ona tylko kopiuje dane z jednego miejsca pamięci RAM do innego.


Przepraszam, źle zrozumiałem to co czytałem.

andrews napisał(a):
Nie jestem pewien, czy na końcu ciągu wysyłasz znak '\0' (Null), czy raczej '\r' (Carriage Return).


Wysyłam '\r'.

Czyli odbiorę komendę AT w zaproponowanej przez Ciebie formie, następnie pierwszą część (do separatora '|') wpiszę do zmiennej char * adres1, a drugą do zmiennej char * adres2. Później nie wiem właśnie co z tym zrobić?

==========
Na szybko mi jeszcze przyszło do głowy, żeby utworzyć dodatkową zmienną tablicową, która w warunku if przed pętlą while() będzie brana pod uwagę jeśli będzie miała zapisany jakiś adres zamiast zmiennej temp_in[8] np.:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


następnie odczytane liczby do separatorów ',' wpisywać kolejno do zmiennych a,b,c,d,e,f,g,h. Oczywiście musiałbym jeszcze dodać do tych zmiennych dodatkowo na początku prefiks 0x i na końcu przecinek.

Czy nie tędy droga?
==========



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 kwi 2019, o 20:03 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Tom92 napisał(a):
następnie odczytane liczby do separatorów ',' wpisywać kolejno do zmiennych a,b,c,d,e,f,g,h. Oczywiście musiałbym jeszcze dodać do tych zmiennych dodatkowo na początku prefiks 0x i na końcu przecinek.


Widzę, że chyba coś Ci się pomieszało. Nie musisz niczego dodawać. Mam wrażenie, że nie rozumiesz różnicy pomiędzy wartością liczbową a ciągiem znaków.
Dla uproszczenia tablica dwuelementowa:

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

Ten zapis tworzy dwuelementową tablicę wartości. Kompilator utworzy zmienną poprzez zarezerwowanie w pamięci RAM dwóch bajtów i umieszczenie w nich przypisanych im wartości. Na podstawie prefiksu 0x zidentyfikuje format heksadecymalny i wartości obliczy poprzez:
0x28 = 2*16+8 = 40 (00101000 binarnie)
0x86 = 8*16+6 = 134 (10000110 binarnie)

Natomiast to, co Ty próbujesz zrobić, to chyba w efekcie coś w 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 to Ci się nie uda, ponieważ wyrażenie w cudzysłowie to tak naprawdę tablica znaków (kodów ASCII):
"0x28" to to samo co {'0', 'x', '2', '8', '\0'} lub {0x30, 0x78, 0x32, 0x38}
i tak traktuje to kompilator, a nie jako wartość 0x28.
Rozumiesz chyba, że nie da się wpisać całego ciągu do pojedynczej zmiennej jednobajtowej.

Dlatego też, kiedy już wydobędziesz sobie z komendy AT jakiś dwucyfrowy ciąg znaków (np. za pomocą funkcji strtok() ) musisz użyć funkcji, która skonwertuje go na jednobajtową wartość.
Biorąc przykładowo ciąg znaków "4C", Twoja funkcja powinna:
  1. odczytać kod ASCII pierwszego znaku - tutaj będzie to 0x34 ('4')
  2. na podstawie tej wartości znaku ASCII obliczyć wartość pierwszej cyfry - tutaj będzie to 4
  3. odczytać kod ASCII drugiego znaku - tutaj będzie to 0x43 ('C')
  4. na podstawie tej wartości znaku ASCII obliczyć wartość drugiej cyfry - tutaj będzie to 12
  5. obliczyć wartość na podstawie wzoru
    wynik = (wartość pierwszej cyfry)*16+(wartość drugiej cyfry)
    czyli w naszym wypadku 4*16+12=76
  6. zwrócić wynik

I tak po kolei wszystkie dwucyfrowe ciągi znaków, przetworzyć na wartości jednobajtowe i przypisać do odpowiednich elementów Twojej tablicy adres1[].

Można byłoby też ewentualnie użyć do konwersji funkcji strtoul() z biblioteki standardowej, ale to trochę przerost formy nad treścią.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 kwi 2019, o 07:49 
Offline
Użytkownik

Dołączył(a): 13 paź 2015
Posty: 303
Lokalizacja: Rybnik
Pomógł: 10

andrews napisał(a):
Kompilator utworzy zmienną poprzez zarezerwowanie w pamięci RAM dwóch bajtów i umieszczenie w nich przypisanych im wartości. Na podstawie prefiksu 0x zidentyfikuje format heksadecymalny i wartości obliczy poprzez:
0x28 = 2*16+8 = 40 (00101000 binarnie)
0x86 = 8*16+6 = 134 (10000110 binarnie)


Nie wiedziałem jak traktuje to kompilator. Dziękuje Ci andrews za cierpliwość i szczegółowe wytłumaczenie, teraz na podstawie nowej wiedzy postaram się napisać funkcję konwertującą. Jak będę miał jeszcze pytania to się odezwę.



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: 6 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

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


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:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO