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 w 2025? 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 9 kwi 2025, o 06:00


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 
    Autor Wiadomość
    PostNapisane: 29 lip 2018, o 17:02 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 11 mar 2014
    Posty: 1475
    Pomógł: 167

    W wątku z opisem dotyczącym programu SQP-I2Cscan napisanym w C# pojawiły się głosy, by tą wersje programu także opisać, więc poznęcam się nad Wami i to zrobię :mrgreen:.

    Drugim programem, który powstał ramach Mirkowego konkursu (i dla Was na szczęście ostatnim, dzięki czemu więcej nie będę opisywał ;)) dotyczącego API dla ATB-USBasp 4.2 to program SQP-I2Cscan. Tak, tak, dla zmyłki to program o tej samej nazwie co wcześniej opisywana wersja z GUI https://forum.atnel.pl/topic21023.html, ale tym razem jest to wersja konsolowa, czyli bez GUI, napisana w C. Wykorzystuje on natywną bibliotekę libusb. Wymagane pliki są do pobrania ze strony https://sourceforge.net/projects/libusb/ (dołączone są też do archiwum projektu).

    Jest to prosty program, realizujący tylko jedną praktyczną funkcję - skanuje magistralę I2C wykorzystując ATB-USBasp 4.2 (plus jeden bonus, o którym na końcu opisu). Wynik skanowania I2C prezentowany jest tekstowo podając adresy znalezionych urządzeń w formacie dziesiętnym i szesnastkowym zarówno w konwencjach adresów 7-bitowego i 8-bitowego.

    Obrazek

    Dzięki temu, że biblioteka libusb dostępna jest zarówno dla Windows jak i Linux, aplikacja poprawnie kompilującej się, bez jakichkolwiek przeróbek, zarówno pod Windows jak i pod Linux.
    Oczywiście należy pamiętać aby w Makefile dodać odpowiednie podlinkowanie plików nagłówkowych oraz bibliotecznych libusb.

    Cały kod udostępniam na licencja GNU GPL v. 3.0, czyli dostępny jest kod źródłowy z pełnymi prawami do samodzielnej modyfikacji i rozpowszechniania.
    Kod programu znajduje się w wątku konkursowym https://forum.atnel.pl/topic20920.html#p209345. Jest on w tym samym archiwum co wersja w C# z GUI, ale w katalogu o nazwie SQP-I2Cscan (Console).
    Dla lubiących narzędzia do wersjonowania, to ostateczną wersję wrzuciłem też do publicznego repozytorium https://bitbucket.org/rskup/sqp-i2cscan/.

    Program pod Windows pisany był w darmowym przyjemnym i lekkim narzędziu Dev-C++, a w archiwum, dla chcących je szybko otworzyć, dorzucone są od razu pliki projektu z tego narzedzia (SQP-I2Cscan.dev).

    Po tym wstępie przejdźmy do szczegółów programu :)

    Projekt składa się z funkcji umieszczonych w trzech grupach plików:
    - main.c / main.h - funkcje związane z uruchamianiem / kończeniem programu, sprawdzaniem parametrów wejściowych i wywołaniem głównych funkcji programu
    - usbasp.c / usbasp.h - funkcje realizujące logikę działania programu związane z komunikacją z ATB-USBasp
    - usb.c / usb.h - funkcje odpowiadające za komunikację po USB (korzystające z biblioteki libusb)


    usbasp.c to główny trzon tego programu. Mamy w nim trzy podstawowe funkcje (o czwartej później ;) ):
    1. Pierwsza funkcja setI2CBitrate(), służy do ustawiania prędkości na szynie I2C. W której na początku wypełniamy odpowiednio dane w strukturze TusbControlPacket, która wygląda następująco:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Oczywiście przypisujemy do pól w strukturze TusbControlPacket wartości zgodnie z informacjami podanymi w dokumentacji dla API ATB-USBasp, a następnie wywołujemy funkcję wysłania danych poprzez funkcje usb:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    2. Druga funkcja checkI2CDevice() sprawdza obecność urządzenia na szynie I2C o wskazanym adresie. Także tutaj należy wypełnić strukturę TusbControlPacket zgodnie z API ATB-USBasp i wywołać funkcję usbSendControlData(). Przy sprawdzaniu obecności urządzenia dostajemy odpowiedź w formie tekstu OK lub ERROR, dlatego po wysłaniu danych sprawdzamy jeszcze co dostaliśmy w odpowiedzi i zgodnie z tym zwracamy przy kończeniu funkcji odpowiednią wartość (ERROR / SUCCESS / DEVICE_NO_FOUND):
    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.


    3. Trzecia funkcja scanI2C(), jest funkcją realizującą skanowanie na I2C urządzeń o kolejnych adresach (korzystając z wcześniej opisanej funkcji checkI2CDevice()). Skanowanie wykonywane jest to w pętli dla kolejnych adresów od adresu początkowego I2C_7BIT_ADDRESS_MIN do adresu I2C_7BIT_ADDRESS_MAX (obie wartości zdefiniowane są w pliku usbasp.h).
    We wszystkich bibliotekach i poradnikach Mirka, także w API ATB-USBasp stosowany jest adres w notacji 8 bitowej (wartość łącznie z bitem R/W na najmłodszej pozycji), dlatego przy skanowaniu nie wysyłamy kolejnych wartości, tylko z przeskokiem co dwa.
    Ale ja, na przekór :twisted:, lubię stosować notację 7-bitową, i taką używam w programie. Dlatego wartości zakresów adresów do skanowania zdefiniowane w stałych są 7 bitowe (I2C_7BIT_ADDRESS_MIN / I2C_7BIT_ADDRESS_MAX) a wartość wysyłana poprzez API jest przesunięta o jeden bit w lewo:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Zgodnie ze specyfikacją I2C, nie wszystkie adresy przeznaczone są dla normalnych urządzeń. Dlatego nie skanujemy całego zakresu a tylko jego część. Początek i koniec jest zdefiniowany we wspominanych wcześniej stałych I2C_7BIT_ADDRESS_MIN (najmniejszy adres) oraz I2C_7BIT_ADDRESS_MAX (największy adres).
    Gdy wywoływana funkcja checkI2CDevice() zwróci nam SUCCESS, co jest wynikiem odpowiedzi OK przez API ATB-USBasp, oznacza to że zostało wykryte urządzenie o tym adresie. Wypisujemy wtedy na ekranie informacje o tym adresie w postaci szesnastkowej oraz dziesiętnej zarówno w notacji 7-bitowej jak i 8-bitowej.
    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 pliku usb.c mamy funkcje związane z komunikacją po USB. A dokładnie to są to tylko 3 funkcje:
    1. otwarcie urządzenia funkcją openUSB(), gdzie następuje otwarcie urządzenia korzystając z wartości VID i PID zdefiniowanych dla USBasp:
    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.


    2. wysłanie danych kanałem kontrolnym usbSendControlData(), gdzie następuje fizyczne wysłanie danych poprzez wywołanie funkcji libusb_control_transfer() z biblioteki libusb z odpowiednimi otrzymanymi jako argumenty danymi:
    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.

    3. fukncji której nie mogło zabraknąć, czyli zamknięcie naszego urządzenia:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



    Ostatnim plikiem z kodem programu jest plik main.c. Funkcja main() zasadniczo (bo o pewnych dodatkach za chwilę) ma proste działanie:
    - wykonać otwarcie urządzenia ATB-USBasp, używając wcześniej wspominanej funkcji openUSB()
    - sprawdzić czy podany został parametr przy wywołaniu a jak tak i jest prawidłową wartością, to ustawić zgodnie z nim prędkość na szynie I2C, korzystając z wcześniej opisanej funkcji setI2CBitrate()
    - wywołać skanowanie szyny I2C poprzez także wcześniej opisywaną funkcję scanI2C()
    - zamknąć połączenie z urządzeniem USB poprzez funkcję closeUSB()

    I to cała logika skanowania I2C :D. Prawda, że proste?

    To teraz jeszcze napiszę o dwóch elementach znajdujących się w kodzie, która mogą przeglądającym lekko go zaciemniać:

    1. Jako, że program ma działać poprawnie po skompilowaniu zarówno pod Windows jak i Linux, zostały dodane pewne elementy wymagane w systemie Linux.
    W Windows naciśnięcie CTRL-C zabija automatycznie program. W Linux zdefiniowane są sygnały jakie wysyłane są do programu. Dlatego dodane zostało przechwytywanie sygnału SIGINT i SIGTERM
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Otrzymanie tych sygnałów powoduje, oprócz wypisania komunikatów, ustawienie zmiennej globalnej receivedTermSignal. Zmienna ta jest sprawdzana w pętali skanowania i jej ustawienie powoduje przerwanie skanowania.
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



    2. Drugim elementem jest dodatek w kodzie zmieniający całkowicie jego działanie. Jest to część, która wcześniej została specjalnie ominięta w opisie zawartych w plikach funkcji.
    Jeżeli przeglądaliście kod to w funkcji main() zauważyliście, że wywołanie sprawdzanie parametru wejściowego i skanowanie I2C zawarte jest w dyrektywie:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    To właśnie ten dodatek, który możemy włączyć poprzez zdefiniowanie wartości TOGGLE_I2C_PINS powoduje wyłączenie skanowania a włączenie w czasie kompilacji wywołania funkcji toggleI2CPins():
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


    Co więc robi ta funkcja?
    Zamiast programu skanującego szynę I2C dostajemy program zmieniającymi cyklicznie wartości na wyjściach dedykowanych dla I2C: SDA i SCL - po podłączeniu diod mamy cykliczne ich miganie.
    Funkcja na początku przełącza tryb ATB-USBasp w tzw. tryb bit bang a potem w pętli ustawia i kasuje odpowiednio wyjścia SDA i SCL aż do momentu przerwania tego przez nas (klawiszem CTRL-C):
    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.


    Aby wywołać kompilację programu w wersji SQP-TogglePins musimy zdefiniować wartość TOGGLE_I2C_PINS, co możemy zrobić na jeden z trzech sposobów:
    - w kodzie poprzez dodanie #define TOGGLE_I2C_PINS
    - w pliku Makefile poprzez dodanie -DTOGGLE_I2C_PINS
    - odpowiednio w środowisku w zmiennych kompilacji, dla Dev-C++ wygląda to tak:
    Obrazek

    Dzięki parametrowi -D w Makefile możemy zrobić kompilację od razu obu wersji programu, jak to się dzieje przy użyciu załączonego Makefile.

    I to byłoby na tyle. Jak macie pytania i niejasności, to piszcie. Jak nie, to także piszcie, ale swoje kody i testujcie działanie ATB-USBasp >= 4.2 :).

    --
    Pozdrawiam,
    Robert



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 29 lip 2018, o 17:04 
    Offline
    Moderator
    Avatar użytkownika

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

    Panie - panie! takie "kwiatki" to się wrzuca do DIY ;) bo to fajna inspiracja dla innych

    _________________
    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: 29 lip 2018, o 17:05 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 11 mar 2014
    Posty: 1475
    Pomógł: 167

    mirekk36 napisał(a):
    Panie - panie! takie "kwiatki" to się wrzuca do DIY ;) bo to fajna inspiracja dla innych
    Jakie DIY, to tylko seria odpowiednio ułożonych bitów ;).

    --
    Pozdrawiam,
    Robert



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 29 lip 2018, o 21:01 
    Offline
    Użytkownik

    Dołączył(a): 25 lip 2013
    Posty: 2595
    Pomógł: 128

    Świetna robota Robert! Dziękuję!



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 30 lip 2018, o 11:22 
    Offline
    Użytkownik
    Avatar użytkownika

    Dołączył(a): 11 mar 2014
    Posty: 1475
    Pomógł: 167

    kalani napisał(a):
    Do kompletu brakuje tylko skanowania General Call.
    Tylko zwrócona przez to informacja nic nie wnosi w kwestii rozpoznawania urządzeń. A i tak skanujemy wszystkie adresy, więc dowiemy się czy są urządzenia i w dodatku jakie :).
    Ale jak kto chce, to co za problem dodać jako osobną funkcję lub przed pętlą skanująca adresy? :D

    --
    Pozdrawiam,
    Robert



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

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