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



Teraz jest 28 mar 2024, o 11:56


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 15 ] 
Autor Wiadomość
PostNapisane: 28 cze 2014, o 03:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 27 maja 2013
Posty: 562
Lokalizacja: Bydgoszcz
Pomógł: 23

W ramach nauki by wyjść jakby poza przykłady z BB i Grenn booków, zaczynam eksperymentować z rzeczami bliżej mi nie znanymi :)

W sumie jakby na 1 ogień poszedł taki czujnik natężenia światła BH1750, który sobie nabyłem z stąd:
http://botland.com.pl/czujniki-swiatla-i-koloru/2024-czujnik-natezenia-swiatla-bh1750.html
dokładnie ten model jako moduł na gotowej PCB:
Obrazek

link do noty układu (dodaje także jako załącznik do posta): http://www.elechouse.com/elechouse/images/product/Digital%20light%20Sensor/bh1750fvi-e.pdf

Wiadomo można sobie z powodzeniem takowy czujnik zrobić za pomocą fotorezystora i pomiaru ADC ale mi chodzi raczej o ćwiczenia z czymś nowym w komunikacji I2C.
Po małych perypetiach związanych z nawiązaniem komunikacji z w/w czujnikiem, a raczej jego błędnym adresowaniu, które pomógł mi rozwiązać kolega Rezasurmar za co mu serdecznie dziękuję, zrobiłem taki oto program do jego testowania:

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


Mam nadzieje że program jest czytelny więc nie będę go dodatkowo opisywać. Napisałem go i testowałem na ATB z Atmega32 oraz zegarem 11059200 Mhz. Do komunikacji z czujnikiem przez I2C oraz wyświetlania pomiaru na LCD wykorzystałem biblioteki Mirka z niebieskiej książki.

Dopowiem tylko że przy podłączaniu czujnika proszę zwrócić uwagę na to że pomimo, iż na module widnieją rezystory 4,7K to i tak należy linie SDA i SCL podciągnąć rezystorem 4,7K do VCC. Mi wydawało się że moduł już to po prostu ma, jednakże należy go potraktować jak by był scalakiem i takowe rezystory podciągające wstawić bo inaczej po prostu nie działa.

W programie brakuje przeliczania danych pomiaru na wartość Lux. Jak wyczytacie z noty albo po analizie programu wynik pomiaru zapisuje się w dwóch bajtach H i L. Ja sobie je wyświetlam jeden obok drugiego odczytując wartości z tablicy. Myślę że by jednak wypadało zrobić działanie matematyczne, które by takowy wynik przeliczało na wartości lux. Ja jednakże nie mam pomysłu na razie jak i liczę na to że, ktoś może coś doradzi albo podpowie. :)


Załączniki:

Aby zobaczyć załączniki musisz się zalogować. Tylko zalogowani użytkownicy mogą oglądać i pobierać załączniki.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 cze 2014, o 04:24 
Offline
Moderator
Avatar użytkownika

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

To się nadaje do działu DIY - projekty programistyczne ...

Intre napisał(a):
Mam nadzieje że program jest czytelny więc nie będę go dodatkowo opisywać.


aż serce rośnie jak się widzi TAK napisane kody źródłowe ... ten kod wręcz tłumaczy się sam ;) ... w ogóle fajny arcik. Gratki Intre - miło się czyta ...

_________________
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: 28 cze 2014, o 08:47 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 08 mar 2013
Posty: 236
Lokalizacja: Warszawa
Pomógł: 5

Fajny projekt.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 cze 2014, o 09:12 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 27 maja 2013
Posty: 562
Lokalizacja: Bydgoszcz
Pomógł: 23

:shock: wow, miłe to co piszecie :) ale żeby to trafiło do działu DIY to myślę że trzeba by jeszcze rozwiązać tą kwestie przeliczania wyniku na Luxy

W nocie jest napisane coś takiego:

Cytuj:
How to calculate when the data High Byte is "10000011" and Low Byte is "10010000"
( 2 15 + 2 9 + 2 8 + 2 7 + 2 4 ) / 1.2 ≒ 28067 [ lx ]
(to są potęgi przy tych liczbach nota str.7 do spojrzenia.)

Biblioteka od Arduino do tego czujnika z tego co z niej zrozumiałem za pomocą przesunięć bitowych wpisuje wartości do 1 liczby uint16_t a następnie dzieli przez 1,2 zgodnie więc z powyższym wzorem. No ale wiadomo działania za pomocą liczb z przecinkiem to nie bardzo w AVR. Więc trzeba by zrobić jakby jakąś metodę matematyczną przeliczania tego wyniku by uniknąć liczby zmiennoprzecinkowej. Ktoś ma jakieś pomysły? :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 cze 2014, o 09:14 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 17 sie 2013
Posty: 3797
Lokalizacja: Grudziądz
Pomógł: 143

Tez sie glowilem nad zakupem tego ukladu. Ostatecznie w lapki wpadl mi malutki fotorezystor i czytam go po ADC lecz patrzac na twoj kodzik to jest czytelny i widze ze nie ma wiekszego problemu by sie z ukladem skomunikowac.

_________________
Usługi druku przestrzennego - www.drumik.pl



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 cze 2014, o 22:50 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 27 maja 2013
Posty: 562
Lokalizacja: Bydgoszcz
Pomógł: 23

Dambo dzięki za wskazówkę czy twoim zdaniem taki zapis jest prawidłowy? :

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


No przeliczają się wartości ale nie jestem do końca pewien czy jest to dobrze. W sumie się zastanawiam jak można sprawdzić te wskazania takim domowym sposobem o ile jest to możliwe nie mając dedykowanego urządzenia fabrycznego.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 cze 2014, o 11:29 
Offline
Użytkownik

Dołączył(a): 14 paź 2012
Posty: 43
Lokalizacja: Szczecin
Pomógł: 0

Witam!

A czy czasem w 3 linijce nie powinien być znak | zamiast +



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 cze 2014, o 13:08 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 27 maja 2013
Posty: 562
Lokalizacja: Bydgoszcz
Pomógł: 23

No dobra zrobiłem wg. noty i tak jak coś czułem jest nie tak :)

Więc tak dane z noty:
Cytuj:
High Byte is "10000011" and Low Byte is "10010000"


Powinno wyjść: 28067

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 coś nie tak bo wyświetla się -4702 I skąd ten "-" skoro to jest u_int? ;)
Zrobiłem też wersje bez przesunięcia bitowego z + i z |. Przesunięcia o <<4 itp. zabiegi. :) Jakieś pomysły?
To działanie w sumie możecie zrobić bez czujnika u siebie.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 cze 2014, o 13:37 
Offline
Użytkownik

Dołączył(a): 14 paź 2012
Posty: 43
Lokalizacja: Szczecin
Pomógł: 0

Nie mam teraz jak sprawdzić, ale wydaje mi się, że funkcja lcd_int nie wyświetla uint_32



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 17 sie 2014, o 20:59 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 10 sty 2014
Posty: 446
Lokalizacja: DKL
Pomógł: 53

O proszę, trochę odkopię temat bo sam ostatnio się bawiłem tym sensorkiem, zagłębiając nabytą wiedzę w C dla AVR-ków. Swoją przygodę z tym czujnikiem zacząłem dość przypadkowo, ale nie widziałem wcześniej tego tematu więc zacząłem pisać testowy program na podstawie datasheet-u ;)

Teraz gdy trafiłem tu na ten post kolegi @Intre, to znalazłem wiele podobieństw jakie stworzyłem w stosunku do kodu tu zaprezentowanego. Nie mniej jednak kilka moich spostrzeżeń i sugestii napiszę, bo może rozwieją one wszelkie wątpliwości i będą komuś pomocne.

I tak, faktycznie jak słusznie zauważył kolega @jkarczew, jeśli korzystamy z funkcji lcd_int(),to faktycznie mogą się "minusy" pojawić, bo dla tej funkcji my mamy liczbę 16-bitową ze znakiem czyli operujemy za zakresie -32768 - 32767, a w rejestrze tegoż układu dane są w zakresie int bez znaku czyli 0 - 65535. Ja się identycznie jak ty @Intre natknąłem na "minusy" bo w UART'cie wyświetlić chciałem dane, za pomocą funkcji z BB uart_putint(). Wystarczyło użycie funkcji dla long i nie ma już z tym problemu.

Kolejna sprawa, to zauważyłem że jak liczysz wartość lux_light, to wystarczy ci typ uint16_t do tego celu, pozostałe działania robisz poprawnie, mam na myśli "sklejenie" dwóch bajtów: lux_light = (light_buf[0]<<8) + light_buf[1];. Pozostałe przeliczenia które tu podałeś na wartość LUX są także zgodne z tym co podano w nocie. Tu dodam, że jeśli nie potrzebujesz tej wartości LUX gdzieś wyświetlić lub zapisać, to nie ma sensu robić tych przeliczeń, do sterowania np. natężeniem świecenia LED'ów wystarczy jak porównasz lub porobisz sobie przedziały "surowych" wartości z rejestrów układu.

Teraz jeszcze jedno, bo nie mam pewności, ale w DS tego sensora, jeśli dobrze zrozumiałem, to nie potrzeba na samym starcie wydawać polecenia BH1750_POWER_ON, gdyż ten robi to automatycznie po wydaniu któregokolwiek rozkazu pomiaru, także w przypadku tego modułu funkcja BH1750_init(); jest wg. mnie zbędna. W każdym razie mi działa pomiar bez żadnej inicjalizacji. Oczywiście niczemu ona też nie szkodzi (tak mi się wydaje), także zasadność jej używania uznaję jako kwestię dowolną :)

Ostatnia już sprawa, to czas oczekiwania na wykonanie pomiaru po wydaniu rozkazu. Może on być w zależności od wybranego trybu i rozdzielczości w przedziale od 16-120ms. U Ciebie @Intre nie widzę takiego opóźnienia, czego nie uważam oczywiście za błąd, bo masz przecież to zrealizowane poprzez cykliczne odczyty w timerze programowym, ale zwracam na to uwagę, że pierwszy twój pomiar po podaniu zasilania do układu zwróci 0, a kolejny pomiar da rezultat z poprzedniego rozkazu pomiarowego, także niejako masz rezultat z poprzedniego cyklu pomiaru. Ja u siebie użyłem paskudnego _delay_ms(120) w procedurze BH1750_read(); i oczywiście zamierzam to w docelowych projektach oprzeć także o timer programowy, tak aby nie wprowadzać sobie żadnych dodatkowych opóźnień blokujących.

Mam nadzieję, że moje skromne uwagi do czegoś się przydadzą, a w razie pytań lub wątpliwości chętnie odpowiem w oparciu o swoją wiedzę i nabyte w tym zakresie doświadczenie.

_________________
Migracja z punktu B do punktu C
Pozdrawiam



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 paź 2019, o 11:53 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 28 kwi 2015
Posty: 20
Lokalizacja: Bydgoszcz
Pomógł: 0

Chcę wykorzystać czujnik BH1750. Ten wątek choć już bardzo stary bardzo mi w tym pomógł. Kod po małej modyfikacji sprawdził się wspaniale, działa bez problemu, jednak nie daje mi spokoju sprawa z adersem do tego czujnika.
W nocie adres jest 0x23, natomiast w kodzie Intre jest taka linijka:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Dlaczego należy pomnożyć adres przez 2?
PS
Znalazłem w internecie, w innym kodzie dotyczącym tego czujnika operację bitową na adresie (addr<<1).



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 paź 2019, o 12:22 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 15 lut 2017
Posty: 369
Lokalizacja: Gliwice
Pomógł: 34

karlowic napisał(a):
Dlaczego należy pomnożyć adres przez 2?

Poczytaj o 7-bitowym adresie w komunikacji I2C - tak najczęściej jest przedstawiany adres w dokumentacji scalaków I2C.
Pomnożenie przez 2 to inaczej przesunięcie bitowe w lewo, o 1. Najmniej znaczący bit takiego bajtu determinuje o odczycie lub zapisie do urządzenia slave.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 paź 2019, o 08:19 
Offline
Nowy
Avatar użytkownika

Dołączył(a): 28 kwi 2015
Posty: 20
Lokalizacja: Bydgoszcz
Pomógł: 0

Przesunięcie bitowe o 1 w lewo jest bardziej bliskie prawdy niż pomnożenie x2. Teraz nawet ja wiem o co chodzi. :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 30 paź 2019, o 09:25 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2561
Pomógł: 126

Nie jest bliższe prawdy - jest tożsame.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 1 maja 2020, o 18:49 
Offline
Nowy

Dołączył(a): 24 kwi 2020
Posty: 1
Pomógł: 0

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

Przy ustawieniu 0x2n (n=0 lub 1 lub 3) odczyt miałem tylko 1 raz - potem czujnik przechodzi w tryb uśpienia i nawet ponowne wywołanie Power On i Reset nie dawały efektu.
Pomogło przestawienie na 0x1n, czyli pracę w trybie odczytu ciągłego.

Pozdrawiam!



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

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 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