Índice:

Biblioteca para BMP280 e BME280: 7 etapas
Biblioteca para BMP280 e BME280: 7 etapas

Vídeo: Biblioteca para BMP280 e BME280: 7 etapas

Vídeo: Biblioteca para BMP280 e BME280: 7 etapas
Vídeo: Lesson 29: Introduction to BMP280 Temperature Sensor| Arduino Step By Step Course 2024, Julho
Anonim
Biblioteca para BMP280 e BME280
Biblioteca para BMP280 e BME280
Biblioteca para BMP280 e BME280
Biblioteca para BMP280 e BME280
Biblioteca para BMP280 e BME280
Biblioteca para BMP280 e BME280

Introdução

Não me propus a escrever esta biblioteca. "Aconteceu" como efeito colateral de um projeto que iniciei que usa um BMP280. Esse projeto ainda não terminou, mas acho que a biblioteca está pronta para ser compartilhada com outras pessoas. Posteriormente, tive a necessidade de usar um BME280, que adiciona medição de umidade à capacidade de pressão e temperatura do BMP280. O BME280 é "compatível com versões anteriores" com o BMP280 - ou seja, todos os registros e as etapas necessárias para ler a pressão e a temperatura do BME280 são os mesmos usados para o BMP280. Existem registros e etapas adicionais necessários para ler a umidade, aplicável apenas ao BME280. Isso levanta a questão, uma biblioteca para ambos ou duas bibliotecas separadas. O hardware para os dois tipos de dispositivo é totalmente intercambiável. Mesmo muitos dos módulos vendidos (por exemplo, no Ebay e no AliExpress) são rotulados como BME / P280. Para descobrir que tipo é, você deve olhar para a escrita (minúscula) no próprio sensor ou testar o byte de ID do dispositivo. Decidi ir para uma única biblioteca. Parece que funcionou bem.

Comentários, especialmente sugestões de melhorias, serão bem-vindos.

Recursos e capacidades da biblioteca

Uma biblioteca é um pedaço de software que fornece uma Interface de Programação de Aplicativo (API) para um programador exercitar os recursos do dispositivo, sem necessariamente ter que lidar com todos os detalhes de grão fino. Desejavelmente, a API deve ser fácil para um iniciante, com requisitos simples para começar, ao mesmo tempo em que fornece uma exploração completa dos recursos do dispositivo. Desejavelmente, a biblioteca deve seguir todas as orientações específicas do fabricante do dispositivo, bem como as boas práticas gerais de software. Tenho me esforçado para alcançar tudo isso. Ao começar com o BMP280, encontrei 3 bibliotecas diferentes para ele: Adafruit_BMP280; Seeed_BMP280; e um chamado BMP280 do fabricante do dispositivo. Nem o Adafruit nem o Seeed forneceram recursos estendidos, embora funcionassem bem e fossem fáceis de usar para aplicativos básicos. Não consegui descobrir como usar o produzido pelo fabricante do dispositivo (Bosch Sensortec). Esta pode ser minha deficiência, e não a deles. No entanto, a biblioteca era muito mais complicada do que as outras duas, não consegui encontrar nenhuma instrução ou exemplo de uso (posteriormente encontrei exemplos no arquivo "bmp280_support.c", no entanto, eles não foram particularmente úteis para mim).

Como resultado desses fatores, decidi escrever minha própria biblioteca para o BMP280.

Olhando para a situação da biblioteca para o BME280, encontrei bibliotecas separadas Adafruit_BME280, Seed_BME280 e outra BME280_MOD-1022 escrita por Embedded Adventures. Nenhum deles combinou as funções do BMP280 em uma biblioteca capaz de usar o BME280. Nenhum deles oferece suporte explícito à capacidade dos dispositivos de armazenar alguns bits de dados enquanto o dispositivo e seu microprocessador de controle estão hibernando (esse recurso é evidente na folha de dados e é compatível com a biblioteca que escrevi e descrevi aqui).

Uma biblioteca combinada deve ter suporte para todos os recursos do BME280, mas quando usada com um BMP280, não deve impor nenhuma sobrecarga das funções não utilizadas. Os benefícios de uma biblioteca combinada incluem menos arquivos de biblioteca para gerenciar, fácil combinação e combinação de diferentes dispositivos no mesmo projeto e alterações simplificadas para manutenção ou atualizações que só precisam ser feitas em um lugar ao invés de dois. Provavelmente são todos muito pequenos, até mesmo insignificantes, mas …

Capacidades do dispositivo

O BMP280 e o BME280 são dispositivos de montagem em superfície com cerca de 5 mm quadrados e 1 mm de altura. Existem 8 pads de interface, incluindo 2 pads de entrada de energia separados e dois pads de aterramento. Eles estão disponíveis no eBay como um módulo com 4 ou 6 pinos destacados. O módulo de 4 pinos tem um endereço I2C fixo e não pode ser configurado para usar o protocolo SPI.

O módulo de 6 pinos ou o dispositivo simples pode ser usado com os protocolos I2C ou SPI. No modo I2C, ele pode ter dois endereços diferentes, obtidos conectando o pino SDO ao aterramento (para endereço de base = 0x76) ou ao Vdd (para endereço de base +1 = 0x77). No modo SPI, ele possui o arranjo usual de 1 relógio, 2 dados (um para cada direção) e um pino de seleção de dispositivo (CS).

A biblioteca que escrevi e descrevo aqui suporta apenas I2C. As bibliotecas Adafruit_BMP280 e BME_MOD-1022 têm suporte para i2C e SPI.

A biblioteca pode ser baixada aqui:

github.com/farmerkeith/BMP280-library

Etapa 1: Configurando o Hardware

Configurando o Hardware
Configurando o Hardware

Antes que a biblioteca possa ser útil, é necessário conectar um microcontrolador ao BMP280 (ou a dois deles, se desejar).

Usei um mini pro WeMos D1, então vou mostrar suas conexões. Outros microcontroladores serão semelhantes, você só precisa conectar os pinos SDA e SCL corretamente.

No caso do WeMos D1 mini pro, as conexões são:

Função do pino BMP280 do pino WeMos Notas

SDA D2 SDA SCL D1 SCL Vdd 3V3 Vin Nominal 3,3 V Terra GND Controle de endereço SDO Terra ou Vdd I2C selecione CSB Vdd (GND seleciona SPI)

Observe que o pino SDO em alguns dos módulos MP280 é rotulado como SDD e o pino Vdd pode ser rotulado como VCC. Observação: as linhas SDA e SCL devem ter resistores pull-up entre a linha e o pino Vin. Normalmente, um valor de 4,7 K deve ser OK. Alguns módulos BMP280 e BME280 têm resistores pull-up de 10K incluídos no módulo (o que não é uma boa prática, pois colocar vários dispositivos no barramento I2C pode carregá-lo excessivamente). No entanto, usar 2 módulos BME / P280, cada um com um resistor de 10K, não deve ser um problema na prática, desde que não haja muitos outros dispositivos no mesmo barramento também com resistores pull-up.

Depois de conectar o hardware, você pode verificar facilmente se o seu dispositivo é um BMP280 ou BME280 executando o esboço I2CScan_ID que você pode encontrar aqui:

Você também pode verificar se possui um BMP280 ou BME280 olhando para o próprio dispositivo. Achei necessário usar um microscópio digital para fazer isso, mas se sua visão for muito boa, você poderá fazer isso sem qualquer auxílio. Existem duas linhas de impressão na caixa do dispositivo. A chave é a primeira letra da segunda linha, que no caso dos dispositivos BMP280 é um "K" e no caso dos dispositivos BME280 é um "U".

Etapa 2: APIs fornecidas pela biblioteca

APIs fornecidas pela biblioteca
APIs fornecidas pela biblioteca
APIs fornecidas pela biblioteca
APIs fornecidas pela biblioteca

Incluindo a biblioteca em um esboço

A biblioteca é incluída em um esboço da maneira padrão usando a declaração

#include "farmerkeith_BMP280.h"

Esta declaração precisa ser incluída na parte inicial do esboço, antes do início da função setup ().

Criação de um objeto de software BME ou BMP

Existem 3 níveis para criar o objeto de software BMP280. O mais simples é apenas

bme280 objectName; ou bmp280 objectName;

por exemplo, BMP280 bmp0;

Isso cria um objeto de software com o endereço padrão de 0x76 (ou seja, para SDO conectado ao aterramento).

O próximo nível para a criação de um objeto de software BME280 ou BMP280 tem um parâmetro de 0 ou 1, conforme a seguir:

bme280 objectNameA (0);

bmp280 objectNameB (1);

O parâmetro (0 ou 1) é adicionado ao endereço base I2C, de modo que dois dispositivos BME280 ou BMP280 possam ser usados no mesmo barramento I2C (incluindo um de cada).

O terceiro nível para a criação de um objeto de software BME ou BMP280 possui dois parâmetros. O primeiro parâmetro, que pode ser 0 ou 1, é para o endereço, como no caso anterior. O segundo parâmetro controla a impressão de depuração. Se for definido como 1, cada transação com o objeto de software resulta em saídas Serial.print que permitem ao programador ver os detalhes da transação. Por exemplo:

bmp280 objectNameB (1, 1);

Se o parâmetro de depuração de impressão for definido como 0, o objeto de software reverte para o comportamento normal (sem impressão).

Esta instrução ou instruções precisam ser incluídas após #include e antes da função setup ().

Inicializando o objeto de software BME ou BMP

Antes de ser usado, é necessário ler os parâmetros de calibração do dispositivo e configurá-lo para qualquer modo de medição, sobreamostragem e configurações de filtro apropriadas.

Para uma inicialização simples e de uso geral, a instrução é:

objectName.begin ();

Esta versão de begin () lê os parâmetros de calibração do dispositivo e define osrs_t = 7 (16 medições de temperatura), osrs_p = 7 (16 medições de pressão), modo = 3 (contínuo, Normal), t_sb = 0 (0,5 ms de sono entre conjuntos de medição), filtro = 0 (K = 1, portanto, sem filtragem) e spiw_en = 0 (SPI desabilitado, então use I2C). No caso do BME280, existe um parâmetro extra osrs_h = 7 para 16 medições de umidade.

Há outra versão de begin () que usa todos os seis (ou 7) parâmetros. O equivalente da declaração acima é

objectName.begin (7, 7, 3, 0, 0, 0); // osrs_t, osrs_p, modo, t_sb, filtro, spiw_en

ou objectName.begin (7, 7, 3, 0, 0, 0, 7); // osrs_t, osrs_p, modo, t_sb, filtro, spiw_en, osrs_h

A lista completa de códigos e seus significados está na folha de dados BME280 e BMP280 e também nos comentários no arquivo.cpp da biblioteca.

Medição simples de temperatura e pressão

Para obter uma medição de temperatura, a maneira mais simples é

temperatura dupla = objectName.readTemperature (); // medir a temperatura

Para obter uma medição de pressão, a maneira mais simples é

pressão dupla = objectName.readPressure (); // medir a pressão

Para obter uma medição de umidade, a maneira mais simples é

umidade dupla = objectName.readHumidity (); // medir a umidade (apenas BME280)

Para obter a temperatura e a pressão, as duas instruções acima podem ser usadas uma após a outra, mas há outra opção, que é:

temperatura dupla;

pressão dupla = objectName.readPressure (temperatura); // medir pressão e temperatura

Esta instrução lê os dados do dispositivo BME280 ou BMP280 apenas uma vez e retorna a temperatura e a pressão. Este é um uso um pouco mais eficiente do barramento I2C e garante que as duas leituras correspondam ao mesmo ciclo de medição.

Para o BME 280, uma declaração combinada que obtém todos os três valores (umidade, temperatura e pressão) é:

temperatura dupla, pressão; umidade dupla = objectName.readHumidity (temperatura, pressão); // medir umidade, pressão e temperatura

Esta instrução lê os dados do dispositivo BMP280 apenas uma vez e retorna todos os três valores. Este é um uso um pouco mais eficiente do barramento I2C e garante que as três leituras correspondam ao mesmo ciclo de medição. Observe que os nomes das variáveis podem ser alterados para qualquer coisa que o usuário goste, mas sua ordem é fixa - a temperatura vem primeiro e a pressão vem em segundo lugar.

Esses casos de uso são cobertos em esboços de exemplo fornecidos com a biblioteca, sendo basicTemperature.ino, basicPressure.ino, basicHumidity.ino, basicTemperatureAndPressure.ino e basicHumidityAndTemperatureAndPressure.ino.

Medição de temperatura e pressão mais sofisticada

Embora a série de instruções acima funcione sem problemas, existem alguns problemas:

  1. o dispositivo está funcionando continuamente e, portanto, está consumindo energia em seu nível máximo. Se a energia vem de uma bateria, pode ser necessário reduzi-la.
  2. devido à energia consumida, o dispositivo passará por aquecimento e, portanto, a temperatura medida será superior à temperatura ambiente. Abordarei isso mais em uma etapa posterior.

Um resultado que consuma menos energia e forneça uma temperatura mais próxima da ambiente pode ser obtido usando begin () com parâmetros que o colocam em hibernação (por exemplo, modo = 0). Por exemplo:

objectName.begin (1, 1, 0, 0, 0, 0 [, 1]); // osrs_t, osrs_p, modo, t_sb, filtro, spiw_en [, osrs_h]

Então, quando uma medição for desejada, desperte o dispositivo com um comando de configuração para os registros F2 (se necessário) e F4 que define os valores apropriados de osrs_h, osrs_t e osrs_p, modo positivo = 1 (modo de disparo único). Por exemplo:

[objectName.updateF2Control (1);] // osrs_h - nunca necessário para BMP280, // e não é necessário para BME280 se o número de medições não estiver sendo alterado // do valor fornecido em begin (). objectName.updateF4Control (1, 1, 1); // osrs_t, osrs_p, modo

Depois de acordar o dispositivo, ele começará a medir, mas o resultado não estará disponível por alguns milissegundos - pelo menos 4 ms, talvez até 70 ms ou mais, dependendo do número de medições que foram especificadas. Se o comando de leitura for enviado imediatamente, o dispositivo retornará os valores da medição anterior - o que pode ser aceitável em algumas aplicações, mas na maioria dos casos é provavelmente melhor atrasar até que a nova medição esteja disponível.

Esse atraso pode ser feito de várias maneiras.

  1. espere um período fixo de tempo para cobrir o atraso mais longo esperado
  2. espere um período de tempo calculado a partir do tempo máximo de medição por medição (ou seja, 2,3 ms) vezes o número de medições, mais a sobrecarga, mais uma margem.
  3. espere um período menor de tempo calculado como acima, mas usando o tempo de medição nominal (ou seja, 2 ms) mais a sobrecarga e, em seguida, comece a verificar o bit "Estou medindo" no registro de status. Quando o bit de status for 0 (ou seja, sem medição), obtenha as leituras de temperatura e pressão.
  4. comece imediatamente a verificar o registro de status e obtenha as leituras de temperatura e pressão quando o bit de status ler 0,

Vou mostrar um exemplo de uma maneira de fazer isso um pouco mais tarde.

Operações de registro de configuração

Para que tudo isso aconteça, precisamos de várias ferramentas que ainda não apresentei. Eles são:

byte readRegister (reg)

void updateRegister (reg, valor)

Cada um deles possui vários comandos derivados na biblioteca, o que torna o software para ações específicas um pouco mais simples.

O exemplo powerSaverPressureAndTemperature.ino usa o método nº 3. A linha de código que faz a verificação repetida é

while (bmp0.readRegister (0xF3) >> 3); // loop até F3bit 3 == 0

Observe que este esboço é para um microcontrolador ESP8266. Usei um mini pro WeMos D1. O esboço não funcionará com microcontroladores Atmega, que têm instruções diferentes para dormir. Este esboço exercita vários outros comandos, portanto, apresentarei todos eles antes de descrever o esboço com mais detalhes.

Quando o microcontolador está dormindo em paralelo com o sensor BMP280, a configuração do sensor para as medições necessárias pode ser feita no comando begin (), usando os 6 parâmetros. Porém, se o microcontrolador não está hibernando, mas o sensor está, então, no momento da medição, o sensor deve ser acordado e informado sobre sua configuração de medição. Isso pode ser feito diretamente com

updateRegister (reg, valor)

mas é um pouco mais fácil com os três comandos a seguir:

updateF2Control (osrs_h); // BME280 apenas

updateF4Control (osrs_t, osrs_p, modo); updateF5Config (t_sb, filtro, spi3W_en);

Depois que a medição for feita, se o modo usado for um disparo (modo forçado), o dispositivo voltará a hibernar automaticamente. No entanto, se o conjunto de medições envolver várias medições usando o modo contínuo (Normal), o BMP280 precisará ser colocado de volta no modo de hibernação. Isso pode ser feito com um dos dois comandos a seguir:

updateF4Control16xSleep ();

updateF4ControlSleep (valor);

Ambos definem os bits de modo para 00 (ou seja, modo de espera). No entanto, o primeiro define osrs_t e osrs_p para 111 (ou seja, 16 medições), enquanto o segundo armazena os 6 bits inferiores de "valor" nos bits 7: 2 do registro 0xF4.

Da mesma forma, a seguinte instrução armazena os seis bits inferiores de "valor" nos bits 7: 2 do registro 0xF5.

updateF5ConfigSleep (valor);

O uso desses últimos comandos permite o armazenamento de 12 bits de informação nos registros BMP280 F4 e F5. Pelo menos no caso do ESP8266, quando o microcontrolador acorda após um período de sono, ele começa no início do esboço sem nenhum conhecimento de seu estado anterior ao comando de sono. Para armazenar o conhecimento de seu estado antes do comando dormir, os dados podem ser armazenados na memória flash, usando as funções EEPROM ou gravando um arquivo usando SPIFFS. No entanto, a memória flash tem uma limitação do número de ciclos de gravação, da ordem de 10.000 a 100.000. Isso significa que se o microcontrolador estiver passando por um ciclo de sono-vigília a cada poucos segundos, ele pode exceder a gravação de memória permitida limite em alguns meses. O armazenamento de alguns bits de dados no BMP280 não tem essa limitação.

Os dados armazenados nos registros F4 e F5 podem ser recuperados quando o microcontrolador acorda usando os comandos

readF4Sleep ();

readF5Sleep ();

Essas funções leem o registro correspondente, deslocam o conteúdo para remover os 2 LSBs e retornam os 6 bits restantes. Essas funções são usadas no esboço de exemplo powerSaverPressureAndTemperatureESP.ino da seguinte maneira:

// leia o valor de EventCounter de volta de bmp0

byte bmp0F4value = bmp0.readF4Sleep (); // 0 a 63 bytes bmp0F5value = bmp0.readF5Sleep (); // 0 a 63 eventCounter = bmp0F5value * 64 + bmp0F4value; // 0 a 4095

Essas funções leem o registro correspondente, deslocam o conteúdo para remover os 2 LSBs e retornam os 6 bits restantes. Essas funções são usadas no esboço de exemplo powerSaverPressureAndTemperature.ino da seguinte maneira:

// leia o valor de EventCounter de volta de bmp1

byte bmp1F4value = bmp1.readF4Sleep (); // 0 a 63 bytes bmp1F5value = bmp1.readF5Sleep (); // 0 a 63 eventCounter = bmp1F5value * 64 + bmp1F4value; // 0 a 4095

Temperatura bruta e funções de pressão

As funções básicas readTemperature, readPressure e readHumidity têm dois componentes. Primeiro, os valores brutos de temperatura e pressão de 20 bits são obtidos no BME / P280 ou o valor bruto de umidade de 16 bits é obtido no BME280. Em seguida, o algoritmo de compensação é usado para gerar os valores de saída em graus Celsius, hPa ou% UR.

A biblioteca fornece funções separadas para esses componentes, de modo que os dados brutos de temperatura, pressão e umidade possam ser obtidos e talvez manipulados de alguma forma. O algoritmo para derivar a temperatura, pressão e umidade desses valores brutos também é fornecido. Na biblioteca, esses algoritmos são implementados usando aritmética de ponto flutuante de comprimento duplo. Ele funciona bem no ESP8266, que é um processador de 32 bits e usa 64 bits para variáveis float "duplas". Tornar essas funções acessíveis pode ser útil para avaliar e possivelmente alterar o cálculo para outras plataformas.

Essas funções são:

readRawPressure (rawTemperature); // lê os dados brutos de pressão e temperatura de BME / P280readRawHumidity (rawTemperature, rawPressure); // lê os dados brutos de umidade, temperatura e pressão do BME280 calcTemperature (rawTemperature, t_fine); calcPressure (rawPressure, t_fine); calcHumidity (rawHumidity, t_fine)

O argumento "t-fine" para essas funções vale um pouco de explicação. Os algoritmos de compensação de pressão e umidade incluem um componente dependente da temperatura que é obtido por meio da variável t_fine. A função calcTemperature grava um valor em t_fine com base na lógica do algoritmo de compensação de temperatura, que é então usado como uma entrada em calcPressure e calcHumidity.

Um exemplo do uso dessas funções pode ser encontrado no esboço de exemplo rawPressureAndTemperature.ino, e também no código para a função readHumidity () no arquivo.cpp da biblioteca.

Altitude e pressão ao nível do mar

Existe uma relação conhecida entre pressão atmosférica e altitude. O clima também influencia a pressão. Quando as organizações meteorológicas publicam informações sobre a pressão atmosférica, elas geralmente as ajustam para a altitude e, portanto, o "gráfico sinótico" mostra isóbaras (linhas de pressão constante) padronizadas para significar o nível do mar. Portanto, realmente existem 3 valores nesta relação, e saber dois deles permite a derivação do terceiro. Os 3 valores são:

  • altitude acima do nível do mar
  • pressão do ar real naquela altitude
  • pressão atmosférica equivalente ao nível do mar (mais estritamente, nível médio do mar, porque o nível do mar instantâneo muda constantemente)

Esta biblioteca fornece duas funções para esse relacionamento, como segue:

calcAltitude (pressão, seaLevelhPa);

calcNormalisedPressure (pressão, altitude);

Há também uma versão simplificada, que assume a pressão padrão ao nível do mar de 1013,15 hPa.

calcAltitude (pressão); // padrão seaLevelPressure assumido

Etapa 3: detalhes do dispositivo BMP280

Detalhes do dispositivo BMP280
Detalhes do dispositivo BMP280

Capacidades de hardware

O BMP280 tem 2 bytes de dados de configuração (nos endereços de registro 0xF4 e 0xF5) que são usados para controlar várias opções de medição e saída de dados. Ele também fornece 2 bits de informações de status e 24 bytes de parâmetros de calibração que são usados na conversão dos valores brutos de temperatura e pressão em unidades convencionais de temperatura e pressão. O BME280 tem dados adicionais como segue:

  • 1 byte extra de dados de configuração no endereço de registro 0xF2 usado para controlar várias medições de umidade;
  • 8 bytes extras de parâmetros de calibração usados na conversão do valor de umidade bruta em porcentagem de umidade relativa.

Os registros de temperatura, pressão e status para o BME280 são iguais aos do BMP280, com pequenas exceções, como segue:

  • os bits de "ID" do BME280 são definidos como 0x60, então ele pode ser diferenciado do BMP280 que pode ser 0x56, 0x57 ou 0x58
  • o controle do tempo de sono (t_sb) é alterado para que os dois tempos longos no BMP280 (2000 ms e 4000 ms) sejam substituídos no BME280 por tempos curtos de 10 ms e 20 ms. O tempo máximo de hibernação no BME280 é de 1000 ms.
  • No BME280, os valores brutos de temperatura e pressão são sempre 20 bits se a filtragem for aplicada. O uso de valores de 16 a 19 bits é limitado a casos sem filtragem (ou seja, filtro = 0).

Temperatura e pressão são valores de 20 bits cada, que precisam ser convertidos em temperatura e pressão convencionais por meio de um algoritmo bastante complexo usando 3 parâmetros de calibração de 16 bits para temperatura e 9 parâmetros de calibração de 16 bits mais a temperatura para pressão. A granulatidade da medição de temperatura é de 0,0003 graus Celsius para uma mudança de bit menos significativa (leitura de 20 bits), aumentando para 0,0046 graus Celsius se a leitura de 16 bits for usada.

A umidade é um valor de 16 bits que precisa ser convertido em umidade relativa por meio de outro algoritmo complexo usando 6 parâmetros de calibração que são uma mistura de 8, 12 e 16 bits.

A folha de dados mostra a precisão absoluta da leitura de temperatura como + -0,5 C a 25 C e + -1 C no intervalo de 0 a 65 C.

A granularidade da medição de pressão é 0,15 Pascais (ou seja, 0,0015 hectoPascais) com resolução de 20 bits ou 2,5 Pascais com resolução de 16 bits. O valor bruto da pressão é afetado pela temperatura, de modo que, em torno de 25 ° C, um aumento na temperatura de 1 grau C diminui a pressão medida em 24 Pascais. A sensibilidade à temperatura é considerada no algoritmo de calibração, portanto, os valores de pressão fornecidos devem ser precisos em diferentes temperaturas.

A folha de dados mostra a precisão absoluta da leitura da pressão como + -1 hPa para temperaturas entre 0 C e 65 C.

A precisão da umidade é fornecida na folha de dados como + -3% UR e + -1% histerese.

Como funciona

Os 24 bytes de dados de calibração de temperatura e pressão, e também no caso do BME280 os 8 bytes de dados de calibração de umidade, devem ser lidos do dispositivo e armazenados em variáveis. Esses dados são programados individualmente no dispositivo na fábrica, portanto, dispositivos diferentes têm valores diferentes - pelo menos para alguns dos parâmetros. Um BME / P280 pode estar em um de dois estados. Em um estado, ele está medindo. No outro estado, ele está esperando (dormindo).

Em qual estado ele está pode ser verificado olhando o bit 3 do registro 0xF3.

Os resultados da medição mais recente podem ser obtidos a qualquer momento pela leitura do valor de dados correspondente, independentemente de o dispositivo estar dormindo ou medindo.

Existem também duas maneiras de operar o BME / P280. Um é o modo Contínuo (denominado modo Normal na planilha de dados), que alterna repetidamente entre os estados de Medição e Dormir. Nesse modo, o dispositivo executa um conjunto de medições, depois entra em hibernação, acorda para outro conjunto de medições e assim por diante. O número de medições individuais e a duração da parte do sono do ciclo podem ser controlados por meio dos registros de configuração.

A outra forma de operar o BME / P280 é o modo de disparo único (denominado modo forçado na planilha de dados). Neste modo, o dispositivo é acordado do sono por um comando para medir, ele faz um conjunto de medições e depois volta a dormir. O número de medições individuais no conjunto é controlado no comando de configuração que desperta o dispositivo.

No BMP280, se uma única medição for feita, os 16 bits mais significativos no valor são preenchidos e os quatro bits menos significativos na leitura do valor são todos zeros. O número de medições pode ser definido como 1, 2, 4, 8 ou 16 e conforme o número de medições aumenta, o número de bits preenchidos com dados aumenta, de modo que com 16 medições todos os 20 bits são preenchidos com dados de medição. A folha de dados se refere a este processo como sobreamostragem.

No BME280, o mesmo arranjo se aplica, desde que o resultado não esteja sendo filtrado. Se a filtragem for usada, os valores são sempre 20 bits, independentemente de quantas medições são feitas em cada ciclo de medição.

Cada medição individual leva cerca de 2 milissegundos (valor típico; o valor máximo é 2,3 ms). Adicione a isso um overhead fixo de cerca de 2 ms (geralmente um pouco menos) significa que uma sequência de medição, que pode consistir de 1 a 32 medições individuais, pode levar de 4 ms a 66 ms.

A folha de dados fornece um conjunto de combinações recomendadas de sobreamostragem de temperatura e pressão para várias aplicações.

Registros de controle de configuração

Os dois registros de controle de configuração no BMP280 estão nos endereços de registro 0xF4 e 0xF5 e são mapeados em 6 valores de controle de configuração individuais. 0xF4 consiste em:

  • 3 bits osrs_t (mede a temperatura 0, 1, 2, 4, 8 ou 16 vezes);
  • 3 bits osrs_p (medir pressão 0, 1, 2, 4, 8 ou 16 vezes); e
  • Modo de 2 bits (Suspensão, Forçado (ou seja, Single Shot), Normal (ou seja, contínuo).

0xF5 consiste em:

  • 3 bits t_sb (tempo de espera, 0,5 ms a 4000 ms);
  • Filtro de 3 bits (veja abaixo); e
  • 1 bit spiw_en que seleciona SPI ou I2C.

O parâmetro de filtro controla um tipo de algoritmo de decaimento exponencial, ou filtro Infinite Impulse Response (IIR), aplicado aos valores de medição de pressão e temperatura brutos (mas não aos valores de umidade). A equação é fornecida na folha de dados. Outra apresentação é:

Valor (n) = Valor (n-1) * (K-1) / K + medição (n) / K

onde (n) indica a medição mais recente e o valor de saída; e K é o parâmetro do filtro. O parâmetro de filtro K e pode ser definido como 1, 2, 4, 8 ou 16. Se K for definido como 1, a equação torna-se apenas Valor (n) = medição (n). A codificação do parâmetro de filtro é:

  • filtro = 000, K = 1
  • filtro = 001, K = 2
  • filtro = 010, K = 4
  • filtro = 011, K = 8
  • filtro = 1xx, K = 16

O BME 280 adiciona mais um registro de controle de configuração no endereço 0xF2, "ctrl_hum" com um único parâmetro de 3 bits osrs_h (mede a umidade 0, 1, 2, 4, 8 ou 16 vezes).

Etapa 4: Medição e tempo de leitura

Pretendo adicionar isso mais tarde, mostrando o tempo dos comandos e as respostas das medições.

Iddt - corrente na medição de temperatura. Valor típico 325 uA

Iddp - corrente na medição de pressão. Valor típico 720 uA, máximo 1120 uA

Iddsb - atual no modo de espera. Valor típico 0,2 uA, máx 0,5 uA

Iddsl - atual em modo de suspensão. Valor típico 0,1 uA, máx 0,3 uA

Etapa 5: Diretrizes de software

Diretrizes de software
Diretrizes de software
Diretrizes de software
Diretrizes de software

Modo Burst I2C

A folha de dados BMP280 fornece orientação sobre a leitura de dados (seção 3.9). Ele diz que "é altamente recomendável usar uma leitura intermitente e não endereçar cada registro individualmente. Isso evitará uma possível confusão de bytes pertencentes a diferentes medições e reduzirá o tráfego da interface." Nenhuma orientação é fornecida em relação à leitura dos parâmetros de compensação / calibração. Presumivelmente, eles não são um problema porque são estáticos e não mudam.

Esta biblioteca lê todos os valores contíguos em uma única operação de leitura - 24 bytes no caso dos parâmetros de compensação de temperatura e pressão, 6 bytes para temperatura e pressão combinadas e 8 bytes para umidade, temperatura e pressão combinadas. Quando a temperatura sozinha é verificada, apenas 3 bytes são lidos.

Uso de macros (#define etc.)

Não há macros nesta biblioteca além da macro usual "incluir guarda" da biblioteca, que evita a duplicação.

Todas as constantes são definidas usando a palavra-chave const e a impressão de depuração é controlada com funções C padrão.

Tem sido a fonte de alguma incerteza para mim, mas o conselho que recebo ao ler muitos posts sobre este assunto é que o uso de #define para declaração de constantes (pelo menos) e (provavelmente) controle de depuração de impressão é desnecessário e indesejável.

O caso para o uso de const em vez de #define é bastante claro - const usa os mesmos recursos de #define (ou seja, nil) e os valores resultantes seguem as regras de escopo, reduzindo assim a chance de erros.

O caso do controle de impressão de depuração é um pouco menos claro, porque da maneira que fiz isso significa que o código final contém a lógica para as instruções de impressão de depuração, embora nunca sejam exercidas. Se a biblioteca for usada em um grande projeto em um microcontrolador com memória muito limitada, isso pode se tornar um problema. Como meu desenvolvimento foi em um ESP8266 com uma grande memória flash, isso não parecia ser um problema para mim.

Etapa 6: Desempenho de temperatura

Eu pretendo adicionar isso mais tarde.

Etapa 7: Desempenho de pressão

Eu pretendo adicionar isso mais tarde.

Recomendado: