♬ ☘ Moja muzyka do kodowania ♬ ♬ ♬ ☘
♫ ♩ ♪ Find Me ⚡ ☘ ⚡ Wings Of Love ♪ ♩ ♫
https://youtu.be/uq8wRyNV9NA
pięćdziesiąt twarzy Greya
Z lektury wzmiankowanej książki podstawowy wiosek dla mnie taki, że monotonia czy wręcz nuda to znani wrogowie udanej zabawy.
W końcu jak długo i na ile sposobów można wiązać się kablem?
A skoro tematyka przewodowego Ethernetu została już poruszona na forum, więc w ramach urozmaicenia opisywany dalej interfejs SCPI do Meratronika V543 bazuje na rozwiązaniu bezprzewodowym. Podstawą jego jest komputerek Raspberry PI Zero w wersji z WiFi. Wybór platformy był dość prosty: o układzie ESP8266 napisano w majowej EdW, więc napoczętego przez kogoś tematu nie będę już drążyć. Do wszelkich shieldów z WiFi dedykowanych Arduino podchodzę póki co ze sporą rezerwą, ten wariant zatem także odpada. I tak pozostaje relatywnie tanie i posiadające ogromne wsparcie społecznościowe Raspberry PI, do zastosowań ‘pod zabudowę’ wersja Zero z WiFI jest wręcz idealna. Niewielka gabarytowo, posłuszna, wdzięczna w oprogramowaniu i za jedyne pięć dyszek.
niepozorna Malinka
W formie garstki linków wskazania na opisy co i jak skonfigurować, a ogarnięcie świeżego sklepowego modułku i przygotowanie go do dalszych prac zajmie raptem jeden wieczór. Na kolejnych etapach pracy korzystałam z tych materiałów z sieci:
https://www.raspberrypi.org/documentati ... s/linux.md
https://techfreak.pl/raspberry-pi-zero- ... acja-wifi/
http://www.science.smith.edu/dftwiki/in ... spberry_Pi
http://www.science.smith.edu/dftwiki/in ... spberry_Pi
http://pi4j.com/pins/model-zero-rev1.html
https://cdn.sparkfun.com/assets/learn_t ... Zero_1.pdf
Jeżeli póki co nie chcemy nic lutować do złącz Maliny, a nie posiadamy na podorędziu kabelka USB OTG i Mini HDMI to aby dostać się do konsoli systemu pozostaje nam opisywana w linkach powyżej partyzantka z przekładaniem karty do czytnika w komputerze i edytowaniem plików na karcie.
Gdy ktoś pracuje na co dzień z Linux to wszelkie narzędzia ma pod ręką niejako z pudełka i sprawa nie jest skomplikowana. Istnieje też inna alternatywna ścieżka - wstępne skonfigurowanie świeżego systemu na dużej Raspberry PI, przy użyciu klawiatury i monitora czy nawet telewizora, potem kartę można przełożyć do Zero.
Ja poszłam tą właśnie drogą, ssh i wifi ustawiłam sobie wygodnie na większej siostrze, operacje typu `expand filesystem` i wgranie świeżych paczek systemowych, git i reszta – już w natywnym środowisku sprzętowym PI Zero.
I jeszcze jedno - w trakcie rozkładania obrazu systemu na karcie przy pomocy polecenia `dd` tak naprawdę nie wiadomo co się dzieje. Programik dd nie należy do specjalnie wylewnych, a sam proces wgrywania zajmuje dłuższą chwilę. Warto wtenczas otworzyć sobie na boczku drugi terminal, wykonać `top` albo `ps –A` aby pozyskać identyfikator procesu dd, a potem wysyłać mu sygnał USR1, o na przykład tak:
W ten sposób zagadnięte dd wyświetli na niemej dotychczas konsoli informacje ile aktualnie już pracy wykonał, a przede wszystkim – jak nam odpowie, to znaczy że nic tam nie zawisło. U mnie akurat to było pomocne, bo wiekowy nieco czytnik renomowanej firmy Tesco ma problem ze stykiem do wykrywania karty SD i czasem w trakcie dłużej trwających operacji potrafi wyciąć psikusa. Na koniec cieszymy się maleńką diodką na PI Zero, której filuterne pomrugiwanie oznacza ładowanie Linuksa, inicjację systemu i jest zaproszeniem do dalszej zabawy.
użytkowanie wieczyste
W moich realiach Malina ma nadany stały adres IP, trwałą dzierżawę IP zapewnia odpowiedni konfiguracja serwera DHCP wbudowanego w domowy router i rozpoznająca Malinkę po adresie MAC. Tak samo rozpoznawany jest Rigol-Cukierek. Drobna edycja pliku /etc/hosts zapewnia widoczność modułku po nazwie, nie ma sensu dla takiego drobiazgu bawić się w lokalny DNS.
Mając dostęp do systemu przez ssh jesteśmy praktycznie w domu i dalsze prace będą koncentrowały się tylko i włącznie na sprawach związanych z interfejsem do Meratronika. Dobrze jest doinstalować sobie pakiet proftpd wtedy dowolnym , ulubionym klientem ftp możemy komfortowo nawigować po systemie plików Maliny, a także edytować zdalne pliki tekstowe jeżeli nasz ulubiony edytor to potrafi (na przykład Kate z KDE). Drugi przydaś to git, ja programik pisałam bezpośrednio na Malinie, a odrobina pecha przy wyłączaniu zasilacza i pstryk - po filesystemie. Tak więc git add/commit/push pozwalały zachować spokój ducha, ponieważ prace były bezpieczne, poza Maliną.
wąż kusiciel kontra C
Przyznam, dłuższą chwilę zastanawiałam się w czym popełnić oprogramowanie komunikacyjno-sterujące, a możliwości jest całkiem sporo. W domyślnej instalacji Linuksa na PI mamy język C/C++ (gcc v.6.3), można łatwo doinstalować Free Pascal, jest też Python, choć co odrobinę zaskakujące w wersji 2.7. I ten Python mnie kusił straszliwie, och jak mocno. Tym bardziej, że miałabym wsparcie u autora tej oto cudnej zabawki https://www.sbprojects.ga/projects/pi-epsim/ , tam emulatorem pamięci steruje właśnie PI Zero i program w Pythonie. Robiąc bliźniaczy projekcik miałabym relatywnie łatwiej niż walcząc z tematem od zera. Tylko że zadziałała zasada `czym skorupka i tak dalej` i oko me zawisło na kultowej jak dla mnie książce `Programowanie zastosowań sieciowych w systemie Unix`, która praktycznie w całości bazuje na języku C. No i dylemat się rozwiązał.
Nie zmienia to faktu, że połączenie Python/GPIO i tak muszę rozpoznać detalicznie, do pisania przydasiów na kolanie wydaje się być bardzo efektywne vide wzmiankowany emulator Sana, który mi ciągle nie daje spokoju.
zapoznanie z GPIO
Dostęp do GPIO Maliny wcale nie jest skomplikowany, a jeżeli ktoś wcześniej bawił się w Arduino to już w ogóle w temat wejdzie bezboleśnie. Kluczową sprawą jest pobranie sobie na Malinkę pakietu WiringPI http://wiringpi.com/ i skompilowanie bibliotek. Do wywołania kompilatora/linkera dodajemy -lwiringPi , aplikacje linkują się bez problemu. Interfejsik mój prosty, to i funkcji bibliotecznych jeno garstka w użyciu, oto one:
* pinMode ( pin, kierunek ) - konfiguracja wej/wyj
* digitalWrite( pin, stan ) - zapis
* digitalRead( pin ) - odczyt
potem pojawiła się jeszcze funkcja instalująca handler przerwania dla danego pinu IO czyli:
* wiringPiISR( pin, rodzaj_pobudzenia, adres_handlera )
Prosty programik, który nabazgrałam w międzyczasie generował falę prostokątną na pinie 0, cały kod sprowadza się raptem do poniższych linijek:
Kod: Zaznacz cały
pinMode ( 0, OUTPUT );
while ( 1 ) {
digitalWrite( 0, HIGH );
digitalWrite( 0, LOW );
}
Jak widać dostęp do GPIO jest intuicyjny, a programowo można generować całkiem szybkie przebiegi.
logika na poziomie
Fakt to ogólnie znany, że malinowe GPIO pracuje z poziomami logicznymi charakterystycznymi dla logiki 3.3V i nie jest ‘five volts tolerant’. Dla odmiany logika mojego neonowego Meratronika to klasyczny TTL, interfejs z układami 74LS165 takoż. Niezbędna jest zatem konwersja 5<->3v3 dla linii interfejsu, a ową wykonałam przy pomocy łatwego do kupienia modułku do zmiany poziomów.
https://botland.com.pl/konwertery-napie ... ololu.html
W tym przypadku modułek-konwerter został spreparowany do pracy z kątowymi złączami igłowymi i kabelkami, tak było mi najłatwiej i w sumie najelastyczniej – w końcu to jeden wielki eksperyment i zmiany są na porządku dziennym. Robiąc docelowe rozwiązanie taki modułek najlepiej umieścić w podstawce DIL lub wręcz wlutować w płytkę.
kanapka z Maliną
Zacznę od tego, że schemat przyłączenia interfejsu do PI Zero wygląda jak poniżej:
Konwerterek, który posiadam ma cztery kanały, pokrywa nadawane prze PI sygnały /LINE_LOAD, LINE_CLK jak i odczytywane LINE_DATA oraz LINE_READY. Świadomie zrezygnowałam z obsługi LINE_START, niech mierniczek spokojnie pracuje sobie we własnym rytmie, impulsy na LINE_READY zauważane przez Malinę w postaci przerwań zapewnią odczyt nowych wartości w stosownym momencie i nic nie zostanie przegapione.
Kolejna rzecz to sygnalizacja pracy interfejsu. Oczywiście jak zobaczymy PI w naszej sieci lokalnej to już jest nieźle, a jak zalogujemy się do niej via ssh to rewelacja. Ale w trakcie normalnego użytkowania chyba warto wiedzieć czy w ogóle programik komunikacyjny ruszył, czy odczytuje miernik i czy jest komunikacja z PC na poziomie komend SCPI. Do tego celu służą widoczne na schemacie dwie diody świecące, podparte tranzystorami i zapięte go pinów 4 i 5. Ich miganie oznacza kolejne cykle odświeżenia danych przez miernik oraz kolejne obsługiwane polecenia SCPI. Nieustanna błyskoteka na tyle miernika oznacza zatem, że całość pracuje w miarę poprawnie.
Dalej garść zdjęć z kolejnych etapów melanżu Maliny z podrutowanym interfejsem do V543.
Wstępne przymiarki grzebyczka gold-pin
Okazało się, że otworki z Malinie są zbyt małe i aby przewlec śrubki M3 muszę je nieco poszerzyć, zatem pilnik-iglak w dłoń. Miałam stres wtedy, taka drobniutka lutowanka na płytce i ostre narzędzie.
Po kilku przymiarkach Malina zawisła na słupkach dystansowych na płytce interfejsu, tak na kanapkę. Orientacja PI jest taka, aby złącze zasilające mikro USB było w dół, to w moich realiach skutecznie zminimalizuje ryzyko wygięcia lub odłamania złącza z płytki PI.
Obowiązkowy LED od zasilania. Może i zabawne, ale komórkowa ładowarka z której zasilane jest PI nie ma sygnalizacji, a sami ledzik na PI maleńki i przysłonięty drutami, lampka na boku w tym przypadku akurat jest dla mnie zasadna
Diody sygnalizujące cykle odczytu V543 oraz komunikację SCPI są zamontowane na brzegu, widać je w miarę dobrze choć i tak trzeba zapuścić żurawia na tył urządzenia.
Test diodek na sucho:
https://youtu.be/IccJuTZlHwI
I podczas normalnej pracy interfejsu - prawa to odczyty, lewa - polecenia SCPI z terminala
https://youtu.be/4n_aE9SOfYo
A tu dygresja nie na temat – w pudełku taki oto ledzik z czasów PRL znalazłam, prostokątny, czerwony, CEMI bodajże. Ale mi się go szkoda zrobiło, bo nielutowany nigdy i wrócił do siebie.
Konwerter 5-3v3 został zawieszony na króciutkich specjalnie ku temu spreparowanych kabelkach połączeniowych. Całość jest w miarę bezboleśnie rozbieralna gdyby zaszła jakaś potrzeba poprawek czy przeróbek, a jednocześnie dość pakowna, a pomimo konstrukcji natury powietrznej nic nie dynda ani się nie majta.
Zrobienie zdjęć zadeczka Meratronika z zamontowanym interfejsem wymaga odrobiny akrobatyki ewentualnie wykorzystania lusterka, całość prezentuje się następująco i to jest stan na chwilę obecną docelowy.
gwara meratronikowa
Kod programiku v543.c dostępny jest w lokalizacji https://github.com/bienata/piv543scpi/b ... ter/v543.c i proszę o wyrozumiałość, to wersja `na kolanie` i jeszcze rozwojowa.
O detalach implementacyjnych oprogramowania nie będę się tu zbytnio rozwodzić, informacje o programowaniu gniazdek oraz przykłady sieciowych aplikacji klient-serwer można znaleźć w literaturze, choćby w doskonałej pozycji, którą wskazałam na początku tego tekstu. Jeżeli zapoznamy się jakoś ze standardowymi funkcjami socket(), bind(), listen() i accept() to w zasadzie możemy już w sieci zrobić cokolwiek tylko przyjdzie nam do głowy.
Chcę za to poruszyć teraz temat samego definiowania zestawu poleceń SCPI dla multimetru V543, czy jakiegokolwiek innego `customowego` sprzętu, bo tu nie ukrywam miałam pewien problem.
Pierwsza moja myśl była taka, aby pasujące do urządzenia komendy zapożyczyć sobie z jakiegoś sprzętu, który ma SCPI zaimplementowane, na przykład `DM3000 Digital Multimeter` https://dokumente.unibw.de/pub/bscw.cgi ... uelle5.pdf I w zasadzie byłoby super gdyby nie to, że V543 ma jednak w porównaniu z rzeczonym multimetrem dość ubogie możliwości, zbiór poleceń należałoby ograniczyć, a takie znowu przerzedzenie spowodowało utratę spójności składni i generalnie wyglądało dziwnie. Przejrzenie dokumentacji do kolejnego miernika, tym razem `Fluke 8845` http://assets.fluke.com/manuals/8845a___pmeng0200.pdf dało efekt podobny. Nie potrafiłam jakoś wyłuskać sensownego podzbioru poleceń, zawsze wychodziło jakieś pokraczne dziwadło.
Pozostało zatem spreparowanie własnej autorskiej wersji dialektu SCPI, dedykowanej dokładnie mojemu mierniczkowi V543. I tu kłopot polega na tym, że trzeba zdecydować w jakiej części obróbka danych ma być po stronie miernika, a w jakiej po stronie aplikacji klienckiej, która z tych danych skorzysta.
Przykład wariantowości sytuacji:
* możemy odesłać surową binarną ramkę, która odzwierciedla stan wyświetlacza, bity zakresu, polaryzacji i tryby pracy – dana w postaci unsigned long.
* możemy też na poziomie interfejsu ładnie spreparować wynik pomiaru i odesłać na przykład wartość napięcia w mV i minusem gdy ujemne w formie napisu ASCII.
I tu powstaje pytanie – jak będzie używany interfejs SCPI? Czy może systemowo? I z miernikiem będzie komunikować się inne urządzenie lub aplikacja? A może jednak na żywca z konsoli lub prostymi skryptami będzie te polecenia wydawał człowiek, czyli dalsze przetwarzanie będzie na poziomie białkowym? Tego nie wiadomo przecież, definiując składnię trzeba wypracować coś po środku. SCPI jest (w mojej opinii) interfejsem typu maszyna-maszyna a nie człowiek-maszyna, choć prostota poleceń i czytelna forma nie wykluczają jego manualnej obsługi (vide `Rigol na smyczy`). Tak po prawdzie to mając podobne zagwozdki warto sięgnąć po opracowanie opisujące standard, na przykład: http://www.ivifoundation.org/docs/scpi-99.pdf Finalnie stanęło na tym, że mój Meratronik będzie rozumiał następujące autorskie polecenia:
Kod: Zaznacz cały
TCommand scpiCommands[] = {
{ "*idn?", &handlerIdn },
{ ":meter:mode?", &handlerMode },
{ ":meter:v:range?", &handlerVRange },
{ ":meter:r:range?", &handlerRRange },
{ ":meter:raw?", &handlerRawData },
{ ":meter:display?", &handlerDisplay },
{ ":debug:exit", &handlerExit },
{ NULL , NULL }
};
*idn?
Identyfikacja urządzenia, numer seryjny przepisany z obudowy oraz copyright aby wyglądało na profeskę, przynajmniej dla tych, co się nie znają.
:meter:mode?
Polecenie zwraca aktualny tryb racy multimetru lub błąd w przypadku nie wciśnięcia żadnego z przycisków funkcyjnych.
Zwraca wartość jest w formacie n|xx , gdzie n – identyfikator trybu wynikający z kombinacji bitów na tylnym złączu, xx –literały { R, AC, DC }, czyli w kodzie jest:
Kod: Zaznacz cały
const char *pszModeDesc[] = {
"error", // 0
"R", // 1
"AC", // 2
"error", // 3
"DC" // 4
};
:meter:v:range?
Polecenie zwraca aktualnie ustawiony zakres pomiarowy napięcia lub błąd gdy miernik nie jest w trybie VAC lub VDC.
Zwraca wartość jest w formacie n|xxxx|ddd na zasadach jak powyżej, dozwolone wartości zgodnie z definicją:
Kod: Zaznacz cały
TRangeInfo volRanges[] = {
{ "100V", 100 }, //0
{ "1V", 10000 }, //1
{ "1000V", 10 }, //2
{ "10V", 1000 }, //3
{ "100mV", 100 }, //4
{ "error", 1 }, //5
{ "error", 1 }, //6
{ "error", 1 } //7
};
:meter:r:range?
Polecenie zwraca aktualnie ustawiony zakres pomiarowy rezystancji lub błąd gdy miernik nie jest w trybie R.
Zwraca wartość jest w formacie n|xxx|ddd na zasadach jak powyżej, a dozwolone wartości takie:
Kod: Zaznacz cały
TRangeInfo resRanges[] = {
{ "100kΩ", 100 }, //0
{ "1kΩ", 10000 }, //1
{ "error", 1 }, //2
{ "10kΩ", 1000 }, //3
{ "error", 1 }, //4
{ "1MΩ", 10000 }, //5
{ "error", 1 }, //6
{ "10MΩ", 1000 } //7
};
W obu przypadkach ddd - to podzielnik, wynikający z aktualnie ustawionego zakresu, jest podstawą do sformatowania wyniku.
:meter:raw?
Polecenie zwraca 32-bitową liczbę w formie ośmiu cyfr szesnastkowych. Zawartość binarna zgodna z Tabelą 1 z artykułu w EdW 4/2018.
:meter:display?
Polecenie zwraca zawartość wyświetlacza w postaci pięciocyfrowej liczby dziesiętnej (bcd) wraz ze znakiem polaryzacji dla pomiarów DC oraz bez znaku dla R i AC. Brak kropki dziesiętnej, wynik trzeba sformatować samodzielnie.
:debug:exit
Komenda na użytek wewnętrzny, to zatrzymanie aplikacji, przydaje się zamiast wpisywania `killall v543`
Jak widać odpowiedzi interfejsu są zrozumiałe dla średnio rozgarniętego operatora, ale i możliwe do obróbki programowej. Wystarczy napis z informacją o zakresie czy trybie potraktować funkcją strtok() czy jej odpowiednikiem dzielącym napis na składniki w/g separatora (u mnie `|`) i mamy osobne wartości do wykorzystania.
Proszę też zauważyć, że nie ma w tym zestawie polecenia *rst resetującego urządzenie. No cóż – w moim przypadku załamanie pracy aplikacji automatycznie znieczuli ją na nadchodzące polecenia, więc zdalny restart nie wchodzi w grę. Pomoże tylko interwencja przez ssh lub brutalna manipulacja przy zasilaniu.
Na chwilę obecną nie pochylam się zbytnio nad zdarzeniami zachodzącymi w otoczeniu multimetru, więc brakuje obsługi poleceń *ese?, *esr? I tym podobnych. Można oczywiście zastanowić się nad zapamiętywaniem wystąpienia sygnału OVER wraz ze znacznikiem czasu czy obserwowaniem wartości MIN/MAX. Malina pracująca jako interfejs ma naprawdę sporą moc obliczeniową i można sobie używać.
Testy - tu z wywołaniem exit:
Kod: Zaznacz cały
echo ":debug:exit" | nc neonowy 5555
Pomiary rezystancji:
testr.sh pisze:Kod: Zaznacz cały
echo "*idn?" | nc neonowy 5555
echo ":meter:mode?" | nc neonowy 5555
echo ":meter:r:range?" | nc neonowy 5555
echo ":meter:display?" | nc neonowy 5555
echo ":meter:raw?" | nc neonowy 5555
Kod: Zaznacz cały
while true; ./testr.sh; sleep .5; done
Pomiary napięcia:
testv.sh pisze:Kod: Zaznacz cały
echo "*idn?" | nc neonowy 5555
echo ":meter:mode?" | nc neonowy 5555
echo ":meter:v:range?" | nc neonowy 5555
echo ":meter:display?" | nc neonowy 5555
echo ":meter:raw?" | nc neonowy 5555
Kod: Zaznacz cały
while true; ./testv.sh; sleep .5; done
Na żywo praca interfejsu wygląda tak:
https://youtu.be/X6LNc4dJ-tI
Aby programik v543 uruchamiał się automatycznie, wystarczy dodać go do /etc/rc.local i mamy samograj.
Podsumowanie i :debug:exit
O Raspberry PI napisano już bardzo wiele, więc z moje strony może tylko tyle, że nie ma co demonizować tego systemiku i traktować jako czegoś szczególnie magicznego. To zwykły system mikroprocesorowy bazujący na dość mocnym ARM z linuksem (a'la Debian) na pokładzie, oswojenie go tak, aby skakał przez kijek nie jest jakimś szczególnym wyzwaniem. Ma bardzo dużo zalet i sporo pracy potrafi z nas zdjąć. Ma też swoje upierdliwości, z którymi trzeba się będzie pogodzić gdy kto jednak zdecyduje się pójść w tym właśnie kierunku.
Ważne natomiast jest to, że obcując z Raspberry PI możemy w pełni wykorzystać swoje dotychczasowe doświadczenia z Linux zdobyte na domowej, dużej maszynie. Próg wejścia jest naprawdę niewielki. W drugą stronę zadziała to tak samo - eksperiencja z przygód z Maliną przyda się do pracy z innymi, poważniejszymi platformami bazującymi na Linux, czy Unix. Do kompletu dochodzi ogromna ilość literatury, na wszelkie możliwe okazje, od administracji po development aplikacji sieciowych, jest w czym wybierać.