Komunikácia cez Bluetooth

Windows 8.1 aplikácia môže pre prístup k zariadeniam cez Bluetooth používať nové API rozhrania API RFCOMM a GATT (Generic Attribute Profile). Tieto rozhrania dokážu komunikovať cez Bluetooth BR / EDR aj cez Bluetooth LE. Bluetooth zariadenia, či už klasické, alebo “smart” sa musia najskôr zistiť a spárovať cez rozhranie Nastavenie počítača (Počítače a zariadenie> Zariadenie> Pridať zariadenie) Až potom budú prístupné cez Bluetooth WinRT API.

Informácie o svojom zariadení, alebo o všeobecnej triede zariadení musíte pridať do aplikačného manifestu napríklad pre ľubovoľné zariadenie podporujúce RFCOMM:

<Capabilities>

<m2:DeviceCapability Name=”bluetooth.rfcomm”>

<m2:Device Id=”any”>

<m2:Function Type=”name:serialPort” />

</m2:Device>

</m2:DeviceCapability>

</Capabilities>

 

Pre overenie komunikácie si môžete napísať jednoduchú aplikáciu, ktorá bude prijímať dáta z externého zariadenia, napríklad Bluetooth GPS, prípadne Bluetooth modulu pripojeného k vašej hobby konštrukcii na báze mikrokontroléru. Pod názvom Bluetooth analyzer je dostupná vo Windows store http://apps.microsoft.com/windows/app/bluetooth-analyzer/e632b14b-268e-458b-99ee-7a6b858a72be

V príklade popisujem používateľské rozhranie triviálneho, ale funkčného príkladu, ktorý prijíma bajty z RFCOMM cez Bluetooth pozostáva z dvoch prvkov – ComboBoxu pre výber zariadenia a prvku TextBlock pre výpis prijatých znakov.

<StackPanel Orientation=”Vertical” Margin=”120,10,0,0″ Grid.Row=”1″>

<ComboBox x:Name=”cbZariadenia” Header=”Bluetooth RF comm zariadenia”

PlaceholderText=”Vyber zariadenie…” ItemsSource=”{Binding}”

HorizontalAlignment=”Left” VerticalAlignment=”Top”

Width=”400″ Height=”70″

SelectionChanged=”cbZariadenia_SelectionChanged” />

<TextBlock x:Name=”tbStatus” Text=”čakám na výber zariadenia”

FontSize=”24″ Width=”400″ Height=”40″ HorizontalAlignment=”Left”/>

<ScrollViewer x:Name=”scrollViewer” Height=”300″ Width=”600″

HorizontalAlignment=”Left”>

<TextBlock x:Name=” tbBajty” TextWrapping=”Wrap” />

</ScrollViewer>

</StackPanel>

 

Fungovanie objasnia fragmenty kódu Procedúra BtInit sa volá v metóde LoadState. Úlohou metódy je získať informácie o pripojených Bluetooth zariadeniach podporujúcich RFCOMM.

private StreamSocket _socket = new StreamSocket();

private string _buffer = string.Empty;

 

public List<cZariadenia> lZariadenia = new List<cZariadenia>();

public List<string> lNazvyZariadeni = new List<string>();

 

private async void BtInit()

{

Windows.Devices.Enumeration.DeviceInformationCollection zariadenia

= await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync( RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));

 

foreach (var zar in zariadenia)

{

cZariadenia zz = new cZariadenia();

zz.id = zar.Id;

zz.name = zar.Name;

lZariadenia.Add(zz);

string ss = zz.name;

lNazvyZariadeni.Add(ss);

}

cbZariadenia.DataContext = lNazvyZariadeni;

}

 

Samozrejme, dal by sa napojiť ComboBox priamo na zoznam zariadení, osobitný zoznam názvov bol zavedený z dôvodu možnosti neskoršej konverzie technokratických názvov na používateľské.

Výber zariadenia, ktoré chcete použiť a inicializovat je v obsluhe udalosti SelectionChanged. Samotná inicializácia je v metóde InitBtDevice().

private void cbZariadenia_SelectionChanged(object sender,

SelectionChangedEventArgs e)

{

string sNazov;

string sID = “”;

ComboBox cb = (ComboBox)sender;

if (cb.SelectedItem != null)

{

sNazov = cb.SelectedItem.ToString();

 

//najdem id

foreach (cZariadenia oo in lZariadenia)

{

if (oo.name == sNazov) sID = oo.id;

}

 

//ak som nasiel vybrane zariadenie inicializujem

if (sID.Length > 1) InitBtDevice(sID);

}

}

 

private async void InitBtDevice(string sID)

{

RfcommDeviceService service = await RfcommDeviceService.FromIdAsync(sID);

_socket.Control.KeepAlive = true;

_socket.Control.NoDelay = true;

await _socket.ConnectAsync(service.ConnectionHostName,

service.ConnectionServiceName);

await WaitForData(_socket);

}

 

V asynchrónnej procedúre, ktorá prijíma dáta môžete v cvičnom príklade použiť aj rekurzívne volanie procedúry aby sa po prijatí znaku čakalo na ďalší znak.

 

async private Task WaitForData(StreamSocket socket)

{

try

{

byte[] bytes = new byte[1];

await socket.InputStream.ReadAsync(bytes.AsBuffer(), 1,

InputStreamOptions.Partial);

string str = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);

_buffer += str;

tbBajty.Text = _buffer;

}

catch (Exception e){}

finally

{

WaitForData(socket);

}

}

 

Predchádzajúca procedúra síce funguje, ale oveľa lepšie riešenie je čakanie na udalosť ktorú vyvolá prijatie znaku. V druhom príklade ukážeme inicializáciu komunikácie využívajúcej sockety. V reálnej aplikácii by ste samozrejme použili konštrukciu Try…catch

private async void ConnectToServiceAsync(IUICommand command)

{

DeviceInformation serviceInfo = (DeviceInformation)command.Id;

this.State = BluetoothConnectionState.Connecting;

connectService = RfcommDeviceService.FromIdAsync(serviceInfo.Id);

rfcommService = await connectService;

if (rfcommService != null)

{

//Vytvorenie socketu

socket = new StreamSocket();

connectAction = socket.ConnectAsync(rfcommService.ConnectionHostName,

rfcommService.ConnectionServiceName );

await connectAction;

writer = new DataWriter(socket.OutputStream);

reader = new DataReader(socket.InputStream);

Task listen = ListenForMessagesAsync();

this.State = BluetoothConnectionState.Connected;

tbStatus.Text = “Connection succesfull”;

}

}

 

Procedúra čakajúca na znaky:

private async Task ListenForMessagesAsync()

{

while (reader != null)

{

uint sizeFieldCount = await reader.LoadAsync(1);

//socket zatvoreny skor nez sa nacitali data

if (sizeFieldCount != 1) return;

byte[] bytes = new byte[1];

reader.ReadBytes(bytes);

string str = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);

tbBajty.Text += str;

}

}

Do mozaiky skladačky použiteľnej aplikácie chýba už len procedúra na vyslanie znaku.

public async Task<uint> SendMessageAsync(string message)

{

uint sentMessageSize = 0;

if (writer != null)

{

uint messageSize = writer.MeasureString(message);

writer.WriteByte((byte)messageSize);

sentMessageSize = writer.WriteString(message);

await writer.StoreAsync();

}

return sentMessageSize;

}

Bluetooth1.png

Obrázek 8.x: Príklad používateľského rozhrania aplikácie na monitorovanie sériovej komunikácie cez Bluetooth RFCOMM. Pripojené je externé GPS zariadenie

Reklamy

Pridaj komentár

Zadajte svoje údaje, alebo kliknite na ikonu pre prihlásenie:

WordPress.com Logo

Na komentovanie používate váš WordPress.com účet. Odhlásiť sa / Zmeniť )

Twitter picture

Na komentovanie používate váš Twitter účet. Odhlásiť sa / Zmeniť )

Facebook photo

Na komentovanie používate váš Facebook účet. Odhlásiť sa / Zmeniť )

Google+ photo

Na komentovanie používate váš Google+ účet. Odhlásiť sa / Zmeniť )

Connecting to %s


%d bloggers like this: