Characteristic é uma unidade fundamental de dados em Bluetooth Low Energy, através da qual um Central lê ou grava informações em um dispositivo periférico. Cada Characteristic pertence a um serviço GATT específico, possui um UUID único e um conjunto de propriedades (read, write, notify, indicate) que definem as operações possíveis. De acordo com a Bluetooth Core Specification 5.4 (2023), a Bluetooth SIG especificou mais de 500 características padrão para dispositivos médicos, fitness e industriais. Os desenvolvedores criam características personalizadas para transmitir qualquer tipo de dado do usuário — desde leituras de sensores até comandos de controle do dispositivo.
Pontos principais
Uma Characteristic é um atributo do protocolo GATT que contém um valor e metadados. Na arquitetura BLE, os dados não são transferidos diretamente entre dispositivos, mas sim pela leitura e gravação dos valores das características do serviço. Se um serviço é uma pasta, então uma Characteristic é um arquivo dentro dessa pasta.
Cada Characteristic consiste em três componentes: declaração (declaration), valor (value) e descritores (descriptors). A declaração contém o UUID da característica e suas propriedades. O valor são os dados reais transferidos entre Central e Peripheral. Os descritores fornecem configuração adicional.
De acordo com a Bluetooth Core Specification 5.4 (2023), todas as trocas de dados em BLE ocorrem através de operações sobre características. Até perfis padrão como Heart Rate Profile ou Battery Service são construídos sobre um conjunto de características com UUIDs predefinidos. Isso garante a compatibilidade de dispositivos de diferentes fabricantes sem configuração prévia.
É importante que o desenvolvedor entenda: cada Characteristic pode suportar diferentes combinações de propriedades. Uma característica pode ser somente leitura, outra para gravação, uma terceira para notificações. A escolha correta das propriedades determina o cenário de uso e o consumo de energia do dispositivo.
As propriedades (properties) de uma característica definem quais operações são permitidas sobre ela. É uma máscara de bytes onde cada bit ativa ou desativa uma operação específica. Abaixo estão listadas as principais propriedades.
| Propriedade | Bit | Descrição | Uso típico |
|---|---|---|---|
| Read | 0x02 | Central pode ler o valor atual | Status, nível de bateria, configuração |
| Write | 0x08 | Central pode gravar um novo valor | Comandos de controle, ajustes |
| Notify | 0x10 | Peripheral envia valor sem confirmação | Dados em fluxo (pulso, temperatura) |
| Indicate | 0x20 | Peripheral envia valor com confirmação | Dados críticos (alertas, estados) |
| Write Without Response | 0x04 | Gravação sem aguardar confirmação do servidor | Transmissão de comandos em alta velocidade |
As permissões (permissions) são o nível de acesso no nível do servidor GATT. Diferente das propriedades, que são declaradas na declaração da característica, as permissões são verificadas em cada operação. Elas podem incluir requisitos de criptografia e autenticação.
A Bluetooth SIG especificou mais de 500 características padrão que cobrem a maioria dos casos de uso comuns do BLE. O uso de UUIDs padrão garante que qualquer dispositivo receptor interprete corretamente os dados sem configuração prévia.
Estas são as características padrão mais utilizadas:
| UUID | Nome | Tipo de dado | Serviço |
|---|---|---|---|
| 0x2A19 | Battery Level | uint8 (0–100%) | Battery Service |
| 0x2A37 | Heart Rate Measurement | uint8 + flags | Heart Rate |
| 0x2A6E | Temperature | int16 (0.01°C) | Environmental Sensing |
| 0x2A6F | Humidity | uint16 (0.01%) | Environmental Sensing |
| 0x2A00 | Device Name | String UTF-8 | Generic Access |
| 0x2A01 | Appearance | uint16 | Generic Access |
Se uma característica padrão existente cobre sua tarefa, use-a. Isso simplifica a certificação Bluetooth e melhora a compatibilidade com o ecossistema. Crie características personalizadas apenas para dados únicos que não estejam no registro SIG.
Criar uma característica é feito no lado do Peripheral — o dispositivo que fornece os dados. Vamos ver as implementações no iOS (Swift) e Android (Java).
O Core Bluetooth fornece a classe CBMutableCharacteristic para criar uma característica com UUID, propriedades e valor inicial.
import CoreBluetooth
let characteristicUUID = CBUUID("2A19") // Característica de nível de bateria
let characteristic = CBMutableCharacteristic(
type: characteristicUUID,
properties: [.read, .notify],
value: nil,
permissions: [.readable]
)
// Atualizar valor ao alterar
let batteryData = Data([batteryLevel]) // uint8
peripheralManager.updateValue(
batteryData,
for: characteristic,
onSubscribedCentrals: nil
)
No Android, uma característica é criada usando BluetoothGattCharacteristic com UUID, propriedades e permissões.
import android.bluetooth.*;
UUID charUuid = UUID.fromString("00002A19-0000-1000-8000-00805F9B34FB");
BluetoothGattCharacteristic characteristic =
new BluetoothGattCharacteristic(
charUuid,
BluetoothGattCharacteristic.PROPERTY_READ
| BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ
);
// Definir o valor
characteristic.setValue(batteryLevel, BluetoothGattCharacteristic.FORMAT_UINT8, 0);
gattServer.notifyCharacteristicChanged(device, characteristic, false);
As operações sobre uma Characteristic se dividem em três tipos: leitura (read), escrita (write) e notificações (notify/indicate). A escolha depende do cenário: dados sob demanda são lidos, comandos são escritos, dados em fluxo se inscrevem em notificações.
Read: o Central envia uma solicitação para ler o valor da característica. O Peripheral responde com o valor atual. A operação é síncrona e requer uma solicitação explícita de cada lado. Usada para dados que mudam raramente: versão do firmware, número de série, configurações.
Write: o Central envia dados para o Peripheral. Há dois modos: Write with Response (confirmação do Peripheral) e Write Without Response (sem confirmação). Write with Response garante a entrega — o Peripheral envia uma confirmação após a gravação. Write Without Response é mais rápido mas não garante a entrega.
Notify e Indicate: o Peripheral inicia a transmissão de dados para o Central. No Notify, os dados são enviados sem confirmação — se o Central não receber o pacote, ele é perdido. No Indicate, o Central envia uma confirmação (nível PDU), garantindo a entrega. Indicate é mais lento mas mais confiável. Para se inscrever em notificações, o Central grava o valor 0x0001 no CCCD (Client Characteristic Configuration Descriptor).
MTU (Maximum Transmission Unit) define o tamanho máximo de um único pacote de dados BLE. Por padrão, o MTU é de 23 bytes, dos quais 3 bytes são o cabeçalho — a carga útil (ATT payload) é de 20 bytes. Isso é suficiente para a maioria dos dados de sensores, mas não para transferências de arquivos ou grandes configurações.
A Bluetooth Core Specification 5.4 suporta negociação de MTU — o Central e o Peripheral podem concordar com um tamanho de pacote maior de até 517 bytes. O processo funciona assim: o Central envia uma solicitação MTU Exchange com seu MTU proposto; o Peripheral responde com seu MTU; o menor dos dois valores é usado.
// iOS solicita MTU ao conectar
// MTU máximo no iOS é 185 bytes
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverServices error: Error?
) {
// Solicitar MTU para periférico específico
peripheral.maximumWriteValueLength(for: .withResponse)
}
De acordo com a Bluetooth SIG (2023), aumentar o MTU de 23 para 185 bytes reduz a sobrecarga de transmissão de dados em até 80% devido à redução do número de pacotes. Para aplicações que transmitem leituras de alta frequência (como ECG ou acelerômetro), o aumento do MTU é crítico para a estabilidade do fluxo.
Perguntas frequentes
A especificação BLE não limita o número de características em um serviço. Na prática, a limitação é determinada pela memória disponível do servidor GATT e pelos requisitos de desempenho. Para dispositivos embarcados, recomenda-se no máximo 10–15 características por serviço.
Notify envia dados sem confirmação — o pacote pode ser perdido sem aviso ao remetente. Indicate requer confirmação (ACK) no nível do protocolo, garantindo a entrega. Indicate é mais lento mas mais confiável. Para dados críticos (alertas, comandos), use Indicate.
Sim, uma característica pode ter uma combinação de propriedades. Por exemplo, uma característica de configuração pode suportar Read (leitura do valor atual) e Write (alteração da configuração). Combine as propriedades de acordo com seu cenário de uso.
Use a negociação de MTU para aumentar o tamanho do pacote para 185–517 bytes. Se os dados ainda forem maiores, implemente a fragmentação no nível da aplicação: divida os dados em várias solicitações sequenciais com controle de integridade.
Se sua tarefa for coberta por uma característica padrão, use UUIDs do registro Bluetooth SIG. Isso simplifica a certificação e garante a compatibilidade com o ecossistema. Crie UUIDs personalizados apenas para dados únicos de terceiros.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também