Sergii Baidachnyi

Blog about technologies

UWP: Working with Bluetooth (part 5: Bluetooth RFCOMM)

with one comment

Windows 10 API supports not just Bluetooth Low Energy devices, but allows you to utilize RFCOMM protocol as the most widespread since Bluetooth invention. Even if your module doesn’t support BLE, you always can use RFCOMM. As in the case of BLE Windows 10 allows you to publish RFCOMM services or work with other services as a client.

I decided to implement client only, and for a server I used a cheap Bluetooth module HC-06. It’s possible to buy the module for couple dollars and you can find lots of videos and examples about how to connect it to Arduino board. But you can use any available Bluetooth module. Just in case you can find a schema below:

clip_image002

My module wasn’t on a plate with a voltage regulator. So, I decided to add a voltage divider for TX->RX connection, because Arduino generate 5 volts there rather than 3.3 volts. If you have a module like on the schema above (with the regulator), you still can use the divider, and it will not break your circuit.

To communicate with the module from Arduino, you can simply use the serial port. So, I connected TX and RX pins on Arduino to RX and TX pins on the module. Additionally, I connected 3.3V and GRN on Arduino to VCC and GRN on the module.

I setup my module to use 115200 speed and changed the name of the module to rfcommhc06. You can do it connection the module to your computer using USB to Serial adapter and execute some AT commands (AT+NAMErfcommhc06 and AT+BAUD8).

Finally, I could implement a very simple code for Arduino:

void setup()
{
   Serial.begin(115200);
   pinMode(13,OUTPUT);
}
byte blue;
void loop()
{
   if(Serial.available())
   {
      blue=Serial.read();
      Serial.write(blue);
      if (blue==3)
      {
         digitalWrite(13,HIGH);
      }
      else if(blue==2)
      {
         digitalWrite(13,LOW);
      }
      Serial.write(blue);
   }
}

This code read data from serial port using infinity loop and one there is 3, it sends high voltage to pin number 13. In the case if 2 is in the stream, it sends low voltage to pin 13. Because pin 13 are connected with a LED on Arduino Uno boards, the led will switch status between on and off depends on input data. At the end of each iteration, I send all incoming data back.

If you finish your circuit and deploy the code successfully, it’s time to start developing a client for Windows 10.

The first part of our code will look similar to BLE example. We have to start watcher and declare handlers for Added and Removed events:

DeviceWatcher deviceWatcher;
DataWriter tx;
DataReader rx;
StreamSocket stream;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
   deviceWatcher = DeviceInformation.CreateWatcher(
      "System.ItemNameDisplay:~~\"rfcommhc\"",
      null,
      DeviceInformationKind.AssociationEndpoint);
   deviceWatcher.Added += DeviceWatcher_Added;
   deviceWatcher.Removed += DeviceWatcher_Removed;
   deviceWatcher.Start();
   base.OnNavigatedTo(e);
}

The DeviceWatcher_Added method will looks different compare to BLE example.

private async void DeviceWatcher_Added(DeviceWatcher sender,
   DeviceInformation args)
{
   var device = await BluetoothDevice.FromIdAsync(args.Id);
   var services = await device.GetRfcommServicesAsync();
   if (services.Services.Count>0)
   {
      var service = services.Services[0];
      stream = new StreamSocket();
      await stream.ConnectAsync(service.ConnectionHostName,
      service.ConnectionServiceName);
      rx = new DataReader(stream.InputStream);
      tx = new DataWriter(stream.OutputStream);
      await this.Dispatcher.RunAsync(
         Windows.UI.Core.CoreDispatcherPriority.Normal,
         () => { switchLed.IsEnabled = true; });
      deviceWatcher.Stop();
   }
}

First, we use the BluetoothDevice class rather than BluetoothLEDevice. Once we have a reference to the device, the GetRfcommServiceAsync method helps us to get list of all available services. Our Arduino code is very primitive and we have just one service. Once we have a reference to the service, we can use the StreamSocket class to establish a connection to the Bluetooth module and get references to input and output streams.

Finally, we can use DataReader and DataWriter classes to start working with the module like with a virtual serial port:

private async void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
{
   byte data = 2;
   if (switchLed.IsOn)
   {
      data = 3;
   }
   tx.WriteByte(data);
   await tx.StoreAsync();
   uint buf;
   buf = await rx.LoadAsync(1);
   var symbol = rx.ReadByte();
   Debug.WriteLine(data);
}

If you want to develop something more for Arduino and Windows 10, I would recommend to use Remote Wiring project (https://github.com/ms-iot/remote-wiring) that can help you control Arduino board using your own UWP application.

Written by Sergiy Baydachnyy

05/19/2017 at 10:58 PM

One Response

Subscribe to comments with RSS.

  1. I made a similar program to connect my app device to another device.
    I have an error occurs when I try await stream.ConnectAsync(service.ConnectionHostName, service.ConnectionServiceName)

    WinRT information: A socket operation was attempted to an unreachable network.

    Capabilities are setted like this :

    Do you see any solution of my issue ?

    Thanks

    Antoine

    09/28/2017 at 12:36 PM


Leave a comment