BETA
Aby się zalogować, najpiew wybierz portal.
Aby się zarejestrować, najpiew wybierz portal.
Podaj słowa kluczowe
Słowa kluczowe muszą mieć co najmniej 3 sąsiadujące znaki alfanumeryczne
Pole zawiera niedozwolone znaki

Baza wiedzy











Obsługa portu IrDA w urządzeniach typu Smart Devices

04-01-2005 20:24 | 2iup
Komunikacja bezprzewodowa z wykorzystaniem promieni podczerwonych stała się ostatnimi czasy niezwykle popularna. Nie szukając daleko, przyjaciel każdego leniwego miłośnika telewizji - najprostszy pilot komunikuje się z odbiornikiem telewizyjnym przy użyciu promieni podczerwonych.Technologię tą wykorzystać można nie tylko do zmieniania kanałów, ale i do transmisji danych. Ta ważna cecha w połączeniu z niską ceną i łatwością użycia spowodowała, iż porty IrDA (Infrared Data Association) są obecnie

  

Obsługa portu IrDA w urządzeniach typu Smart Devices

 

 

 

Komunikacja bezprzewodowa z wykorzystaniem promieni podczerwonych stała się ostatnimi czasy niezwykle popularna. Nie szukając daleko, przyjaciel każdego leniwego miłośnika telewizji - najprostszy pilot komunikuje się z odbiornikiem telewizyjnym  przy użyciu promieni podczerwonych.Technologię tą wykorzystać można nie tylko do zmieniania kanałów, ale i do transmisji danych. Ta ważna cecha w połączeniu z niską ceną i łatwością użycia spowodowała, iż porty IrDA (Infrared Data Association) są obecnie montowane w większości komputerów osobistych, palmtopów i telefonów komórkowych. W moim artykule przedstawię sposób obsługi portu IrDA w środowisku programowym Microsoft Visual Studio .NET.

 

 

            Wstęp

 

Programiści Microsoft dołączyli do .NET Compact Framework w wersji 1.1 klasy pozwalające na obsługę portu IrDA w urządzeniach mobilnych. Nie jest to żadna rewolucja, wcześniej też było to możliwe. W językach takich jak embedded VB czy C++ można było napisać parędziesiąt linii kodu wyszukujących numer portu w rejestrze, ustawiających parametry i otwierających połączenie. Można było również skorzystać z prostszego rozwiązania, poszperać w Internecie i użyć gotowych klas, napisanych wcześniej przez innych programistów. Teraz odpowiednie narzędzia są dostępne bezpośrednio w VS .NET.

 

W pakiecie .NET  do obsługi IrDA istnieją 4 klasy:

 

IrDAClient – główna klasa odpowiedzialna za ustanawianie połączenia, zajmująca się wyszukiwaniem urządzeń i przesyłaniem danych

IrDADeviceInfo – klasa dostarczająca informacji na temat urządzeń, z którymi możemy się połączyć np.: będących w zasięgu portu

IrDAEndPoint – klasa reprezentująca punkt końcowy, adres połączenia

IrDAListener – klasa monitorująca połączenie, czekająca na próbę połączenia

 

Klasy te są zawarte w bibliotekach System.Net i System.Net.Socket. Używając ich mamy pełny dostęp do funkcjonalności portu podczerwieni. Przykłady zawarte w dalszej części artykułu przybliżą  ich zastosowanie.

 

 

Wyszukiwanie urządzeń

 

            Poniższy fragment kodu wyszukuje urządzenia w zasięgu portu IrDA i wyświetla w kontrolce listBox ich nazwy. Wyszukiwanie urządzeń w celu połączenia ich za pomocą portów podczerwieni może się wydać kuriozalnym pomysłem, biorąc pod uwagę ograniczenia, które taki typ połączenia nam narzuca (niewielka odległość połączenia, wrażliwość na przeszkody i konieczność ustawienia portów naprzeciw siebie). Nie znajdziemy w ten sposób niczego poza tym, co znajduje się w zasięgu naszego wzroku. Napisany kod dostarczy nam jednak paru istotnych informacji i będzie wykorzystywany w następnych przykładach.

 

[Kod C#]
 

      int n = 10;

      IrDAClient irdaClient = new IrDAClient();

      IrDADeviceInfo [] deviceList = irdaClient.DiscoverDevices(n);

           

      if( deviceList.Length > 0 )

            for( int i = 0; i < deviceList.Length; i++ )

                  listBox.Items.Add( deviceList[i].DeviceName );

      else

            listBox.Items.Add( "Nie znaleziono urządzeń." );

                       

            W przedstawionym fragmencie programu stworzony został obiekt typu IrDAClient i wykorzystana jedna z jego metod DiscoverDevices. Metoda ta wykonuje całą potrzebną robotę, tzn. zwraca informacje o znalezionych urządzeniach w postaci wspomnianego już wcześniej obiektu IrDADeviceInfo. Jednym z parametrów konstruktora jest liczba określająca maksymalną ilość urządzeń, o których chcemy uzyskać informacje. Następnie, jeśli jakiekolwiek urządzenia zostały znalezione, to program wyświetla ich nazwy. Korzystamy tu z własności DeviceName klasy IrDADeviceInfo. Inne przydatne własności to DeviceID podający identyfikator urządzenia i Hints podający rodzaj urządzenia.

           

 

         Wymiana danych

           

            Dla samego wyszukiwania urządzeń nie znajdziemy wielu zastosowań, dlatego też dalsza część artykułu traktować będzie o bardziej użytecznych funkcjach umożliwiających wymianę informacji między urządzeniami. Następne dwa przykłady demonstrują wysyłanie i odbieranie danych przez port podczerwieni.

 

Wysyłanie danych

 

[Kod C#]

      IrDAClient irdaClient = new IrDAClient();

      IrDADeviceInfo [] deviceList = irdaClient.DiscoverDevices(1);

           

      if(deviceList.Length > 0)

      {

            try

            { 

                  IrDAEndPoint endPoint = new IrDAEndPoint(deviceList[0].DeviceID, "IrDAConnection");

                  irdaClient.Connect(endPoint);

            }

            catch (Exception ex)

            { 

                  MessageBox.Show(ex.Message.ToString());

            }

                                   

            Stream irdaStream = irdaClient.GetStream();

            byte [] bytes = ASCIIEncoding.ASCII.GetBytes(“Hello world!”);

            irdaStream.Write(bytes,0,bytes.Length);

 

            irdaStream.Close();

      }

      irdaClient.Close();

            

            Początek kodu jest już znany. Wyszukujemy urządzenie, z którym chcemy się połączyć. Tym razem wystarczy jedno takie urządzenia. Jeśli udało się je znaleźć, tworzymy obiekt IrDAEndPoint reprezentujący adres z którym chcemy się połączyć. Adres tworzymy na podstawie dwóch parametrów, przekazywanych w konstruktorze do obiektu: identyfikatora urządzenie docelowego DeviceID i nazwy usługi. Nazwa usługi może być dowolna, ale powinna być taka sama w obydwu urządzeniach, które chcemy ze sobą skomunikować. W przykładzie użyto nazwy „IrDAConnection”. Tą samą nazwę wykorzystamy w przykładzie, demonstrującym odbieranie danych. Następna linijka kodu to wywołanie metody Connect, która tworzy połączenie do podanego adresu. Mamy teraz już wszystko przygotowane do przesyłania danych. Wysyłając dane przez port IrDA postępujemy podobnie jakbyśmy chcieli zapisać je do pliku – wysyłamy je do strumienia. Taki strumień udostępnia metoda GetStream klasy IrDAClient. Ostatnią rzeczą, o którą musimy zadbać jest zamiana danych na tablicę bajtów, ponieważ tylko w takiej formie możemy przekazać je metodzie Write klasy Stream. Zrobi to za nas klasa ASCIIEncoding. Nawiązując do historii programowania, jako przykładowe dane do wysłania wykorzystamy ciąg znaków postaci „Hello world!”. Określamy jeszcze dwa pozostałe parametry metody Write, indeks tablicy, od którego zaczynamy wysyłanie danych oraz liczbę bajtów do wysłania.

Warto pamiętać, że chcąc nawiązać połączenie z innym urządzeniem nie musimy uprzednio wyszukiwać tego urządzenia. Możemy wywołać przeciążoną metodę Connect z parametrem określającym tylko nazwę usługi. Wtedy metoda ta sama wyszukuje urządzenia i łączy się z pierwszym, na które napotka. Sposób wykorzystany w przykładzie daje nam jednak większą kontrolę, pozwalając na połączenie się z określonym przez nas urządzeniem.

 

Odbieranie danych

             

[Kod C#]
 

      IrDAClient irdaClient = new IrDAClient();

      IrDADeviceInfo [] deviceList = irdaClient.DiscoverDevices(2);

      if(deviceList.Length > 0)

      {

            IrDAEndPoint endPoint = new IrDAEndPoint(deviceList[0].DeviceID, "IrDAConnection");

            IrDAListener irdaListener = new IrDAListener(endPoint);

            irdaListener.Start();

            irdaClient = irdaListener.AcceptIrDAClient();

            Stream irdaStream = irdaClient.GetStream();

            byte [] bytes = new byte[200];

                       

            irdaStream.Read(bytes,0,bytes.Length);

            listBox.Items.Add(ASCIIEncoding.ASCII.GetString(bytes, 0, bytes.Length));

                       

            irdaStream.Close();

            irdaListener.Stop();

                                   

      }

      irdaClient.Close();

 

Następnie odbieramy wysłane powitanie. Początek przykładu jest identyczny. Wyszukujemy urządzenie i tworzymy adres (IrDAEndPoint). Następnie zamiast obiektu IrDACllient tworzymy obiekt klasy IrDAListener. Obiekt ten po uruchomieniu metodą Start będzie czekał na próbę połączenia. Jeśli taka nastąpi, to w następnej linijce kodu, za pomocą metody AcceptIrDAClient, zostanie utworzony obiekt IrDAClient. Teraz już możemy postępować podobnie jak w poprzednim przykładzie, tzn. uzyskać dostęp do strumienia metodą GetStream, i odczytać z niego przesłane dane metodą Read. W przykładzie dane zostają zapisane w utworzonej tablicy bajtów bytes, a następnie przekształcone do zmiennej typu string (tutaj znów wykorzystujemy klasę ASCIIEncoding) i wyświetlone w kontrolce listBox. Dwa pozostałe parametry metody Read strumienia są analogiczne do parametrów metody Write: określają indeks tablicy, od którego zaczynamy i maksymalną ilość bajtów do zapisania.

W ten sposób przesłaliśmy i odebraliśmy dane poprzez port podczerwieni IrDA. Wykorzystując gotowe klasy nie jest to wcale skomplikowane i jak widać nie wymaga pisania wielu linii kodu. 

Przyjrzyjmy się jeszcze jednej rzeczy. Teraz udało się przesłać dane pomiędzy dwoma programami napisanymi przez nas w środowisku Windows. O ile można założyć, że wszystkie programy windowsowe powinny się komunikować bez przeszkód, to czy uda nam się nawiązać połączenie z urządzeniem, które Windows nie obsługuje? Jeśli urządzenie docelowe ma zaimplementowaną obsługę protokołu IrDA to powinno nam się to udać. Sprawdzimy to poniżej próbując wyciągnąć parę informacji z telefonu komórkowego.

  

 

Wymiana danych z innymi urządzeniami

 

Postaramy się teraz połączyć z telefonem komórkowym i uzyskać od niego nazwę jego producenta. Posłużymy się w tym celu komendami - AT.  Szczegółowe informacje na ten temat można znaleźć w Internecie. Nie będę ich opisywał, ale przytoczę parę przykładów.

 

Przykładowe AT Commands:

            AT – komenda sprawdzająca komunikacje z telefonem

AT+CGMI – żądanie informacji o producencie   

AT+CGMM – zażądaj informacje o modelu telefonu

ATD – komenda wybierania numer

 

            Każda komenda wysyłana przez port IrDA do telefonu musi kończyć się znacznikiem ‘\r’. Jeśli telefon ją poprawnie zinterpretuje to odeśle jej wynik i potwierdzi go komunikatem ‘OK’, w przeciwnym przypadku wyśle komunikat o błędzie ‘ERROR’. Dane odsyłane przez telefon są również odpowiednio sformatowane - zaczynają się i kończą ciągiem ‘\r\n’.

            Mój pierwszy program komunikujący się z telefonem komórkowym wykorzystywał do obsługi portu IrDA darmową bibliotekę znalezioną na stronie www.opencfnet.org. Program działał świetnie, poprawnie wysyłał komendy i przyjmował odpowiedzi. Przed napisaniem artykułu przepisałem ten program jeszcze raz, tym razem używając klas z .NET Compact Framework. Niestety, nowy program na początku nie działał. Okazało się, że występuje różnica w danych wychodzących z portu IrDA wysłanych z wykorzystaniem klas .NET i wspomnianych darmowych klas. Klasy z bibliotek OpenNETCF dodają do wysyłanych danych jeden, początkowy, zerowy bajt. Klasy .NET tego nie robią. Weźmiemy to pod uwagę w poniższym przykładzie.

  

[Kod C#]

IrDAClient irdaClient = new IrDAClient();

IrDADeviceInfo [] deviceList = irdaClient.DiscoverDevices(2);

if(deviceList.Length > 0)

{

      IrDAEndPoint endPoint = new IrDAEndPoint(deviceList[0].DeviceID, "IrDA:IrCOMM");

      irdaClient.Connect(endPoint);

      Stream irdaStream = irdaClient.GetStream();

  

      //tworzymy komendę

      byte [] komenda = new byte[9];

      komenda[0] = 0;

      komenda[1] = (byte)'A';

      komenda[2] = (byte)'T';

      komenda[3] = (byte)'+';

      komenda[4] = (byte)'C';

      komenda[5] = (byte)'G';

      komenda[6] = (byte)'M';

      komenda[7] = (byte)'I';

      komenda[8] = (byte)'\r';

                                             

      irdaStream.Write(komenda,0,komenda.Length);

      irdaStream.Flush();

          

      byte [] bytes = new byte[200];

      string str;

 

      do

      {

            irdaStream.Read(bytes,0,bytes.Length);

            str = ASCIIEncoding.ASCII.GetString(bytes, 1, bytes.Length-1);                

            listBox.Items.Add(str);

      }while(str.IndexOf("OK") == -1 && str.IndexOf("ERROR") == -1);                              

irdaStream.Close();

}

irdaClient.Close();

 

W tym przykładzie również zaczynamy od wyszukania urządzenia, połączenia się z nim i uzyskania dostępu do strumienia. Jedyną różnicą jest nazwa usługi, z którą się łączymy. W przykładzie używamy „IrDA:IrCOMM”. Jest to usługa działająca w telefonach komórkowych, używająca protokołu IrCOMM do komunikacji przez port podczerwieni. Następnie tworzymy komendę składającą się z pierwszego bajtu zerowego (wspominałem o tym wcześniej), treści komendy i znacznika końca, i wysyłamy ją do strumienia. Telefon odpowie prawie natychmiast, więc czyścimy strumień metodą Flush i od razu przystępujemy do czytania odpowiedzi. Odczytywanie odpowiedzi realizowane jest w pętli, w której pobierane są kolejne linie ze strumienia aż do momentu wczytania linii zawierającej słowo kończące ‘OK’ lub ‘ERROR’. Odczytane linie wpisywane są do kontrolki listBox. Zamianą bajtów na typ string zajmuje się tak jak w poprzednich przykładach klasa ASCIEncoding, z tą różnicą, że czytanie tablicy rozpoczynamy od 2 elementu (elementu o indeksie 1), aby pominąć zerowy bajt występujący na początku. Poprawna odpowiedź powinna zawierać powtórzoną komendę, nazwę producenta telefonu i powinna być potwierdzona słowem ‘OK’.

Powyższy przykład można zmodyfikować w taki sposób, aby program usuwał znaczniki początku i końca odebranej odpowiedzi przed wpisaniem jej do kontrolki listBox. Spowoduje to większą czytelność komunikatów, ale nie ma istotnego znaczenia dla głównego tematu tego artykułu, dlatego w zamieszczonym przykładzie zostało pominięte.

 

 

Podsumowanie

 

W artykule opisałem komunikacje z wykorzystaniem portów IrDA w środowisku Visual Studio .NET. Wykorzystałem klasy dostępne w Compact Framework 1.1 i pokazałem jak przy ich pomocy napisać programy przekazujące informacje między portami IrDA obsługiwanymi przez MS Windows, oraz komunikujące się z telefonem komórkowym.

           

W załączniku znajduje się program demonstrujący wykorzystane w artykule przykłady.

 

 

Odnośniki:

Microsoft – IrDA

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/irda/irda/irda_start_page.asp

Microsoft – Przykład aplikacji wykorzystującej komunikację poprzez IrDA

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_evtuv/html/etsamTicTacToeSample.asp

Microsoft – IrDA QuickStart Tutorial

http://samples.gotdotnet.com/quickstart/CompactFramework/doc/irdafiletransfer.aspx

OpenNETCF

http://www.opennetcf.org/

           

Załączniki:

Podobne artykuły

Komentarze 2

jedrekwie
jedrekwie
5 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Ciekawe zagadnienie, pokazane w sposob jasny i zrozumialy. Momentami przegadane (mam tu na mysli zbedne wyjasnianie znaczenia argmunetow wywolania metod, ktore wszyscy znaja).

Ogolne wrazenie -->  +
User 112468
User 112468
0 pkt.
Nowicjusz
21-01-2010
oceń pozytywnie 0
Witam

Artykuł bardzo przejrzysty i klarowny, ale jest malutka literówka w nazwach klas które są używane do sworzenia tej aplikacji. Mianowicie chodzi o System.Net.Sockets a nie System.Net.Socket :-) Generalnie oceniam bardzo pozytywnie :-)
pkt.

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.