Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Bluetooth Serial Sin Problemas en Raspberry Pi 2 con Windows 10 IoT Core

Componentes y suministros

Raspberry Pi 2 Model B×1
Adaptador USB Bluetooth genérico×1
Arduino UNO×1
Módem Bluetooth SparkFun BlueSMiRF Silver×1

Aplicaciones y servicios en línea

Sobre el proyecto

Este proyecto se detalla en embedded101.com: "Win 10 IoT-Core: Bluetooth Universal Windows Serial App".

Acerca de

Es una app Universal Windows que conecta un dispositivo IoT Core (Raspberry Pi 2) a un dispositivo Bluetooth embebido mediante el Perfil de Puerto Serial (SPP) usando un adaptador USB Bluetooth genérico.

Contexto

Bluetooth permite redes punto a punto a corto alcance. A diferencia de Wi-Fi, la conexión es uno a uno. Dos dispositivos pueden conectarse de forma simétrica (perfil serial, intercambio de datos raw) o asimétrica (un extremo genera formato específico para el otro). Ejemplos: A2DP para audio, HSP para auriculares, OBEX para intercambio de objetos.

El ejemplo oficial de Microsoft usa GATT (Generic Attribute Profile) para Bluetooth Low Energy. Este proyecto es mucho más simple: solo usa SPP (Serial Port Profile) basado en RFCOMM. Fue desarrollado con un adaptador USB Bluetooth muy antiguo, por lo que debería funcionar con cualquier adaptador.

La app IoT

App de prueba Bluetooth Serial Universal Windows (Windows 10). Al iniciar, enumera (lista) todos los dispositivos Bluetooth emparejados. Seleccionas uno con doble clic para iniciar conexión. Escribes texto en un TextBox y lo envías con un botón. La app recibe automáticamente cualquier texto entrante y lo muestra. Si el extremo remoto hace eco, el texto enviado reaparece en la caja de recepción.

Bluetooth Serial Sin Problemas en Raspberry Pi 2 con Windows 10 IoT Core

El extremo remoto (Endpoint)

Para pruebas se usa un Arduino UNO con adaptador Bluetooth. Un sketch simple hace eco de lo que recibe por Bluetooth:

Configuración del Shield (Setup)

// Aplicación serial loopback
// Iniciada por sistema conectado
// Nota: usable con Bluetooth donde Rx/Tx del BT van a Tx/Rx del Arduino
// Desconectar adaptador BT para programar.
void setup() {
  // Mi adaptador está a 115200 baudios (puerto Arduino-BT)
  // Se configura en modo comando del adaptador. NO es la tasa BT.
  Serial.begin(115200);
  delay(333);
  while (!Serial) ;
  delay(1000);
  Serial.println("The quick brown fox jumps over the lazy dog!");
}

Bucle del Shield (Loop)

void loop() {
  char ch = Serial.read();
  while (255 == (byte)ch) { ch = Serial.read(); }
  Serial.print(ch);
}

Emparejamiento (Pairing)

Bluetooth es punto a punto: antes de conectar deben emparejarse. No se hace dentro de la app. El emparejamiento con clave puede ser problemático entre dispositivos embebidos (a menudo sin interfaz, IoT Core no soporta popups). Existe un portal web de IoT Core y una utilidad de línea de comandos en el dispositivo (vía SSH). La versión más reciente del portal web soporta emparejamiento con clave (faltaba en Windows 10 RTM). El artículo mencionado lo explica en detalle.

Iniciar el proyecto

En Visual Studio 2015: Nuevo Proyecto → Visual C# → Windows → Aplicación en blanco (Universal Windows).

Crear la UI de la app

La UI se implementa en XAML. Es bastante directa:

El ListBox ConnectDevices tiene ItemsSource enlazado a PairedDevices y ItemTemplate con TextBlock enlazado a la propiedad Name:

<ListBox x:Name="ConnectDevices" ItemsSource="{Binding Source={StaticResource PairedDevices}}" Margin="10" DoubleTapped="ConnectDevices_DoubleTapped" Width="Auto" Height="Auto">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Name}" />
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

Configuración de la app

Modifica la sección Capabilities al final:

<Capabilities>
  <Capability Name="internetClient" />
  <DeviceCapability Name="bluetooth.rfcomm">
    <Device Id="any">
      <Function Type="name:serialPort"/>
    </Device>
  </DeviceCapability>
</Capabilities>

La capacidad internetClient ya existe; no es necesaria para esta app, pero se puede dejar.

Información de dispositivos emparejados (PairedDevice)

Al iniciar, se enumeran los dispositivos emparejados:

DeviceInformationCollection DeviceInfoCollection
  = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));

Esta colección se convierte en ObservableCollection para el ListBox:

_pairedDevices = new ObservableCollection<PairedDeviceInfo>();

Se itera DeviceInfoCollection creando objetos PairedDeviceInfo que se añaden a _pairedDevices.

PairedDeviceInfo tiene propiedades: Name (string), Id (string), DeviceInfo (DeviceInformation).

En el ListBox se muestra el campo Name. Al seleccionar (doble clic), el DeviceInformation del extremo forma parte del item seleccionado y se usa para la conexión.

Conexión

Se obtiene el servicio RFCOMM del DeviceInformation. La conexión se establece como StreamSocket usando el HostName del extremo (dirección MAC Bluetooth) y el string ServiceName:

_service = await RfcommDeviceService.FromIdAsync(DeviceInfo.Id);
_socket = new StreamSocket();
await _socket.ConnectAsync(_service.ConnectionHostName, _service.ConnectionServiceName);

Si todo va bien, el socket es válido (no nulo). Manejo de errores con try-catch. Envío y recepción usan InputStream y OutputStream del socket.

Recepción de texto

La recepción debe iniciarse primero (hilo separado). Hace async wait para entrada serial, procesa y repite en bucle hasta cancelación:

private async void Listen() {
  ReadCancellationTokenSource = new CancellationTokenSource();
  if (_socket.InputStream != null) {
    dataReaderObject = new DataReader(_socket.InputStream);
    while (true) {
      await ReadAsync(ReadCancellationTokenSource.Token);
    }
  }
}
DataReader dataReaderObject;
private CancellationTokenSource ReadCancellationTokenSource;
private async Task ReadAsync(CancellationToken cancellationToken) {
  uint ReadBufferLength = 1024;
  cancellationToken.ThrowIfCancellationRequested();
  dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
  var loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
  UInt32 bytesRead = await loadAsyncTask;
  if (bytesRead > 0) {
    string recvdtxt = dataReaderObject.ReadString(bytesRead);
  }
}

Envío de texto

El envío es accionado desde la UI, esencialmente sincrónico (aunque usa await para liberar la UI):

private async void Send(string msg) {
  Task storeAsyncTask;
  DataWriter dataWriteObject = new DataWriter(_socket.OutputStream);
  dataWriteObject.WriteString(msg);
  storeAsyncTask = dataWriteObject.StoreAsync().AsTask();
  UInt32 bytesWritten = await storeAsyncTask;
}

Estados de los botones

Los botones de comando se habilitan/deshabilitan según el estado de la app. Ejemplo: Send y Start Recv deshabilitados si no hay conexión, habilitados al conectar.

¡Disfruta! :)

Proceso de manufactura

  1. Extensión de GoPiGo v2 en Windows 10 IoT Core para Raspberry Pi 3
  2. Control de Brillo LED con PWM mediante Pulsador en Arduino Mega
  3. Dispositivo de Medición de Presión y Flujo de Aire de Precisión con Sensor Analógico
  4. Construye un Juego Giroscópico en Tiempo Real con Arduino Nano y Sensor MPU-6050
  5. Cámara de Seguridad con Detección de Movimiento ESP32 para Discord
  6. Proyecto Sensor DHT11 Temperatura y Humedad con Indicadores LED y Altavoz Piezo
  7. Unopad: Controlador MIDI Arduino para Ableton Live sin complicaciones
  8. Mando a Distancia TV Personalizado con Arduino UNO: Alimentado por Batería, Carcasa Impresa en 3D
  9. Controla un LED por Bluetooth con Arduino – Guía DIY paso a paso
  10. Sensor de obstáculos IR casero con Arduino – Tutorial fácil con LED IR y fotodiodo
  11. Electrodomésticos activados por voz: Control Bluetooth con Google Assistant