Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Bluetooth Serial no Raspberry Pi 2 com Windows 10 IoT Core: Guia Completo

Componentes e Materiais

Componente Quantidade
Raspberry Pi 2 Model B 1
Dongle Bluetooth USB Genérico 1
Arduino UNO 1
Módem Bluetooth SparkFun BlueSMiRF Silver 1

Aplicativos e Serviços Online

Sobre o Projeto

Mais Detalhes

Este projeto é discutido em detalhes no embedded101.com: "Win 10 IoT-Core: Bluetooth Universal Windows Serial App".

Sobre

Este projeto é um Universal Windows App que conecta um dispositivo IoT Core (como Raspberry Pi 2) a um dispositivo Bluetooth embarcado via Bluetooth Serial Profile, usando um dongle Bluetooth USB genérico.

Contexto

O Bluetooth suporta rede peer-to-peer de curto alcance. Diferente de Wi-Fi, a conectividade Bluetooth é um-para-um. Dois dispositivos podem conectar e interagir. Por exemplo, dois dispositivos podem conectar de forma simétrica usando o perfil serial e trocar dados brutos. Geralmente, porém, a conectividade Bluetooth é assimétrica: uma ponta gera um formato de dados específico para ser consumido na outra. Exemplo: um celular implementa o perfil A2DP (Advanced Audio Distribution Profile) e transmite áudio para um headset que implementa o perfil HSP (Headset Profile). OBEX (Object Exchange) é uma conexão simétrica entre dois dispositivos que trocam dados entre si.

O projeto de exemplo Bluetooth da Microsoft para IoT Core usa o perfil GATT (Generic Attribute Profile), que fornece serviços de descoberta e descrição para o protocolo Bluetooth Low Energy. Com esse protocolo, dispositivos simples de baixa potência podem ser conectados em uma ponta gerando dados para serem consumidos por um processador complexo.

Este projeto é muito mais simples que o exemplo da Microsoft. Ele se preocupa apenas com o SPP (Serial Port Profile), baseado no perfil RFCOMM. Foi desenvolvido com um dongle Bluetooth USB muito antigo e deve funcionar com qualquer dongle Bluetooth.

O App IoT

Este app é um simples app de teste Bluetooth Serial Universal Windows (Windows 10). Ele começa enumerando (como lista) todos os dispositivos Bluetooth pareados ao dispositivo onde o app roda. Um é selecionado com duplo clique, iniciando a conexão. Texto a enviar é digitado em uma TextBox e enviado ao pressionar um botão. O app recebe automaticamente qualquer texto enviado a ele (e o exibe). Portanto, quando o endpoint (como acima) simplesmente ecoa o texto recebido, o texto enviado deve reaparecer na caixa de recepção no app UW.

Bluetooth Serial no Raspberry Pi 2 com Windows 10 IoT Core: Guia Completo

O Endpoint

Para teste, usa-se um Arduino Uno com adaptador Bluetooth. Ele tem um shield simples que ecoa de volta qualquer caractere recebido via Bluetooth:

Configuração do Shield:

// App serial loop back
// Após setup
// Iniciado pelo sistema conectado
// Pode ser usado com Bluetooth onde RxTx do dispositivo BT
// estão conectados ao TxRx da placa Arduino.
// Precisa desconectar adaptador BT para programar.
void setup() {
  // Meu adaptador está configurado para este BAUD 115200
  // Esta é a taxa da porta Arduino para adaptador BT
  // Definida quando adaptador BT está em modo comando.
  // NÃO é a taxa BT que não pode ser definida.
  Serial.begin(115200);
  delay(333);
  while (!Serial) ;
  delay(1000);
  Serial.println("The quick brown fox jumps over the lazy dog!");
}

Loop do Shield:

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

Pareamento

Bluetooth é um cenário peer-to-peer. Antes de conectar via Bluetooth, os dispositivos devem ser pareados. Isso não é feito dentro do app. Pareamento com chave de acesso pode ser problemático entre dispositivos embarcados, pois são frequentemente headless e podem não suportar popups (como o IoT Core não suporta). Existe um portal web IoT Core para isso, bem como um utilitário de linha de comando no dispositivo que pode rodar via shell SSH. A versão mais recente do portal web do OS suporta pareamento com chave de acesso, que faltava na época do Windows 10 RTM. O artigo "Win 10 IoT-Core: Bluetooth Universal Windows Serial App" discute pareamento neste contexto em detalhes.

Iniciando o Projeto

O projeto do app é criado no Visual Studio 2015 usando o template Universal Windows App:

Novo Projeto → Visual C# → Windows → Blank App (Universal Windows)

Criando a UI do App

A UI é implementada em XAML. Crie a UI conforme o layout acima (ou similar):

Você pode preferir layout com Relative StackPanels ou Grid rows/columns.

O ConnectDevices é um ListBox com Binding Source definido para PairedDevices (ver depois) e ItemTemplate consistindo de um TextBlock vinculado à propriedade Name de PairedDevices (ver depois).

<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>

Configuração do App

Modifique a seção Capabilities (no final) para:

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

A capability internetClient já estará lá. Não é necessária para este app, então você pode removê-la. Eu deixo.

Informações do PairedDevice

No início do app, os dispositivos pareados são enumerados usando:

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

Esta coleção é transformada em um ObservableCollection para uso no ListBox:

_pairedDevices = new ObservableCollection<PairedDeviceInfo>();

A DeviceInfoCollection é iterada criando um objeto PairedDeviceInfo para cada item, adicionado à coleção _pairedDevices.

PairedDeviceInfo é uma classe com propriedades:

Name <string>
Id <string>
DeviceInfo <DeviceInformation>

A classe tem construtor apropriado.

DeviceInformation é Windows.Devices.Enumeration.DeviceInformation.

No listbox de dispositivos pareados, o campo Name é exibido (via binding).

Quando um dispositivo é selecionado (duplo clique), o DeviceInformation do endpoint faz parte do item de menu selecionado e é usado para estabelecer a conexão.

Conexão

O DeviceInformation é usado para obter o serviço RFCOMM. A conexão é estabelecida como StreamSocket usando o HostName do Endpoint (na verdade seu endereço MAC Bluetooth) e a string ServiceName.

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

Se tudo correr bem, temos uma conexão — o socket será válido (não nulo). Claro, isso tem tratamento de erro (try-catch). Envio e recebimento de texto usam as propriedades InputStream e OutputStream do socket.

Receber Texto

O recebimento deve ser iniciado primeiro, pois roda em thread separada. Executa um await assíncrono para obter entrada serial, processa a entrada e executa outro receive assíncrono — tudo em loop. Este loop continua até uma cancelamento ser gerado.

private async void Listen() {
  ReadCancellationTokenSource = new CancellationTokenSource();
  if (_socket.InputStream != null) {
    dataReaderObject = new DataReader(_socket.InputStream);
    // continua lendo entrada serial
    while (true) {
      await ReadAsync(ReadCancellationTokenSource.Token);
    }
  }
}
DataReader dataReaderObject;
private CancellationTokenSource ReadCancellationTokenSource;
private async Task ReadAsync(CancellationToken cancellationToken) {
  uint ReadBufferLength = 1024;
  // Se cancelamento solicitado, atende
  cancellationToken.ThrowIfCancellationRequested();
  // Define InputStreamOptions para completar leitura assíncrona quando um ou mais bytes disponíveis
  dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
  // Cria task para aguardar dados no serialPort.InputStream
  loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
  // Inicia task e aguarda
  UInt32 bytesRead = await loadAsyncTask;
  if (bytesRead > 0) {
    string recvdtxt = dataReaderObject.ReadString(bytesRead);
  }
}

Enviar Texto

Enquanto o texto recebido é assíncrono (chegada não determinística), o envio é acionado pela UI do app e é essencialmente síncrono (embora use await para liberar a UI).

private async void Send(string msg) {
  Task storeAsyncTask;
  DataWriter dataWriteObject = new DataWriter(_socket.OutputStream);
  dataWriteObject.WriteString(msg);
  // Inicia task assíncrona para completar operação de escrita
  storeAsyncTask = dataWriteObject.StoreAsync().AsTask();
  UInt32 bytesWritten = await storeAsyncTask;
}

Estados dos Botões

Os botões de comando são habilitados/desabilitados conforme o estado do app. Exemplo: botões Send e Start Recv desabilitados quando não conectado, habilitados quando conectado, etc.

Aproveite! :)

Processo de manufatura

  1. Estendendo GoPiGo v2 no Windows 10 IoT Core para Raspberry Pi 3
  2. Controle de Brilho de LED com PWM via Botão no Arduino Mega
  3. Dispositivo de Precisão para Medição de Pressão e Fluxo de Ar com Sensor Analógico
  4. Construa um Jogo em Tempo Real com Giroscópio: Arduino Nano + Sensor MPU-6050
  5. Câmera de Segurança com Detecção de Movimento ESP32-CAM para Discord
  6. Projeto DHT11: Sensor Temperatura/Umidade com LEDs Indicadores e Buzzer
  7. Unopad: Controlador MIDI Arduino Perfeito para Ableton Live
  8. Controle Remoto TV Personalizado com Arduino – Bateria e Gabinete 3D
  9. Controlar um LED via Bluetooth com Arduino – Guia DIY Simples
  10. Construa um Sensor de Obstáculos Simples com Arduino – Tutorial Fácil com LED IR e Fotodiodo