sábado, 25 de abril de 2020

WEB BLE CONVERSANDO COM NINA B302


O objetivo deste BLOG é mostrar que é possível hoje você utilizar o browser seu APP (Chrome) para conseguir ter acesso aos NINA via BLE e interagir. Foram realizados testes com o NINA B302 e NINA W102.

PS: Windows 7 não funciona!

O exemplo utilizado no NINA foi o BLESERIAL. Converse com o NINA B302 via BLE SERIAL e seu WEB APP


Adquirimos então os seguintes componentes



Montado ficou assim



O esquema elétrico é este



Algumas características do Kit

-Botão de RESET;
-Botão de Modo BOOTLOADER (W102);
-Plugável no PROTOBOARD;
-Acesso às várias GPIOS;

Pequena 


Abaixo o roteiro para você seguir:

Baixe e instale o Arduino IDE 
Inicie o Arduino IDE, vá em Preferências e adicione 

https://www.adafruit.com/package_adafruit_index.json



como "URL adicional do gerenciador de pastas"

Abra o Boards Manager no menu Tools -> Board e instale o "Adafruit nRF52 by Adafruit"

Selecione sua placa nRF5 no menu Ferramentas -> Placa

Adafruit Bluefruit nRF52 Feather





OBSERVAÇÃO: Durante a instalação, o Arduino IDE leva alguns minutos para extrair as ferramentas após o download, por favor, seja paciente.

Gravando bootloader da Adafruit

Use o gravador SEGGER JLINK para gravar o BREAKOUT com módulo NINA B302, conecte nos pinos do SWCLK (pino 7) e SWDIO (pino 9) do SEGGER JLINK nos pinos  SWDCLK e SWDIO do BREAKOUT (pinos nas laterais, próximo à antena). Não esquecer de ligar os GND do BREAKOUT no GND do SEGGER JTAG, bem como alimentar o BREAKOUT com 3.3V.



Ligue os pinos SWD DIO e CLK ...
...nestes pinos da placa BREAKOUT

Você pode também usar o ST-LINK V2



Abra J-FLASH lite e grave o bootloader da Adafruit




O mesmo se encontra em 

....\packages\adafruit\hardware\nrf52\0.19.0\bootloader\feather_nrf52840_express

Compile depois para o NINA B302
https://github.com/adafruit/Adafruit_nRF52_Bootloader

Com ele, você poderá transferir programas via DFU USB. Maiores detalhes sobre este bootloader

https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather/update-bootloader

Segundo a documentação, se você pressionar o reset, o módulo aguardará por um certo tempo se há algo sendo enviado pelo Arduino, ou seja, o programa a ser gravado via DFU.

ATENÇÃO, o bootloader usa USB para gravação do NINA 302, OU SEJA, CRIA UMA COMM VIRTUAL, TAMBÉM PARA SER A SERIAL PADRÃO DO ARDUINO

INSTALE OS DRIVERS
https://github.com/adafruit/Adafruit_Windows_Drivers

Conecte na USB + e USB - um cabo USB, AGUARDE INSTALAR OS DRIVERS



Futuramente altere arquivo variant.cpp para que as GPIOS sejam os mesmos do NINA B302, atualmente estão para o ADAFRUIT FEATHER EXPRESS.

variant.h
viariant.cpp

ÓTIMA REFERENCIA PARA PINOS DO ARDUINO E PINOS (GPIOS) DO NINA B302


Consulte

https://www.u-blox.com/sites/default/files/NINA-B3_DataSheet_%28UBX-17052099%29.pdf

Compilando e Transferindo o programa BLEUART

Compile o programa e pressione o botão para gravar.

Ao aparecer a mensagem "Upgrading target on COM...", pressione imediatamente o botão de reset do módulo NINA B302


Como podem observar, o programa será transferido!


LEIA O BLOG ABAIXO

Tradução do BLOG de FRANÇOIS BEAUFORT
https://developers.google.com/web/updates/2015/07/interact-with-ble-devices-on-the-web


Interaja com dispositivos Bluetooth na Web







E se eu disser a você que os sites podem se comunicar com dispositivos Bluetooth próximos de maneira segura e preservadora da privacidade? Dessa forma, monitores de freqüência cardíaca, lâmpadas cantantes, tartarugas e gatos mal-humorados voadores podem interagir diretamente com um site.
Até agora, a capacidade de interagir com dispositivos bluetooth era possível apenas para aplicativos nativos. A API da Web Bluetooth visa alterar isso e traz para os navegadores da Web também. Juntamente com esforços como o Physical Web , as pessoas podem acessar e interagir com dispositivos diretamente da Web. Confira este drone controlado por um vídeo de aplicativo da web para ter uma idéia de como isso funcionaria.

Antes de começarmos

Este artigo pressupõe que você tenha algum conhecimento básico de como o Bluetooth Low Energy (BLE) e o Generic Attribute Profile (GATT) funcionam.
Mesmo que a especificação da API Bluetooth da Web ainda não tenha sido finalizada, a Equipe do Chrome está procurando ativamente desenvolvedores entusiasmados (quero dizer, você) para experimentar esta API em andamento e dar feedback sobre as especificações e sobre a implementação .
Um subconjunto da API Bluetooth da Web está disponível no Chrome OS, Chrome para Android M, Mac (Chrome 56) e Windows 10 (Chrome 70). Isso significa que você poderá solicitar e conectar-se a dispositivos Bluetooth próximos, ler / gravar características de Bluetooth, receber notificações do GATT , saber quando um dispositivo Bluetooth é desconectado e até ler e gravar em descritores de Bluetooth .
Para versões anteriores do Windows e Linux, você ainda precisa acessar chrome://flags/#enable-experimental-web-platform-features, ativar o sinalizador destacado e reiniciar o Chrome por enquanto.

Disponível para testes de origem

Para obter o máximo de feedback possível dos desenvolvedores que usam a API Bluetooth da Web em campo, adicionamos anteriormente esse recurso no Chrome 53 como uma avaliação de origem para o Chrome OS, Android M e Mac.

Requisitos de segurança
Para entender as vantagens e desvantagens da segurança, recomendo a postagem do Modelo de segurança da Web Bluetooth de Jeffrey Yasskin, engenheiro de software da equipe do Chrome, trabalhando na especificação da API da Web Bluetooth.

Apenas HTTPS

Como essa API experimental é um recurso novo e poderoso adicionado à Web, o Google Chrome visa disponibilizá-la apenas para contextos seguros . Isso significa que você precisará criar com o TLS em mente.









Durante o desenvolvimento, você poderá interagir com o Bluetooth da Web por meio do http: // localhost usando ferramentas como o Chrome Dev Editor ou o prático python -m SimpleHTTPServer, mas para implantá-lo em um site, será necessário ter o HTTPS configurado no servidor. Pessoalmente, gosto das páginas do GitHub para fins de demonstração.
Para adicionar HTTPS ao seu servidor, você precisará obter um certificado TLS e configurá-lo. Verifique o artigo Segurança com HTTPS para obter as práticas recomendadas. Para obter informações, agora você pode obter certificados TLS gratuitos com a nova Autoridade de Certificação Vamos Criptografar .

Gesto de usuário necessário

Como um recurso de segurança, a descoberta de dispositivos Bluetooth com navigator.bluetooth.requestDevicedeve ser acionada por um gesto do usuário , como um toque ou um clique do mouse. Estamos falando de ouvir pointerupclicktouchendeventos.
button.addEventListener('pointerup', function(event) {
  // Call navigator.bluetooth.requestDevice
});

Entre no Código

A API da Web Bluetooth depende muito das promessas de JavaScript Se você não estiver familiarizado com eles, confira este ótimo tutorial de Promessas . Mais uma coisa, () => {}são simplesmente as funções de seta do ECMAScript 2015 - elas têm uma sintaxe mais curta em comparação às expressões de função e vinculam lexicamente o thisvalor.

Solicitar dispositivos Bluetooth

Esta versão da especificação da API Bluetooth da Web permite que sites em execução na função Central se conectem a servidores GATT remotos por uma conexão BLE. Ele suporta a comunicação entre dispositivos que implementam o Bluetooth 4.0 ou posterior.
Quando um site solicita acesso a dispositivos próximos usando navigator.bluetooth.requestDevice, o Google Chrome solicita ao usuário um seletor de dispositivos onde ele pode escolher um dispositivo ou simplesmente cancelar a solicitação.

navigator.bluetooth.requestDevicefunção usa um objeto obrigatório que define filtros. Esses filtros são usados ​​para retornar apenas dispositivos que correspondam a alguns serviços anunciados do Bluetooth GATT e / ou o nome do dispositivo.
Por exemplo, solicitar dispositivos Bluetooth que anunciam o Serviço de bateria Bluetooth GATT é simples:
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
Se o serviço Bluetooth GATT não estiver na lista dos serviços Bluetooth GATT padronizados , você poderá fornecer o UUID Bluetooth completo ou um formulário curto de 16 ou 32 bits.
navigator.bluetooth.requestDevice({
  filters: [{
    services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb']
  }]
})
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
Você também pode solicitar dispositivos Bluetooth com base no nome do dispositivo que está sendo anunciado com a namechave de filtros ou até mesmo um prefixo desse nome com a namePrefixchave de filtros. Observe que, nesse caso, você também precisará definir a optionalServiceschave para poder acessar alguns serviços. Caso contrário, você receberá um erro mais tarde ao tentar acessá-los.
navigator.bluetooth.requestDevice({
  filters: [{
    name: 'Francois robot'
  }],
  optionalServices: ['battery_service']
})
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
Finalmente, em vez de filtersvocê pode usar a acceptAllDevicestecla para mostrar todos os dispositivos Bluetooth próximos. Você também precisará definir a optionalServiceschave para poder acessar alguns serviços. Caso contrário, você receberá um erro mais tarde ao tentar acessá-los.
navigator.bluetooth.requestDevice({
  acceptAllDevices: true,
  optionalServices: ['battery_service']
})
.then(device => { /* ... */ })
.catch(error => { console.log(error); });





Conectar a um dispositivo Bluetooth

Então, o que você faz agora que BluetoothDeviceretornou da navigator.bluetooth.requestDevicePromessa? Vamos nos conectar ao servidor remoto GATT do Bluetooth, que contém as definições de serviço e característica.
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => {
  // Human-readable name of the device.
  console.log(device.name);

  // Attempts to connect to remote GATT Server.
  return device.gatt.connect();
})
.then(server => { /* ... */ })
.catch(error => { console.log(error); });

Leia uma característica do Bluetooth

Aqui estamos conectados ao servidor GATT do dispositivo Bluetooth remoto. Agora, queremos obter um serviço GATT principal e ler uma característica que pertence a esse serviço. Vamos tentar, por exemplo, ler o nível de carga atual da bateria do dispositivo.
No exemplo abaixo, battery_levelé a característica do nível da bateria padronizada .
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => device.gatt.connect())
.then(server => {
  // Getting Battery Service...
  return server.getPrimaryService('battery_service');
})
.then(service => {
  // Getting Battery Level Characteristic...
  return service.getCharacteristic('battery_level');
})
.then(characteristic => {
  // Reading Battery Level...
  return characteristic.readValue();
})
.then(value => {
  console.log('Battery percentage is ' + value.getUint8(0));
})
.catch(error => { console.log(error); });
Se você usar uma característica Bluetooth GATT personalizada, poderá fornecer o UUID completo do Bluetooth ou um formulário curto de 16 ou 32 bits service.getCharacteristic.
Observe que você também pode adicionar um characteristicvaluechangedouvinte de evento em uma característica para lidar com a leitura de seu valor. Consulte Ler amostra alterada do valor da característica para ver como lidar opcionalmente com as próximas notificações do GATT.
...
.then(characteristic => {
  // Set up event listener for when characteristic value changes.
  characteristic.addEventListener('characteristicvaluechanged',
                                  handleBatteryLevelChanged);
  // Reading Battery Level...
  return characteristic.readValue();
})
.catch(error => { console.log(error); });

function handleBatteryLevelChanged(event) {
  let batteryLevel = event.target.value.getUint8(0);
  console.log('Battery percentage is ' + batteryLevel);
}

Gravar em uma característica do Bluetooth

Escrever em uma característica Bluetooth GATT é tão fácil quanto lê-lo. Desta vez, vamos usar o ponto de controle da frequência cardíaca para redefinir o valor do campo Energia gasta para 0 em um dispositivo monitor de freqüência cardíaca.
Eu prometo que não há mágica aqui. Tudo explicado na página Característica do ponto de controle da frequência cardíaca .
navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] })
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('heart_rate'))
.then(service => service.getCharacteristic('heart_rate_control_point'))
.then(characteristic => {
  // Writing 1 is the signal to reset energy expended.
  var resetEnergyExpended = Uint8Array.of(1);
  return characteristic.writeValue(resetEnergyExpended);
})
.then(_ => {
  console.log('Energy expended has been reset.');
})
.catch(error => { console.log(error); });

Receba notificações do GATT

Agora, vamos ver como ser notificado quando a característica de medição da frequência cardíaca mudar no dispositivo:
navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] })
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('heart_rate'))
.then(service => service.getCharacteristic('heart_rate_measurement'))
.then(characteristic => characteristic.startNotifications())
.then(characteristic => {
  characteristic.addEventListener('characteristicvaluechanged',
                                  handleCharacteristicValueChanged);
  console.log('Notifications have been started.');
})
.catch(error => { console.log(error); });

function handleCharacteristicValueChanged(event) {
  var value = event.target.value;
  console.log('Received ' + value);
  // TODO: Parse Heart Rate Measurement value.
  // See https://github.com/WebBluetoothCG/demos/blob/gh-pages/heart-rate-sensor/heartRateSensor.js
}
exemplo de notificações mostra como interromper as notificações stopNotifications()e remover adequadamente o characteristicvaluechangedouvinte de evento adicionado .

Desconecte-se de um dispositivo Bluetooth

Para proporcionar uma melhor experiência ao usuário, você pode mostrar uma mensagem de aviso se ele BluetoothDevicefor desconectado para convidar o usuário a se reconectar.
navigator.bluetooth.requestDevice({ filters: [{ name: 'Francois robot' }] })
.then(device => {
  // Set up event listener for when device gets disconnected.
  device.addEventListener('gattserverdisconnected', onDisconnected);

  // Attempts to connect to remote GATT Server.
  return device.gatt.connect();
})
.then(server => { /* ... */ })
.catch(error => { console.log(error); });

function onDisconnected(event) {
  let device = event.target;
  console.log('Device ' + device.name + ' is disconnected.');
}
Você também pode ligar device.gatt.disconnect()para desconectar seu aplicativo Web do dispositivo Bluetooth. Isso acionará gattserverdisconnectedouvintes de eventos existentes Observe que NÃO interromperá a comunicação do dispositivo bluetooth se outro aplicativo já estiver se comunicando com o dispositivo Bluetooth. Confira a amostra de desconexão de dispositivo e a amostra de reconexão automática para aprofundar.







Ler e gravar nos descritores Bluetooth

Os descritores Bluetooth GATT são atributos que descrevem um valor de característica. Você pode lê-los e gravá-los de maneira semelhante às características do Bluetooth GATT.
Vamos ver, por exemplo, como ler a descrição do usuário do intervalo de medição do termômetro de funcionamento do dispositivo.
No exemplo abaixo, health_thermometerestão o serviço Health Thermometer , measurement_intervalcaracterística Measurement Interval e gatt.characteristic_user_descriptiondescritor Characteristic User Description .
navigator.bluetooth.requestDevice ({filtros: [{services: ['health_thermometer']}]}))
.then (device => device.gatt.connect ())
.then (server => server.getPrimaryService ('health_thermometer'))
.then (service => service.getCharacteristic ('measure_interval'))
.then (característica => característica.getDescriptor ('gatt.characteristic_user_description'))
.then (descriptor => descriptor.readValue ())
.then (value => {
  deixe decodificador = novo TextDecoder ('utf-8');
  console.log ('Descrição do Usuário:' + decoder.decode (value));
})
.catch (erro => {console.log (erro);});
Agora que lemos a descrição do usuário para o intervalo de medição do termômetro de saúde do dispositivo, vamos ver como atualizá-lo e escrever um valor personalizado.
navigator.bluetooth.requestDevice ({filtros: [{services: ['health_thermometer']}]}))
.then (device => device.gatt.connect ())
.then (server => server.getPrimaryService ('health_thermometer'))
.then (service => service.getCharacteristic ('measure_interval'))
.then (característica => característica.getDescriptor ('gatt.characteristic_user_description'))
.then (descritor => {
  deixe codificador = novo TextEncoder ('utf-8');
  deixe userDescription = encoder.encode ('Define o tempo entre as medições.');
  retornar descriptor.writeValue (userDescription);
})
.catch (erro => {console.log (erro);});

Amostras, demonstrações e codelabs

Todas as amostras de Bluetooth da Web abaixo foram testadas com sucesso. Para aproveitar ao máximo essas amostras, recomendo que você instale o aplicativo BLE Peripheral Simulator para Android, que simula um periférico BLE com um serviço de bateria, um serviço de frequência cardíaca ou um serviço de termômetro de saúde.

Principiante

  • Informações do dispositivo - recupere informações básicas do dispositivo de um dispositivo BLE.
  • Nível da bateria - recupere as informações da bateria de um dispositivo BLE que anuncia as informações da bateria.
  • Redefinir energia - redefine a energia gasta de um dispositivo BLE que anuncia a frequência cardíaca.
  • Propriedades da característica - exibe todas as propriedades de uma característica específica de um dispositivo BLE.
  • Notificações - inicie e pare as notificações características de um dispositivo BLE.
  • Desconexão do dispositivo - desconecte e seja notificado de uma desconexão de um dispositivo BLE após conectar-se a ele.
  • Obter características - obtenha todas as características de um serviço anunciado a partir de um dispositivo BLE.
  • Obter descritores - obtenha todos os descritores de todas as características de um serviço anunciado a partir de um dispositivo BLE.

Combinando várias operações

Bibliotecas

  • web-bluetooth-utils é um módulo npm que adiciona algumas funções de conveniência à API.
  • Um shim da API Bluetooth da Web está disponível no nobre , o mais popular módulo central do Node.js. BLE. Isso permite que você faça webpack / browserify noble sem a necessidade de um servidor WebSocket ou outros plugins.
  • angular-web-bluetooth é um módulo para Angular que abstrai todo o padrão necessário para configurar a API Bluetooth da Web.
  • <platinum-bluetooth> é um conjunto de elementos Polymer para descobrir e se comunicar com dispositivos Bluetooth próximos, com base na Web Bluetooth API. Por exemplo, veja como ler o nível da bateria de um dispositivo bluetooth próximo que anuncia um serviço de bateria:
<platinum-bluetooth-device services-filter='["battery_service"]'>
  <platinum-bluetooth-service service='battery_service'>
    <platinum-bluetooth-characteristic characteristic='battery_level'>
    </platinum-bluetooth-characteristic>
  </platinum-bluetooth-service>
</platinum-bluetooth-device>
var bluetoothDevice = document.querySelector('platinum-bluetooth-device');
var batteryLevel = document.querySelector('platinum-bluetooth-characteristic');

bluetoothDevice.request()
.then(_ => batteryLevel.read())
.then(value => {
  console.log('Battery percentage is ' + value.getUint8(0));
})
.catch(error => { console.log(error); });

Ferramentas

  • Introdução à Web O Bluetooth é um aplicativo da Web simples que gera todo o código do JavaScript para começar a interagir com um dispositivo Bluetooth. Digite um nome de dispositivo, um serviço, uma característica, defina suas propriedades e você estará pronto.
  • Se você já é desenvolvedor de Bluetooth, o Plug - in do Web Bluetooth Developer Studio também gera o código JavaScript da Web Bluetooth para o seu dispositivo Bluetooth.

Dicas do desenvolvedor

Uma página "Bluetooth Internals" está disponível no Chrome chrome://bluetooth-internalspara que você possa inspecionar tudo sobre dispositivos Bluetooth próximos: status, serviços, características e descritores.


Bluetooth Internals

Também recomendo que você verifique a página oficial "Como arquivar bugs no Bluetooth da Web" , pois a depuração do Bluetooth às vezes pode ser difícil.

Qual é o próximo passo
Verifique primeiro o status de implementação do navegador e da plataforma para saber quais partes da API da Web Bluetooth estão sendo implementadas no momento.
Embora ainda esteja incompleto, aqui está uma prévia do que esperar no futuro próximo:
  • A procura de anúncios BLE próximos acontecerá com navigator.bluetooth.requestLEScan().
  • A especificação da atualização do Eddystone permitirá que um site aberto a partir de uma notificação física da Web se comunique com o dispositivo que anuncia sua URL.
  • Um novo serviceaddedevento rastreará os Serviços Bluetooth GATT recém-descobertos, enquanto o serviceremovedevento rastreará os removidos. Um novo servicechanged evento será acionado quando qualquer característica e / ou descritor for adicionado ou removido de um serviço Bluetooth GATT.

TESTES COM WEB BLE E NINA B (Android M, Chrome)

Após fazer o SCAN, encontrou o Bluefruit52 e fiz a conexão e os serviços oferecidos pela aplicação BLE foram mostrados.



O primeiro serviço implementa o BLE serial, então entrei no mesmo e escrevi 0 (ASCII 48) na sua característica!


Obtive então no terminal serial do NINA B


Dúvidas:

suporte@smartcore.com.br

Referências:

https://developers.google.com/web/updates/2015/07/interact-with-ble-devices-on-the-web
https://www.u-blox.com/en/docs/UBX-17056481
https://www.u-blox.com/sites/default/files/NINA-B3_DataSheet_%28UBX-17052099%29.pdf

Sobre a SMARTCORE

A SmartCore fornece módulos para comunicação wireless, biometria, conectividade, rastreamento e automação.
Nosso portifólio inclui modem 2G/3G/4G/NB-IoT/Cat.M, satelital, módulos WiFi, Bluetooth, GNSS / GPS, Sigfox, LoRa, leitor de cartão, leitor QR code, mecanismo de impressão, mini-board PC, antena, pigtail, LCD, bateria, repetidor GPS e sensores.
Mais detalhes em www.smartcore.com.br