Biblioteki .Net do komunikacji ze sterownikami PLC Siemens – Komunikacja z LOGO

2

Sterowniki serii LOGO!, znajdujące się w ofercie Siemens-a to najprostsze ze sterowników PLC oferowanych przez tą firmę. Odbiegają one dość znacznie zarówno od serii S7-300/400 jak i od S7-1200/1500. Różnice znajdziemy zarówno w możliwościach konfiguracji o dodatkowe moduły, mocy obliczeniowej jak i w samym oprogramowaniu służącym do programowania i parametryzacji. LOGO znajdują zastosowania głównie w najprostszych maszynach, gdzie ilość sygnałów i operacji, jakie chcemy na nich wykonywać jest niewielka lub w zastosowaniach typu Smart Home.

W poprzednich postach z tego cyklu wspominałem, że również z tymi sterownikami możemy nawiązać połączenie z poziomu .Net wykorzystując do tego dostępne biblioteki. Niedawno pojawiła się okazja na przetestowanie tych możliwości w praktyce i na kanwie tego doświadczenia powstał ten post.Komunikację z LOGO trzeba zrealizować nieco inaczej niż w przypadku pozostałych sterowników. Tyczy się to zarówno konfiguracji samego sterownika jak i sposobu nawiązywania połączenia.

Do testowania komunikacji wykorzystałem ulubioną bibliotekę Sharp7, która jest .Net-owym portem biblioteki Snap7. W dokumentacji Snap7 znajdziemy nawet specjalny dokument, opisujący jak sobie poradzić z realizacją takiego połączenia. Zacznijmy więc od sterownika.

KONFIGURACJA STEROWNIKA

Po stronie projektu sterownika konieczne jest ustawienie parametrów połączenia.W tym celu, w narzędziu LOGO Soft Comfort, w naszym projekcie, przełączamy się do zakładki Network Project. W okienku Network View klikamy pozycję Add New Device i dodajemy nasz sterownik. Definiujemy adres IP, na którym będziemy realizować z nim połączenie Ethernetowe.Kiedy obrazek sterownika pojawi się już w oknie Network View, musimy zdefiniować połączenie serwerowe. Sterownik w naszym przypadku będzie działał jako serwer. To nasza aplikacja będzie z nim nawiązywać połączenie, wykonywać operacje odczytu/zapisu i zamykać to połączenie.W tym celu klikamy prawym przyciskiem na obrazku sterownika i z podręcznego menu wybieramy pozycję Add server connection… .

Pojawi się okienko konfiguracyjne. Jeżeli chcemy, aby dostęp do sterownika miał komputer z dowolnym adresem IP, po prawej stronie zaznaczamy pozycję Accept All Connection Requests. Poniżej wpisujemy numer TSAP, czyli numer określający kanał i pozycję w komunikacji. Numery TSAP mają w tym przypadku duże znaczenie, gdyż zarówno numer po lewej stronie jak i numer po prawej będziemy wykorzystywać do parametryzacji połączenia po stronie naszej aplikacji. Wartość parametru Connect With an Operator Panel nie ma wielkiego znaczenia dla funkcjonowania naszej komunikacji.
Konfigurację musimy oczywiście zapisać i załadować do sterownika !

APLIKACJA

Połączenie ze sterownikiem będziemy parametryzować nieco inaczej niż w przypadku opisywanych wcześniej sterowników. Tym razem nie będziemy podawać parametrów Rack i Slot. Skorzystamy z wcześniej ustalonych numerów TSAP.

Kod konfigurujący połączenie będzie wyglądał tak:

Utworzymy obiekt klasy S7Client

var _logo = new S7Client();

 

Zdefiniujemy parametry połączenia

_logo.SetConnectionParams(_ipAddress, 0x0300, 0x0200);

 

I już możemy próbować nawiązywać połączenie – identycznie jak w przypadku sterowników S7-300/400 czy S7-1200/1500

var result = _logo.Connect();

 

Trzeba zwrócić uwagę na jedną, bardzo ważną sprawę. W definicji funkcji SetConnectionParams znajdziemy argumenty LocalTSAP i RemoteTSAP. Musimy je wprowadzić odwrotnie, niż zrobiliśmy to w konfiguracji sterownika. Numer TSAP, który zdefiniowaliśmy w projekcie sterownika jako Remote wprowadzamy jako LocalTSAP, a numer TSAP który zdefiniowaliśmy jako LOCAL wprowadzamy jako RemoteTSAP.

Odczyt i zapis danych będzie wyglądał również nieco inaczej. Cała przestrzeń VM wewnątrz pamięci sterownika mapowane jest w komunikacji na blok DB1. I tutaj uzyskamy dostęp do zdefiniowanych zmiennych oraz wejść/wyjść. Operacje wykonujemy oczywiście za pomocą metod DBWrite i DBRead.

Mapa adresów w DB1 sterowników LOGO przedstawia się w następujący sposób:

Dla przykładu. Aby odczytać zawartość zmiennej typu Integer. Znajdujące się pod adresem VM8 odczytamy 2 bajty spod adresu 8 w DB1. Następnie należy wykonać standardową konwersję z formatu Simatic.

var buffer = new Byte[2];
var result = _logo.DBRead(1, 8, 2, buffer);
var value = S7.GetIntAt(buffer,0);

 

Aby odczytać stan wejścia 2 w sterowniku, musimy pobrać cały bajt (w komunikacji S7 nie ma możliwości odczytu pojedynczego bit-u) i „wyłuskać” z niego interesujący nas bit.

var buffer = new byte[1];
var result = _logo.DBRead(1, 1024, 1, buffer);
var i2 = S7.GetBitAt(buffer, 0, 2);

 

Warto pamiętać, że jeżeli chcemy bezpośrednio wystawić wyjście ze sterownika (czego raczej zalecam unikać, lepiej wystawiać flagę i następnie na podstawie tej flagi wyjście wystawić ze sterownika, analizując wcześniej wszystkie parametry i stany mające wpływ na dane wyjście). To musimy przeczytać cały bajt wyjść, następnie zmienić jedynie ten bit na którym nam zależy i zapisać bajt z powrotem. W przeciwnym wypadku może się zdarzyć, że zmienimy stan wyjścia które jest wysterowywane (lub nie) przez program sterownika.

ZX Spectrum – wspomnień czar

6

Każdy z nas jakoś zaczynał swoją przygodę z komputerami. Dla jednych były to współczesne PC-ty lub produkty z logiem nadgryzionego jabłka. Dla innych – nieco starszych – PC-ty starszej generacji, pracujące pod kontrolą Windowsa XP albo może nawet i DOS-a. Być może była to poczciwa Amiga, na którą wielu w czasach jej świetności spoglądało z pożądaniem i zazdrością wobec kolegów posiadających takie cudenko. Część z nas jednak, pierwsze kroki w cyfrowym świecie stawiała jeszcze z pomocą komputerów 8-bitowych. W Polsce spotykaliśmy głównie 3 przedstawicieli tego gatunku. Atari, Komodę (czyli Commodore 64) oraz ZX Spectrum. Z wypiekami na twarzy podłączaliśmy je do błyskającego kineskopem telewizora, wgrywaliśmy gry z kaset i przeżywaliśmy wspaniałe przygody w tętniącym pixelami świecie.

Z punktu widzenia dzisiejszego gracza gry z tamtego okresu można by pewnie określić jednym słowem – „tragedia”. Kilka pixeli na ekranie definiowało naszego bohatera, który podążał przez kolejne ekrany, lub komnaty – również reprezentowane przez małą grupkę kwadratowych plamek. Działała jednak wyobraźnia i pomimo bardzo wysokiego stopnia trudności, jaki serwowały ówczesne gry, dostarczały one wielu niezapomnianych do dzisiaj emocji.

8-bitowce zaopatrzone były również w pewną wspaniałą rzecz. Był nią interpreter języka BASIC. Pozwalał on na stawianie pierwszych nieśmiałych kroków w świecie programowania. Jakież ogromne wrażenie robiło odpalenie pierwszego, samodzielnie napisanego programu w basic-u. Oto my – stoimy niemal w tym samym rzędzie co autorzy gier, w które tak namiętnie grywamy. To oczywiście stwierdzenie mocno na wyrost, ale w głowie kilku- czy kilkunasto-latka trochę tak to wyglądało. Oto mamy moc, która pozwala nam zrobić z naszym komputerem niemalże wszystko.

BASIC był językiem prostym. Szybko można było zrozumieć co to jest zmienna, jak działają pętle i instrukcje warunkowe. Łatwo prosto i czytelnie. Żadnych obiektów, żadnych wzorców projektowych, żadnych skomplikowanych zasad. Żadnych maszyn wirtualnych, serwerów albo środowisk uruchomieniowych. Po włączeniu zasilania natychmiast pojawiał się wesoło mrugający kursor interpretera zachęcający do wprowadzania programu, który potem można było zapisać na kasecie lub dyskietce. Jaka to była radość – mój własny program na kasecie.

Później pojawiała się ochota na zrozumienie, jak to jest że gry wyświetlają grafikę, jak to jest że animowana postać na ekranie może być sterowana za pomocą klawiszy lub joysticka. Jak to jest, że w tle gra muzyka lub pojawiają się efekty dźwiękowe. Ciekawość prowadziła wprost do kodu źródłowego gier – a tam – zwykle czekał już Assembler. Programowanie w tamtym czasie było tak bardzo „bliskie metalu”. Grzebiąc w kodzie gier można było metodą prób i błędów osiągnąć całkiem ciekawe efekty. Trzymając w dłoni podręcznik opisujący assemblera zaś, przeżyć swoje pierwsze „aha … to tak to jest zrobione”. 

W Polsce pojawiła się też prasa poświęcona mikrokomputerom. Niezapomniany Bajtek czy Mikroklan. Często pojawiały się tam listingi programów lub gier, które należało pieczołowicie wklepać i cieszyć się z działającego programu lub gry. Częściej jednak szmat czasu należało poświęcić na znalezienie błędu, który powstał podczas przepisywania kodu. Była to jednak nieodzowna część klimatu tamtych czasów. 

Moja przygoda z komputerami zaczęła się właśnie od ZX Spectrum. Genialnego urządzenia wytwarzanego przez Sinclair Research w latach 80-tych. Małe gabaryty, 48kB pamięci, kolorowa grafika i wbudowany głośniczek. Kasety z grami przegrywało się od kolegów lub kupowało na straganach – piractwo nie było wtedy prawnie zabronione. I to właśnie Sinclair Basic był językiem, w którym napisałem pierwszy w życiu program.

Kilka dni temu – po wielu latach – odkopałem moje Spectrum+. Nadal działa w 100%. Odpaliłem pierwszą grę – i okazało się, że nadal jest tak samo fajna jak była 30 lat temu. Brakuje mi jednak skill-a. Palce już zapomniały jak trafić w odpowiednie klawisze, żeby Manic Minner nie zginął już na pierwszej planszy i nie pojawił się znienawidzony napis „Game over”. Kursor basic-owego interpretera nadal ochoczo mruga zachęcając do programowania. Czas się cofnął.

Gry i programy z 8-bitowców możemy oczywiście odpalić na emulatorach, które dają nam namiastkę zabawy z tamtych lat. Pojawiła się również moda na retro. Ostatnimi czasy mamy wysyp różnego rodzaju urządzen dla fanów old-schoolowego grania. Mamy NES-a mini, SNES-a mini, Playstation Classic i nawet C64 mini. Ja sam czekam z niecierpliwością na reedycję ZX Spectrum pod nazwą ZX Spectrum Next

Fajnie też wrócić do czasów, kiedy programowanie było prostsze i dawało prawdziwą kontrolę nad sprzętem. Dzisiaj kod dla 8-bitowców możemy wygodnie przygotować na laptopie, odpalić w emulatorze, zdebuggować, postawić breakpointy. To wszystko było kiedyś niemal nieosiągalne. Kod należało najpierw bardzo dobrze przemyśleć, potem najlepiej zapisać na kartce i przeanalizować jeszcze raz a dopiero na koniec wprowadzić za pomocą klawiatury. Każdy bajt pamięci był na wagę złota. Każda linijka kodu musiała krótko i zwięźle realizować swoje zadanie. Dzisiaj działamy na dużo wyższym poziomie abstrakcji, ale kto wie, czy ówczesne metody programowania nie były jednak lepsze ?

Wracam do mojego Spectrum. Jednostajny dźwięk z magnetofonu obwieszcza, że kolejna gra się „wgrała”. Można zacząć zabawę :).

Tutaj ten post miał się skończyc. Ale dosłownie w momencie gdy pisałem tego posta pojawił się na Netflix-ie nowy odcinek Black Mirror – Bandersnatch osadzony w realiach gamedev-u dla ZX Spectrum. Jeszcze go nie oglądałem. Ciekawe, czy sprowokuje on przynajmniej część osób do wygrzebania ze strychu swojej starej maszynki albo chociaż odpalenia emulatora, by poczuć jak to było.

Piekiełko wieloplatformowego desktopu

0

Od dłuższego czasu śledzę tematykę desktopowych aplikacji wieloplatformowych, marząc wciąż o rozwiązaniu idealnym. Do napisania tego postu zmobilizowała mnie ogromna ilość różnego rodzaju postów, czy też wpisów na różnych forach sugerująca jakoby Electron stał się obecnie dominującą technologią tworzenia wieloplatformowych rozwiązań desktop.

Jest w tym stwierdzeniu dużo prawdy. Co raz więcej aplikacji powstaje w tej technologii lub jest wręcz migrowanych z rozwiązań natywnych właśnie na aplikacje bazujące na Electronie.

Dla niewtajemniczonych: Electron to taka paczka zawierająca w sobie silnik chromium oraz node.js, która pozwala zapakować aplikację webową w taki sposób, że działa ona niemal jak natwna aplikacja desktopowa. Oczywistą zaletą jest właśnie wieloplatformowość takiego rozwiązania.

Kiedy zaczynałem swoją zawodową przygodę z programowaniem ponad 15 lat temu, technologie webowe były jeszcze nieco w powijakach. Javascript służył do animowania obrazków na stronach a prym w dostarczeniu rozwiązań webowych po stronie serwera wiódł tandem PHP + MySQL. Sam zresztą w czasach studenckich sporo czasu spędziłem pracując w tym ekosystemie tworząc proste rozwiązania dla klientów. Można było w ten sposób fajnie dorobić do uczelnianego stypendium. Z mojego punktu widzenia – w tamtym czasie – „Prawdziwe” aplikacje, to był jednak natywny desktop i tym się chciałem zajmować (co się zresztą udało). Dominującą pozycję wtedy na świecie (przynajmniej z punktu widzenia programisty z Polski) miał Windows. Maca używano tylko za oceanem a Linux był uważany za system jedynie serwerowy. Temat wieloplatormowości nie był więc zbyt istotny.

Świat się zmienił. Dzisiaj praktycznie każde rozwiązanie przybiera postać aplikacji webowej. Rozwiązań natywnych jest coraz mniej. Co prawda na mobilkach nadal zdecydowanie rządzą aplikacje natywne, ale przy obecnym rozwoju hardware-u to prawdopodobnie również jedynie kwestia czasu. Dzisiejsze natywne rozwiązania desktopowe to głównie bardzo specjalistyczne oprogramowanie – chociaż i rozwiązania chociażby CAD trafiają coraz częściej do przeglądarki. Zdecydowanie łatwiej zarabiać w ten sposób w modelu subskrypcyjnym – ulubionym ostatnimi czasy przez wiele firm.

Okazuje się jednak, że jakieś zapotrzebowanie na aplikacje desktopowe nadal jest. Nie w każdym kraju świata możemy sobie zapewnić stały, szybki i tani internet. Czasami nadal występuje potrzeba pracy offline.

W moim odczuciu Electron nie jest rozwiązaniem wybieranym ze względu na swoją jakość, ale bardziej ze względu na optymalizację kosztów. Jeden zespół tworzy wszystko – aplikację webową, mobile i desktop. Przy dzisiejszym wysokim koszcie pracy programisty jest to zrozumiałe. Na rynkach, gdzie koszt pracy programisty nie jest wysoki (jak np. Chiny) sytuacja wygląda z goła inaczej – nadal większość aplikacji to native.

Dlaczego Electron nie bardzo mi się podoba:

  1. Potężny rozmiar gotowego projektu. Proste „Hello World” to ok 115Mb. Wyobraźmy sobie teraz, że napisaliśmy prostego Pong-a w Javascript i chcemy z niego zrobić fajną desktopową aplikację. Stupiętnasto megabajtowy Pong ? Serio ?
  2. Każda aplikacja pracuje w izolowanym środowisku własnego chromium. Im więcej ich odpalimy tym więcej instancji wirtualnego środowiska jest uruchomionych. Pamięciożerność Chrome jest już legendarna – tutaj wszystko multiplikujemy.
  3. Wydajność. Z tym jest już lepiej, ale każdy kto próbował używać pierwszych wersji edytora Atom na nieco słabszym sprzęcie wie o czym mówię.

Jeżeli nie Electron to co ?

Cóż jest wiele innych rozwiązań, ale każde ma jakiś naprawdę istotny mankament. W przypadku Qt, które wydaje się świetnym produktem o ugruntowanej pozycji mamy licencję LGPL v.3 (która jak się okazuje wcale nie jest taka prosta do ogarnięcia, fundacja Qt opublikowała nawet specjalny film, w którym prawnik tłumaczy w jaki sposób Oni ją interpretują) lub kosmiczne koszty w wersji full-commercial. Biblioteki dla C# i Mono takie jak Avalonia są rozwijane przez małe community i ciężko na nich opierać duży komercyjny projekt. Flex ? – no przecież Flash is Dead. Może Java ? … poza produktami JetBrains od lat nie widziałem dużego projektu desktopowego w Javie. Część projektów (jak np. silnik gier Godot, czy LibreOffice lub Blender) tworzy własne rozwiązanie, dedykowane do produktu.

Pewne nadzieje można wiązać z Proton Native, który ma być odpowiednikiem React Native dla desktopu – ale to również projekt we wczesnej fazie rozwoju.

Innymi słowy – na chwilę obecną dobre rozwiązanie, pozwalające tworzyć szybkie i dobrej jakości wieloplatformowe aplikacje desktopowe nie istnieje. Z Electronem jest w tej chwili trochę jak w przysłowiu o demokracji: Jest trochę do d..y, ale póki co niczego lepszego nie wymyślono.

I tym samym – marząc nadal o stworzonej przez Microsoft wersji WPF-a opartej na Xaml-u, współpracującym z .Net Core i działającym natywnie pod Win/Mac/Linux – kończę.

Format IntelHex

0

Dzisiaj również tematyka nieco techniczno-niszowa i tym razem bez wstępnej dygresji :).

Z formatem Intel Hex pewnie stosunkowo niewielu programistów się spotkało i być może niewielu się spotka. Nie mniej jednak, gdy pojawia się taka konieczność – nie jest tak łatwo zdobyć proste i „zjadliwe” informacje a jeszcze trudniej gotową do zaadaptowania implementację w danej technologii.

Zmierzyłem się z tym problemem kilka miesięcy temu i ostatecznie konwerter do tego formatu napisałem sam. W tym poście podzielę się czym to jeść. Na końcu posta znajdziesz link do repozytorium na github, gdzie wrzuciłem prosty przykładowy konwerter napisany w C#.

Format Intel Hex dotyczy plików tekstowych w kodowaniu ASCII. Każda linia w takim pliku zawiera jeden rekord „Hex”. Rekordy te zawierają kod maszynowy w formacie hexadecymalnym (szasnastkowym) oraz pewne informacje stałe (opcjonalnie). Pliki w formacie Intel Hex są często używane do transferowania programu lub danych, które są następnie zapisywane w ROM-ie lub EPROM-ie urządzeń. Większość programatorów EEPROM lub emulatorów urządzeń potrafi korzystać z plików w formacie Intel Hex. Mówimy więc o tematyce niejako związanej z programowaniem układów mikroprocesorowych – chociaż nie do końca. W tym formacie przesyłane są również np. grafiki wyświetlane na prostych wyświetlaczach lub grafiki na etykiety drukowane przez drukarki kodów kreskowych.

Właśnie w tym ostatnim kontekście przeanalizujemy ten format. Przykładowy konwerter, który wrzuciłem do repozytorium służy właśnie do konwertowania plików .bmp do formatu Intel Hex rozumianego przez drukarki kodów kreskowych Intermec.

Istotną kwestią jest pewna dowolność producentów urządzeń w podejściu do formatu. Często można spotkać się z pewnymi dodatkowymi wymaganiami jeżeli chodzi o nagłówek i stopkę transferowanego pliku. Tak jest właśnie w przypadku drukarek Intermec i ten nagłowek i stopkę również można znaleźć w moim przykładowym kodzie.

Rekord w formacie IntelHex ma następującą budowę:

  • Każda linia (czyli każdy rekord) zaczyna się znakiem dwukropka :
  • Następnie znajduje się informacja o długości (ilości) danych zawartych w rekordzie
  • Następnie adres, który mówi o pozycji w rekordzie. Jest to bardzo ważne pole, ponieważ pozwala na poprawne uporządkowanie sekwencji rekordów
  • Typ rekordu – i tutaj znajdziemy:
            – 00 rekord danych
            – 01 rekord końca pliku
            – 02 rekord adresu rozszerzonego segmentu
            – 04 rekord rozszerzonego adresu liniowego
            – 05 początek rozszerzonego adresu liniowego
  • Dane właściwe
  • Suma kontrolna

Na końcu rekordu, w zależności od wymagań urządzenia interpretującego musi znaleźć się znak końca linii (CR – czyli \r w C#) a czasami również i przejścia do nowej linii  (LF – czyli \n w C#).

Sumę kontrolną liczymy w dość standardowy sposób. Zsumowane bajty odejmujemy zsumowaną wartości 255. Sumę oczywiście musimy zapisać w formacie hexadecymalnym.

Jeżeli chodzi o mój przykład kodu, służy on do konwertowania obrazów (bitmap) monochromatycznych o wymiarach od 16×16 do 32×32 piksele do formatu rozumianego przez drukarki kodów kreskowych Intermec. Taka bitmapa jest następnie konwertowana do postaci tablicy bajtów i kolejne wiersze konwertowane są według opisanej powyżej metody.

Kod nie jest zbyt uniwersalny, ale myślę że daje dobry pogląd na to w jaki sposób zmierzyć się z tematem.

Adres repozytorium z przykładowym kodem:

https://github.com/pstrejczek/IntelHex

Komunikacja szeregowa ze skanerami Motorola/Zebra z poziomu C#

0

Dzisiaj post techniczny i pewnie też trochę niszowy. Porozmawiamy o tym jak oprogramować komunikację szeregową ze skanerami Motorola/Zebra bez korzystania z trybu emulacji klawiatury i bez zewnętrznych bibliotek. Ale tradycyjnie, zaczniemy od pewnej dygresji.

W układach przemysłowych czy quasi-przemysłowych korzystamy z wielu różnych standardów komunikacji. Używamy różnych standardów zarówno pod względem warstwy fizycznej jaki i warstwy protokołu. W warstwie fizycznej wykorzystujemy głównie Ethernet i połączenia szeregowe. Jeżeli chodzi o protokoły mamy tego multum na różnych warstwach i poziomach. Komunikację realizujemy zarówno z wszelkiego rodzaju czujnikami jak i urządzeniami wykonawczymi. Od wielu lat, w ofercie wielu znanych producentów komponentów znajdziemy także urządzenia na USB. I tutaj moja rada, i być może nieco kontrowersyjne stwierdzenie: USB NIE JEST STANDARDEM PRZEMYSŁOWYM !. Jeżeli nasz układ (w tym komunikacja) ma być niezawodny i łatwo diagnozowany – unikajmy połączenia USB jak ognia ! Ilość problemów na jakie możemy napotkać jest nieskończona. Od problemów z niewystarczającym zasilaniem, bo dziwne funkcjonowanie sterowników w samym systemie, na które nie mamy wpływu – aż po niedorobione biblioteki producentów urządzeń, które plują wyjątkami w dziwnych sytuacjach na które support odpowiada „u mnie działa”.

Jeżeli istnieje możliwość oprogramowania komunikacji w możliwie najniższej (z naszego punktu widzenia) warstwie – TCP albo Łącze szeregowe – nawet jeżeli będzie wymagało to nieco więcej pracy, to taką drogą idźmy. Będziemy mieć wtedy pełny wpływ na stan połączenia i jego diagnostykę. Możemy też odpowiednio zareagować w różnych dziwnych sytuacjach.

Wróćmy jednak do tematu:

Wiele tańszych skanerów z oferty firmy Zebra (kiedyś Motorola) oferuje interfejs szeregowy a wiele z nich świetnie nadaje się także do zastosowań przemysłowych – np. rewelacyjny model DS457. Łatwo i szybko skonfigurujemy taki skaner, jeżeli potrzebujemy tryb emulacji klawiatury. Wybór skanera z interfejsem szeregowym jest też całkiem uzasadniony, gdy chcemy podpiąć go po ethernecie. Skorzystanie z rozwiązania typu Moxa N-port będzie tańsze, niż zakup skanera który sam z siebie posiada interfejs ethernetowy.

Co jednak, gdy chcielibyśmy posterować triggerem i timeout-em trigger-a z własnej aplikacji ? Albo chcemy zdiagnozować ewentualne problemy przy odczycie lub w samej komunikacji ?

Możemy skorzystać do tego celu z potężnego Zebra SDK, albo możemy sami oprogramować komunikację w standardzie SSI realizowaną przez te skanery – co nie jest zadaniem trudnym, a pozwoli na pełną kontrolę nad obsługą urządzenia. Zaletą będzie brak konieczności instalowania jakichkolwiek driver-ów czy zewnętrznych bibliotek jeżeli chodzi o część naszej aplikacji realizującą komunikację z urządzeniem.

KONFIGURACJA SKANERA

Większość skanerów, po wyjęciu z pudełka, jest skonfigurowana do pracy w trybie emulacji klawiatury. Aby skorzystać z trybu SSI musimy odpowiednio skonfigurować skaner. Konfiguracja odbywa się przez skanowanie odpowiednich kodów kreskowych z dokumentacji skanera, którą pobierzemy ze strony www producenta.

Aby skaner poprawnie pracował w trybie SSI i łatwo było nam oprogramować komunikację najlepiej jest ustawić:

  • Tryb triggera na HOST
  • SSI HOST
  • SEND RAW DECODE DATA
  • Disable ACK/NACK

Jeżeli korzystamy z urządzenia typu N-port w trybie TCPServer i komunikację realizujemy po ethernecie, konieczne może się również okazać zeskanowanie parametru Host: RTS High.

Po tych operacjach, skaner powinien być gotowy do komunikacji w trybie SSI.

OBSŁUGA KOMUNIKACJI

Musimy zadbać o właściwe sformatowanie ramki, którą wyślemy do skanera.

Ramka powinna zawierać:

  • 1 bajt długości ramki.
  • 1 bajt samego komunikatu
  • 1 bajt źródła komunikatu  – ustawiamy na 4
  • 1 bajt z ilością powtórzeń – ustawiamy na 0
  • 1 bajt sumy kontrolnej

Suma kontrola jest dość prosta do policzenia:

Do długości ramki dodajemy wartość samego bajtu komunikatu, wartość bajtu źródła komunikatu, oraz wartość bajtu z ilością powtórzeń. Całość mnożymy przez -1. Przy tych długościach komunikatu cała suma kontrola zmieści się nam w 1 bajcie.

Dalej obsługa jest tak naprawdę stosunkowo prosta:

  • otwieramy sobie połączenie szeregowe lub TCP.
  • wysyłamy do skanera bajt komendy włączającej trigger – 0x8A (w Hex) – pamiętamy o formatowaniu ramki
  • następnie odpalamy trigger wysyłając bajt – 0xE4 (w Hex) – pamiętamy o formatowaniu ramki
  • jeżeli skaner zeskanuje kod to w odpowiedzi otrzymamy zeskanowany kod
  • dobrze jest też wprowadzić timeout – czyli po pewnym czasie od odpalenia triggera wyłączyć go, jeżeli kod nie został zeskanowany. Wyłączenie triggera – 0xE5(Hex) – pamiętamy o formatowaniu ramki

I to tak naprawdę cała filozofia.

Na github-ie umieściłem napisaną przez siebie bibliotekę do obsługi takiej komunikacji (opartą na eventach) wraz z prostą aplikacją testową w Windows Forms.

Zainteresowanych zapraszam na: https://github.com/pstrejczek/MotZebSsi