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



Teraz jest 27 kwi 2026, o 22:39


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 14 ] 
Autor Wiadomość
PostNapisane: 17 lip 2016, o 19:31 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Szanowni Forumowicze,
zabrałem się za poznawanie standardu TWI i do tego celu mam czujnik temperatury i wilgotności HTU21D w module od Sparkfun. Szukałem rozwiązania na Forum i znalazłem temat poświęcony zagadnieniu:
topic11029.html
Nie rozumiem jednak 9. linijki kodu w tym poście:
topic11029.html#p123238

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


Bardzo proszę o wskazówki jak prawidłowo przeczytać tę linijkę kodu i pozdrawiam.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 17 lip 2016, o 22:25 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 cze 2014
Posty: 76
Pomógł: 10

While (len--) -> Dopóki zmienna len, od której z każdym obiegiem jest odejmowane jeden wykonuj
*buf++ -> Wskaźnik na kolejny element bufora jest przypisywany do wyniku
TWI_read( len ? ACK : NACK ) -> Funkcja odczytująca dane. W jej argumencie podajemy ACK ( potwierdzenie ) lub NACK ( brak potwierdzenia ). Tutaj wyrażenie warunkowe sprawi, że wysyłane będzie ACK dopóki zmienna len będzie różne od zera. (Strona 105 BB)


Autor postu otrzymał pochwałę

_________________
:)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 lip 2016, o 04:58 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Dziękuję bardzo za odpowiedź, teraz samą składnię rozumiem. Problem pojawił się z czym innym - otóż kompilator wyrzuca błąd, że nie wie co to ACK i NACK. Domyślam się, że są to definicje z pliku nagłówkowego "i2c.h" z postu, do którego się odniosłem w swojej wcześniejszej wypowiedzi, ale nie ma tam pokazanego tego pliku. Zakładam, że są to skrócone nazwy makr z pliku "twi.h". Zamieniłem je na: TW_MT_DATA_ACK : TW_MT_DATA_NACK, skompilowałem program i się uruchomił, temperaturę pokazuje prawidłowo. Czy to co zrobiłem jest poprawne? Chodzi mi o to, czy dobrze podmieniłem te makra.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 lip 2016, o 10:42 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 cze 2014
Posty: 76
Pomógł: 10

Pod ACK po prostu kryje się 1, a pod NACK 0. Możesz sobie zrobić na przykład tak:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Też będzie działać :D


Autor postu otrzymał pochwałę

_________________
:)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 lip 2016, o 16:50 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Ano widzisz :D Powiedz mi proszę - jak mogłem się tego dowiedzieć, że to 0 i 1 ?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 lip 2016, o 20:46 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 cze 2014
Posty: 76
Pomógł: 10

Cytuj:
I²C jest magistralą zorientowaną bajtowo, a więc bity grupowane są po 8[7]. Dane są wysyłane w kolejności od najbardziej znaczącego bitu do najmniej znaczącego[8]. Po przesłaniu 8 bitów w jednym kierunku, przesyłany jest dodatkowy bit potwierdzenia odebrania danych ACK (lub NACK w przypadku braku potwierdzenia) w kierunku przeciwnym[7].


Skoro ACK i NACK są wysyłane magistralą i2c, to albo są reprezentowane jako GND albo Vcc , czyli logicznie 0 lub 1 :D


Autor postu otrzymał pochwałę

_________________
:)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 lip 2016, o 21:07 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Aa, teraz rozumiem :) Zacząłem się zastanawiać nad inną rzeczą - na podstawie kodu z postu, do którego dałem linka wyżej, mam taki kod:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

'3' odpowiada zmiennej 'len'. Znaczy to, że będę miał wykonane 3 pomiary? I nie do końca rozumiem też tę linijkę:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Mam tutaj rozbicie 16-bitowego wyniku pomiaru na dwie 8-bitowe części?

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


PS: Dodam, że zajrzałem do tego, co jest w tablicy "test". I po wykonaniu funkcji "HTU21_read_temp(3, test)" mam takie liczby w tablicy:
test[0]: 107
test[1]: 172
test[2]: 206,
po czym "temp" ma wartość: temp = 27435. Szukam tutaj może jakiegoś dodawania bitowego, żeby skleić z tego zmienną "temp". Po prostu muszę wiedzieć jak to działa linijka po linijce bo inaczej będę chory :D

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

Mam przesunięcie bitowe 'test[0]' o 8 miejsc w lewo - czego nie za bardzo rozumiem, bo przecież wtedy z liczby 8-bitowej robią się same zera?
Mam przesunięcie bitowe 'test[1]' o 2 miejsca z prawo, co wydaje się mniej dziwne, bo nie tracę całej liczby.
Tak czy siak, nie rozumiem skąd się wzięła cała powyższa jedynka. Bardzo proszę o dalsze wskazówki :)

Biorę też dokumentację czujnika i czytam, co następuje:
Cytuj:
CONVERSION OF SIGNAL OUTPUTS
Default resolution is set to 12-bit relative humidity and 14-bit temperature readings. Measured data are
transferred in two byte packages, i.e. in frames of 8-bit length where the most significant bit (MSB) is transferred
first (left aligned). Each byte is followed by an acknowledge bit. The two status bits, the last bits of LSB, must be
set to ‘0’ before calculating physical values.


Rozumiem stąd, że dane pomiarowe idą w dwóch paczkach po 8 bitów, najbardziej znaczący bit jest wysyłany jako pierwszy i że mam dwa bity stanu, które muszę zrobić zerami, stąd przesunięcie o dwa w prawo? Ale pytanie dalej, po co bufor 3-elementowy? Chodzi o CRC?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 lip 2016, o 17:11 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 cze 2014
Posty: 76
Pomógł: 10

Witam!

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

Ta funkcja odczytuje z czujnika 3 bajty i zapisuje je do tablicy 'test'.


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

Pokażę to na przykładzie. Powiedzmy, że test[0] = 0b01111100 i test[1]=0b10000010
Gdy przesuniemy w lewo bajt test[0] o osiem miejsc dostaniemy 0b0111110000000000
Bajt test[1] ma w sobie dwa bity Statusu, musimy je wyrzucić, dlatego przesuwamy o 2 miejsca w prawo. Teraz mamy 0b00100000.

Po operacji OR 0b0111110000000000 i 0b00100000 otrzymamy 0b0111110000100000
[ 0 OR 0 -> 0 ]
[ 0 OR 1 -> 1 ]
[ 1 OR 0 -> 1 ]
[ 1 OR 1 -> 1 ]

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

zachodzi tylko na test[0]. Gdyby było tak jak mówisz:
Cytuj:
Mam przesunięcie bitowe 'test[0]' o 8 miejsc w lewo - czego nie za bardzo rozumiem, bo przecież wtedy z liczby 8-bitowej robią się same zera?

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


Gdy zajrzysz na 12 stronę PDF'a zobaczysz, że ostatni element tablicy to 'Checksum'
Dalej w nocie jest napisane:
Cytuj:
HTU21D(F) sensor provides a CRC-8 checksum for error detection. The polynomial used is X^8 + X^5 + X^4 +1


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

A ten zapis to rzutowanie zmiennych. Mówi prockowi, że chcesz, aby traktować zmienną temp jako 32bitową.

Jeśli gdzieś jest błąd, proszę o poprawienie, jesteśmy ludźmi, a ja też jestem początkujący :D
Pozdrawiam


Autor postu otrzymał pochwałę

_________________
:)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 lip 2016, o 19:35 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Cytuj:
Gdy przesuniemy w lewo bajt test[0] o osiem miejsc dostaniemy 0b0111110000000000
- a czy robiąc to nie traktujemy 'test[0]' jak liczby 16-bitowej? Chodzi mi o to, że wyczytałem wcześniej, że przesuwając bity w lewo, tracimy bit najbardziej znaczący, a w miejsce najmniej znaczącego wchodzi zero, stąd moja uwaga, że dostaniemy same zera. Tutaj przesuwając bity w lewo z liczby 8-bitowej zrobiliśmy 16-bitową i to jest dla mnie najbardziej zagadkowe :) Dlaczego tak się stało, skoro mam:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
, czyli traktuję to w dalszym ciągu jako zmienną 8-bitową? Przynajmniej tak rozumiem zapis :) Oczywiście jestem w stanie sobie wyobrazić, że zapis, np.:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
da w efekcie:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
, a nie:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
, co wydawałoby się poprawne względem tego, co wyczytałem wcześniej w Internecie.
Nie neguję oczywiście poprawności Twojej odpowiedzi, ja po prostu jeszcze nie rozumiem dlaczego raz potraktowałeś liczbę dodając jej kolejne bity, że zrobiła się z 8-bitowej 16-bitowa, a 'test[1]' zgubiła swoje dwa bity :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 lip 2016, o 20:36 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 cze 2014
Posty: 76
Pomógł: 10

Witam!

Popatrzmy na budowę na przykład liczby 10 = 0b1010
Każdemy bitowi przypisana jest jakaś waga.
2^3, 2^2, 2^1, 2^0, czyli 8,4,2,1.

Stosując wagi można 0b1010 rozpisać jako 1*8+0*4+1*2+0*1 = 10
Trzeba zauważyć, że waga 2^0 jest skrajna. Od niej zaczynamy nadawać wagi kolejnych miejsc. Nie można zrobić wagi 2^-1, bo taka nie istnieje. Dlatego przesuwanie bitowe w prawo wyrzuca bity poza bajt. Możesz zobaczyć, że 0b1010 można zapisać jako 0b00001010 i to da nasze 10, ale zapisanie zera po prawej stronie tj. 0b10100 zmienia całkowicie wartość liczbową, bo to 10 już nie jest.

Zauważ, że wyniki wszystkich operacji będą zapisane do zmiennej 2bajtowej tj. uint16_t , więc tak jak jest granica przed wagą 2^0 (bo nie ma wagi 2^-1 ), tak będzie granica po wadze 2^15.


Autor postu otrzymał pochwałę

_________________
:)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 lip 2016, o 20:48 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Ano widzisz - teraz wszystko jasne :)
Mam teraz inne pytanie - jak wiadomo, na I2C mogę podpiąć więcej niż jedno urządzenie. Muszę tylko w jakiś sposób rozróżnić jakoś te urządzenia wiszące na magistrali - pytanie: jak to zrobić mając np. 3 takie czujniki wiszące na jednej linii?
I jeszcze jedno: z tego, co widzę w dokumentacji mogę mieć rozdzielczość między 8-12 bitów dla wilgotności i 11-14 bitów dla temperatury, przy czym domyślnie mam 12 i 14 bitów. Pytanie: jak wybrać rozdzielczość pomiaru?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 lip 2016, o 20:58 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 cze 2014
Posty: 76
Pomógł: 10

Witaj!

Każde takie urządzenie podpięte do magistrali i2c ma swój adres (informacje na temat adresu są w nocie). Są urządzenia, których nie da się podpiąć w większej ilości do magistrali, z tego co pamiętam EEPROM 24c16 może być tylko jedna.
Z tego co widzę ten czujnik może być również tylko jeden. Co do ustawienia rozdzielczości zapoznaj się ze stroną 13 noty katalogowej.

_________________
:)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 lip 2016, o 21:05 
Offline
Użytkownik

Dołączył(a): 07 paź 2015
Posty: 79
Pomógł: 0

Mam jeszcze pytanie odnośnie CRC. Czytam:
Cytuj:
HTU21D(F) sensor provides a CRC-8 checksum for error detection. The polynomial used is X8 + X5 + X4 + 1.

Czym jest 'X'?
Odnośnie adresu - mówisz o tym: "I²C communication reading and writing the user register example" w tym schemacie, co oznaczają poszczególne bity na stronie 12?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 24 lip 2016, o 21:20 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 cze 2014
Posty: 76
Pomógł: 10

Witam!

Szczerze mówiąc nie wiem co oznacza ten wzór na CRC, ale posłużyć się można biblioteką na arduino, z której wyciągnąłem funkcję do sprawdzania CRC:
Składnia: [ Pobierz ] [ Ukryj ]
język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Co do adresu scalaczka:
Cytuj:
After sending the start condition, the subsequent I²C header consist of a 7-bit I²C device address 0x40
, ale ten adres musisz mieć już gdzieś zdefiniowany, skoro udało Ci się dokonać transmisji.


Autor postu otrzymał pochwałę

_________________
:)



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

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 5 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:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO