- Kit de desenvolvimento nRF52:
- Segger Embedded Studio
- DHT11 com nRF52DK
- Como trabalhar com Bluetooth Low Energy (BLE)?
- Diagrama de características / serviço BLE
- Explicação do programa nRF52 BLE
- Testando nosso programa usando nRF Connect
Com bandas de fitness, smartwatches e outros dispositivos vestíveis cada vez mais populares o uso de Bluetooth 5 / Bluetooth de baixa energiapadrões de comunicação estão sendo amplamente adotados. O BLE nos ajuda a trocar dados em uma distância curta com muito pouca energia, o que é muito importante para dispositivos que funcionam com bateria, como wearables. Também nos ajuda a configurar redes mesh BLE sem fio, esse recurso é útil para dispositivos de automação residencial onde vários dispositivos precisam se comunicar entre si em um ambiente fechado. Já usamos BLE com Raspberry Pi e BLE com ESP32 para executar algumas funções BLE básicas. Os engenheiros estão experimentando com BLE para projetar dispositivos sem fio portáteis que podem funcionar por um longo tempo com pequenas baterias e, há vários kits de desenvolvimento disponíveis para trabalhar com BLE. Em nossa recente análise do Arduino Nano 33, também notamos que a placa tem nRF52840 com recursos BLE.
Neste tutorial, exploraremos outra placa de desenvolvimento empolgante e popular chamada nRF52 DK para medir temperatura e umidade usando BLE. Por padrão, BLE Environment Sensing Profiles suporta uma ampla gama de parâmetros ambientais, mas este tutorial é limitado apenas aos valores de temperatura e umidade. Esta solução conecta-se com um Smartphone sobre Bluetooth de baixa energia e fornece uma atualização frequente em relação aos parâmetros ambientais, ou seja, Temperatura, Umidade. Estaremos usando o sensor DHT1 e a medição de Temperatura será feita com resolução de 0,01 graus Celsius e a medição de Umidade será feita com resolução de 0,01 por cento.
Kit de desenvolvimento nRF52:
nRF52DK é uma plataforma de prototipagem completa para o aplicativo Bluetooth Low Energy e 2.4 GHz Wireless Internet of Things. O kit de desenvolvimento suporta vários conjuntos de ferramentas nórdicos padrão como open-source, GCC e ambientes de desenvolvimento integrados comerciais como Keil, IAR e Segger Embedded Studio, etc. Nordic também fornece um kit de desenvolvimento de software completo para nRF52, que inclui suporte completo para nRF52DK.
nRF52DK é alimentado com nRF52832 ARM Cortex-M4F Microcontrolador, que é 512 Kbytes de Flash Memor integrado e 64 Kbytes de SRAM. nRF52DK tem um depurador integrado Segger J-Link On Board, que fornece uma depuração mais fácil e rápida sem dispositivos de depuração jtag externos / adicionais. Ele também inclui o conector compatível com Arduino Uno Rev3, que suporta a interface das entradas analógicas e digitais com o microprocessador e também inclui protocolos de comunicação padrão como I2C (Inter-Integrated Circuit), SPI (Serial Peripheral Interface) e UART (Universal Asynchronous Receiver and Transmitter). Este kit de desenvolvimento é projetado com uma antena PCB integrada que fornece comunicação sem fio de curto alcance usando Bluetooth Low Energy para conexão com smartphones, laptops e tablets.
Segger Embedded Studio
Para programar a placa de desenvolvimento, usaremos o Segger Embedded Studio com nRF52. Segger Embedded Studio é um poderoso ambiente de desenvolvimento integrado (IDE) C / C ++ voltado especificamente para o desenvolvimento de sistemas embarcados. Isso fornece uma solução all-in-one completa contendo tudo o que é necessário para programação, desenvolvimento e depuração em C embarcado. Isso inclui fluxo de trabalho completo para programação e desenvolvimento de sistemas embarcados, com gerenciamento de projeto, editor, depurador com suporte para dispositivos ARM Cortex. Este IDE poderoso e fácil de usar é totalmente gratuito para clientes nórdicos com licença completa sem quaisquer restrições de tamanho de código. O IDE pode ser baixado do link fornecido abaixo,
Baixar Segger Embedded Studio
DHT11 com nRF52DK
O DHT11 é um sensor de temperatura e umidade completo com um componente de medição de umidade do tipo resistivo e um componente de medição de temperatura do tipo NTC. Oferece excelente qualidade, resposta mais rápida e custo-benefício. Por padrão, todos os sensores DHT11 são calibrados no laboratório, o que resulta em extrema precisão e confiabilidade. Ele se comunica usando o sistema de interface serial de fio único e outras especificações são fornecidas abaixo
Especificações do DHT11:
- Faixa de umidade: 20 - 90% UR
- Faixa de temperatura: 0 - 50 graus Celsius
- Precisão de umidade: ± 5 % RH
- Precisão de temperatura: ± 2 ℃
Diagrama de tempo de DHT11:
Ler os dados do sensor DHT11 é relativamente simples usando o diagrama de tempo mostrado acima. O procedimento é semelhante a qualquer controlador e já usamos este sensor com outras plataformas de desenvolvimento como
- Sensor DHT11 com Raspberry Pi
- Sensor DHT11 com PIC16F877A
- Sensor DHT11 com STM32F103C8
- Sensor DHT11 com NodeMCU
Para fazer a interface do sensor de temperatura e umidade DHT11 com o kit de desenvolvimento nRF52, siga o diagrama de conexão fornecido abaixo.
Estou usando um módulo de conector para conectar o sensor à minha placa, então minha configuração final fica assim
Fluxograma para comunicação com DHT11:
O fluxograma abaixo explica o fluxo lógico do programa que usaremos para a comunicação entre o nRF52DK e o DHT11
Formato de dados:
Como trabalhar com Bluetooth Low Energy (BLE)?
Para entender como usar o recurso BLE, temos que entender algumas terminologias básicas que são explicadas abaixo, você também pode ler o artigo ESP32 BLE para saber mais sobre BLE
Perfil de acesso genérico (GAP)
O Perfil de Acesso Genérico detém a responsabilidade total de estabelecer a conexão para comunicação entre o periférico BLE e os dispositivos centrais. O GAP também fornece vários procedimentos, incluindo varredura / descoberta de dispositivo, estabelecimento de conexão de camada de link, terminação de link, handshaking de recursos de segurança e configuração completa de dispositivo. GAP funciona nos seguintes estados de dispositivo
Estados GAP |
Descrição |
Modo de espera |
Estado inicial do dispositivo após a reinicialização |
Anunciante |
Publicidade do dispositivo com dados que ajudam na verificação do iniciador |
Scanner |
Recebe e envia a solicitação de digitalização para o anunciante |
Iniciador |
Envia uma solicitação de conexão para estabelecer um link |
Mestre de escravos |
Na conexão, dispositivo como escravo se anunciante, mestre se iniciador |
Camada de Perfil de Atributo Genérico (GATT)
GATT significa Generic Attribute Profile Layer, é responsável pela comunicação de dados entre dois dispositivos BLE (Periférico e Central). A comunicação de dados é caracterizada na forma de características, que comunicam e armazenam os dados. O dispositivo BLE desempenha duas funções diferentes para a comunicação do dispositivo fornecida abaixo,
- O GATT Server contém as informações de características que serão usadas para leitura e gravação. Em nosso tutorial, o sensor DHT11 e o dev. o kit é nosso servidor GATT.
- O cliente GATT lê e grava os dados de / para o servidor GATT. O smartphone é um cliente GATT que lê e grava os dados em nossa placa de sensor.
SIG Bluetooth
Bluetooth Special Interest Group (SIG) é a organização de padrões que monitora o desenvolvimento dos padrões Bluetooth e o licenciamento das tecnologias Bluetooth. O grupo SIG não produz nem vende nenhum produto Bluetooth. Ele define a especificação e padronização do Bluetooth. Eles definem o identificador único para o perfil de baixa energia do Bluetooth e respectivas características. As especificações do Perfil GATT podem ser encontradas no link abaixo
Especificações do perfil GATT
Com base na especificação GATT fornecida no link acima, coletamos os identificadores exclusivos necessários para nosso projeto, que estão tabulados abaixo.
Perfil / Características |
UUID |
GAP (acesso genérico) |
0x1800 |
GATT (Atributo Genérico) |
0x1801 |
ESS (detecção de ambiente) |
0x181A |
Temperatura |
0x2A6E |
Umidade |
0x2A6F |
Diagrama de características / serviço BLE
BLE UUIDs
UUID |
Valor de 16 bits |
UUID de 128 bits |
Serviço ESS |
0x181A |
0000181A-0000-0000-0000-00000000000 |
Temp Char |
0x2A6E |
00002A6E-0000-0000-0000-00000000000 |
Umidade Char |
0x2A6F |
00002A6F-0000-0000-0000-00000000000 |
Características de temperatura
Propriedade |
Descrição |
Unidade |
Graus Celsius com resolução de 0,01 graus |
Formato |
sint16 |
UUID |
0x2A6E |
Expoente Decimal |
2 |
Ler |
Obrigatório |
Características de Umidade
Propriedade |
Descrição |
Unidade |
Porcentagem com resolução de 0,01 por cento |
Formato |
uint16 |
UUID |
0x2A6F |
Expoente Decimal |
2 |
Ler |
Obrigatório |
Explicação do programa nRF52 BLE
Usaremos o SDK nRF5 para programar nosso kit de desenvolvimento nRF52. O nRF5 SDK é um kit de desenvolvimento de software completo integrado com vários perfis de Bluetooth Low Energy, GATT Serializer e suporte a driver para todos os periféricos nos SoCs da série nRF5. Este SDK ajuda os desenvolvedores a criar aplicativos de baixo consumo de energia Bluetooth completos, confiáveis e seguros com as séries de microcontroladores nRF52 e nRF51. O programa completo pode ser baixado aqui, a explicação do código é a seguinte.
Configure o pino DHT11 DATA como entrada no nrf52 com pull up enable. O status do pino deve ser alto para confirmar que o nRF52 fornece PULLUP adequado para o pino de dados DHT11
/ * definido para entrada e verifica se o sinal é puxado * / Data_SetInput (); DelayUSec (50); if (Data_GetVal () == 0) {return DHT11_NO_PULLUP; }
Gere o sinal START do microcontrolador nRF52 e verifique o sinal de reconhecimento.
/ * enviar sinal de início * / Data_SetOutput (); Data_ClrVal (); DelayMSec (20); / * manter o sinal baixo por pelo menos 18 ms * / Data_SetInput (); DelayUSec (50); / * verificar o sinal de reconhecimento * / if (Data_GetVal ()! = 0) {/ * o sinal deve ser puxado para baixo pelo sensor * / return DHT11_NO_ACK_0; } / * aguarde no máximo 100 us pelo sinal de confirmação do sensor * / cntr = 18; while (Data_GetVal () == 0) {/ * espere até que o sinal suba * / DelayUSec (5); if (--cntr == 0) {return DHT11_NO_ACK_1; / * o sinal deve estar ativo para o ACK aqui * /}} / * aguarde até que ele caia novamente, fim da sequência de ack * / cntr = 18; while (Data_GetVal ()! = 0) {/ * esperar até que o sinal caia * / DelayUSec (5); if (--cntr == 0) {return DHT11_NO_ACK_0; / * o sinal deve voltar a zero aqui * /}}
Agora leia os 40 bits de dados que contêm 2 bytes de temperatura, 2 bytes de umidade e 1 byte de checksum.
/ * agora lê os dados de 40 bits * / i = 0; dados = 0; loopBits = 40; faça {cntr = 11; / * aguarde no máximo 55 us * / while (Data_GetVal () == 0) {DelayUSec (5); if (--cntr == 0) {return DHT11_NO_DATA_0; }} cntr = 15; / * aguarde no máximo 75 us * / while (Data_GetVal ()! = 0) {DelayUSec (5); if (--cntr == 0) {return DHT11_NO_DATA_1; }} dados << = 1; / * próximo bit de dados * / if (cntr <10) {/ * sinal de dados alto> 30 us ==> bit de dados 1 * / data - = 1; } if ((loopBits & 0x7) == 1) {/ * próximo byte * / buffer = data; i ++; dados = 0; }} while (- loopBits! = 0);
Valide os dados com a ajuda de Checksum.
/ * teste CRC * / if ((uint8_t) (buffer + buffer + buffer + buffer)! = buffer) {return DHT11_BAD_CRC; }
Manipular e armazenar a temperatura e a umidade
/ * armazenar valores de dados para o chamador * / umidade = ((int) buffer) * 100 + buffer; temperatura = ((int) buffer) * 100 + buffer;
Inicialize o serviço nRF5 SDK Logger. O nRF52 SDK possui uma interface de controle de registro chamada nrf_log e usa o backend padrão para registrar as informações. O back-end padrão será uma porta serial. Aqui nós inicializar tanto nrf_log interface de controle e nrf_log backends padrão também.
ret_code_t err_code = NRF_LOG_INIT (NULL); APP_ERROR_CHECK (err_code); NRF_LOG_DEFAULT_BACKENDS_INIT ();
O nRF52 SDK possui funcionalidade de cronômetro de aplicativo. O módulo de cronômetro do aplicativo permite criar várias instâncias de cronômetro com base no periférico RTC1. Aqui, inicializamos o módulo de cronômetro do aplicativo nRF5. Nesta solução, dois cronômetros de aplicativo são usados para um intervalo de atualização de dados.
ret_code_t err_code = app_timer_init (); APP_ERROR_CHECK (err_code);
O nRF52 SDK possui o módulo de gerenciamento de energia completo, já que os dispositivos BLE precisam funcionar por vários meses com uma bateria de célula tipo moeda. O gerenciamento de energia desempenha um papel vital em aplicativos BLE. O módulo de gerenciamento de energia nRF52 lida completamente com o mesmo. Aqui, inicializamos o módulo de gerenciamento de energia do nRF5 SDK
ret_code_t err_code; err_code = nrf_pwr_mgmt_init (); APP_ERROR_CHECK (err_code);
O nRF52 SDK possui um arquivo hexadecimal de firmware Nordic Soft Device, que apresenta pilha central e periférica Bluetooth de baixa energia. Esta pilha de protocolo altamente qualificada inclui GATT, GAP, ATT, SM, L2CAP e Link Layer. Aqui seguimos a sequência de inicialização, que inicializou nRF5 BLE Radio Stack (Nordic Soft Device)
ret_code_t err_code; err_code = nrf_sdh_enable_request (); APP_ERROR_CHECK (err_code); // Configure a pilha BLE usando as configurações padrão. // Buscar o endereço inicial da RAM do aplicativo. uint32_t ram_start = 0; err_code = nrf_sdh_ble_default_cfg_set (APP_BLE_CONN_CFG_TAG, & ram_start); APP_ERROR_CHECK (err_code); // Habilita pilha BLE. err_code = nrf_sdh_ble_enable (& ram_start); APP_ERROR_CHECK (err_code); // Registra um manipulador para eventos BLE. NRF_SDH_BLE_OBSERVER (m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
O GAP é responsável pela verificação / descoberta de dispositivos, estabelecimento de links, terminação de links, inicialização de recursos de segurança e configuração. GAP apresenta parâmetros de conexão chave como intervalo de conexão, latência do escravo, tempo limite de supervisão, etc.
ret_code_terr_code; ble_gap_conn_params_tgap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN (& sec_mode); err_code = sd_ble_gap_device_name_set (& sec_mode, (const uint8_t *) DEVICE_NAME, strlen (DEVICE_NAME)); APP_ERROR_CHECK (err_code); memset (& gap_conn_params, 0, sizeof (gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set (& gap_conn_params); APP_ERROR_CHECK (err_code);
O GATT é responsável pela comunicação de dados entre os dispositivos periféricos e centrais BLE. O módulo nRF52 GATT é útil para negociar e controlar o tamanho máximo de ATT_MTU. Aqui, inicializamos o Módulo de Atributo Genérico SDK nRF52, ret_code_t err_code = nrf_ble_gatt_init (& m_gatt, NULL); APP_ERROR_CHECK (err_code);
O GATT faz a comunicação de dados na forma de serviços e características. Aqui, inicializamos os serviços de detecção de ambiente do GATT, que incluem a inicialização de características como temperatura e umidade.
ret_code_terr_code; nrf_ble_qwr_init_t qwr_init = {0}; // Inicializa o Módulo de Gravação em Fila. qwr_init.error_handler = nrf_qwr_error_handler; err_code = nrf_ble_qwr_init (& m_qwr, & qwr_init); APP_ERROR_CHECK (err_code); m_ess.notif_write_handler = ble_ess_notif_write_handler; err_code = ble_ess_init (& m_ess); APP_ERROR_CHECK (err_code);
A publicidade desempenha um papel vital no ambiente de aplicativos BLE. os pacotes incluem as informações do tipo de endereço, tipo de anúncio, dados de propaganda, dados específicos do fabricante do dispositivo e dados de resposta de varredura. SDK nRF52 com módulo de publicidade. Aqui fazemos a inicialização do módulo de publicidade com os parâmetros.
ret_code_terr_code; ble_advdata_t advdata; ble_advdata_t srdata; ble_uuid_t adv_uuids = {{ESS_UUID_SERVICE, BLE_UUID_TYPE_BLE}}; // Construir e definir dados de publicidade. memset (& advdata, 0, sizeof (advdata)); advdata.name_type = BLE_ADVDATA_FULL_NAME; advdata.include_appearance = true; advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; memset (& srdata, 0, sizeof (srdata)); srdata.uuids_complete.uuid_cnt = sizeof (adv_uuids) / sizeof (adv_uuids); srdata.uuids_complete.p_uuids = adv_uuids; err_code = ble_advdata_encode (& advdata, m_adv_data.adv_data.p_data, & m_adv_data.adv_data.len); APP_ERROR_CHECK (err_code); err_code = ble_advdata_encode (& srdata, m_adv_data.scan_rsp_data.p_data, & m_adv_data.scan_rsp_data.len); APP_ERROR_CHECK (err_code); ble_gap_adv_params_t adv_params; // Defina os parâmetros de publicidade. memset (& adv_params, 0, sizeof (adv_params)); adv_params.primary_phy = BLE_GAP_PHY_1MBPS; adv_params.duration = APP_ADV_DURATION; adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED; adv_params.p_peer_addr = NULL; adv_params.filter_policy = BLE_GAP_ADV_FP_ANY; adv_params.interval = APP_ADV_INTERVAL; err_code = sd_ble_gap_adv_set_configure (& m_adv_handle, & m_adv_data, & adv_params); APP_ERROR_CHECK (err_code);
A conexão BLE será tratada e monitorada com vários parâmetros de conexão, como primeiro atraso de atualização de parâmetros de conexão, próximos atrasos consecutivos, contagem de atualização, função de retorno de chamada do manipulador de eventos de conexão e manipulador de eventos de retorno de chamada de erro de conexão. Aqui fazemos a inicialização dos parâmetros de estabelecimento da conexão BLE e um manipulador de eventos de retorno de chamada para eventos de conexão e eventos de erro.
ret_code_terr_code; ble_conn_params_init_t cp_init; memset (& cp_init, 0, sizeof (cp_init)); cp_init.p_conn_params = NULL; cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; t_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; cp_init.disconnect_on_fail = false; cp_init.evt_handler = on_conn_params_evt; cp_init.error_handler = conn_params_error_handler; err_code = ble_conn_params_init (& cp_init); APP_ERROR_CHECK (err_code);
Após a conclusão da inicialização do sistema, começamos aqui anunciando o nome do dispositivo BLE e as informações de capacidade. A partir daqui, este periférico pode ser visto na lista de varredura Ble do smartphone.
ret_code_terr_code; err_code = sd_ble_gap_adv_start (m_adv_handle, APP_BLE_CONN_CFG_TAG); APP_ERROR_CHECK (err_code);
O loop principal é executado em um intervalo de 2 segundos, lê a temperatura e umidade e atualiza para um dispositivo inteligente conectado usando leitura ou notificação
para (;;) { uint16_t temperatura, umidade; DHTxx_ErrorCode dhtErrCode; idle_state_handle (); if (updtmrexp) { dhtErrCode = DHTxx_Read (& temperatura, & umidade); if (dhtErrCode == DHT11_OK) { NRF_LOG_INFO ("Temperatura:% d Umidade:% d \ n", temperatura, umidade); if (temp_notif_enabled) { ble_ess_notify_temp (m_conn_handle, & m_ess, temperatura); } else { ble_ess_update_temp (& m_ess, temperatura); } if (humid_notif_enabled) { ble_ess_notify_humid (m_conn_handle, & m_ess, umidade); } else { ble_ess_update_humid (& m_ess, umidade); } } updtmrexp = false; } }
Testando nosso programa usando nRF Connect
nRF Connect é uma poderosa ferramenta Bluetooth de baixa energia que permite escanear e explorar os periféricos habilitados para BLE. O nRF Connect for mobile suporta uma ampla gama de perfis padrão adotados por Bluetooth SIG. Podemos verificar nosso programa usando isso, depois de instalar o aplicativo, podemos emparelhar a placa nRF52 com nosso telefone, procurando por dispositivos BLE no aplicativo. Dentro do atributo Sensor ambiental, podemos notar os valores de temperatura e umidade sendo atualizados conforme mostrado nas fotos abaixo.
Hariharan Veerappan é um consultor independente com mais de 15 anos de experiência no desenvolvimento de produtos embarcados. Ele fornece serviços de consultoria em desenvolvimento de firmware embarcado / Linux, ele também fornece treinamento corporativo e online. Hariharan é Bacharel em Engenharia na disciplina de Engenharia Eletrônica e de Comunicação, por meio de seus artigos e tutoriais, ele compartilha sua experiência e pensamentos com os leitores da Circuit Digest.