Índice:

Um Micro: bit Dive-O-Meter: 8 etapas (com imagens)
Um Micro: bit Dive-O-Meter: 8 etapas (com imagens)

Vídeo: Um Micro: bit Dive-O-Meter: 8 etapas (com imagens)

Vídeo: Um Micro: bit Dive-O-Meter: 8 etapas (com imagens)
Vídeo: Como remover a proteção contra gravação de Pen Drive no Windows? | Recoverit 2024, Novembro
Anonim
Um Micro: bit Dive-O-Meter
Um Micro: bit Dive-O-Meter
Um Micro: bit Dive-O-Meter
Um Micro: bit Dive-O-Meter
Um Micro: bit Dive-O-Meter
Um Micro: bit Dive-O-Meter

O verão está aqui, é hora da piscina!

Uma boa oportunidade para levar a si e ao seu micro: morde fora, e neste caso até dentro da piscina.

O micro: bit dive-o-meter descrito aqui é um medidor de profundidade DIY simples que permite medir a profundidade do mergulho. Consiste apenas em um micro: bit, um pack de bateria ou LiPo, um conector de borda para o micro: bit, um sensor de pressão barométrica BMP280 ou BME280 e alguns cabos de ligação. Usando o enviro Pimoroni: bit faz as coisas cada vez mais simples. Tudo isso é embalado em duas camadas de plástico transparente à prova d'água ou sacos de silicone, com alguns pesos adicionados para compensar a força de flutuação.

É uma aplicação do dispositivo sensor de pressão micro: bit que eu havia descrito em um instrutível anterior.

Você pode usar o dispositivo e. g. para competições de mergulho com amigos e família, ou para descobrir a profundidade daquele lago. Eu testei usando a piscina mais funda da minha vizinhança e descobri que funciona a pelo menos 3,2 metros de profundidade. Cerca de cinco metros é o máximo teórico. Até agora não testei sua precisão em nenhum detalhe, mas os números relatados estavam pelo menos na faixa esperada.

Algumas observações: Esta não é uma ferramenta para mergulhadores de verdade. Seu micro: bit ficará danificado se molhar. Você usa este instrutível por sua própria conta e risco.

Atualização de 27 de maio: agora você pode encontrar um script MakeCode HEX que pode carregar diretamente em seu micro: bit. Veja a etapa 6. Atualizar em 13 de junho: Um Enviro: bit e uma versão de cabo adicionados. Veja as etapas 7 e 8

Etapa 1: a teoria por trás do dispositivo

Estamos vivendo no fundo de um oceano de ar. A pressão aqui embaixo é de cerca de 1020 hPa (hectoPascal), já que o peso da coluna de ar formada aqui para o espaço é de cerca de 1 kg por centímetro quadrado.

A densidade da água é muito maior, pois um litro de ar pesa cerca de 1,2 ge um litro de água 1 kg, ou seja, cerca de 800 vezes. Assim, como a queda na pressão barométrica é de cerca de 1 hPa para cada 8 metros de altura, o ganho de pressão é de 1 hPa para cada centímetro abaixo da superfície da água. A uma profundidade de cerca de 10 m, a pressão é de 2.000 hPa, ou duas atmosferas.

O sensor de pressão usado aqui tem uma faixa de medição entre 750 e 1500 hPa com uma resolução de cerca de um hPa. Isso significa que podemos medir profundidades de até 5 metros com uma resolução de cerca de 1 cm.

O dispositivo seria um medidor de profundidade do tipo Boyle Marriotte. Sua montagem é bastante simples e descrita em uma etapa posterior. O sensor usa o protocolo I2C, portanto, um conector de borda para o micro: bit é útil. A parte mais crítica são as bolsas estanques, pois qualquer umidade irá danificar a micro: broca, o sensor ou a bateria. Como parte do ar ficará preso dentro das bolsas, a adição de pesos ajuda a compensar a força de flutuação.

Etapa 2: usando o dispositivo

Usando o dispositivo
Usando o dispositivo
Usando o dispositivo
Usando o dispositivo
Usando o dispositivo
Usando o dispositivo
Usando o dispositivo
Usando o dispositivo

O script, conforme mostrado em detalhes em uma etapa posterior, é uma variação de um script que desenvolvi anteriormente para um medidor de pressão. Para testar o dispositivo, você pode usar a câmara de pressão simples descrita lá.

Para fins de mergulho, mostra a profundidade em metros, calculada a partir das medições de pressão, seja como um gráfico de barras em passos de 20 cm ou, a pedido, em números.

Usando o botão A no micro: bit, você definirá a pressão atual como valor de pressão de referência. Para confirmar a entrada, a matriz pisca uma vez.

Você pode usar isso para ver a que profundidade está mergulhando ou para registrar a que profundidade está mergulhando.

No primeiro caso, defina a pressão do ar externo atual como referência. No segundo caso, defina a pressão no ponto mais profundo em que você era a referência de pressão, o que então permite que você mostre o quão profundo você esteve quando voltou à superfície. O botão B exibe a profundidade, calculada a partir da diferença de pressão, como um valor numérico em metros.

Etapa 3: Materiais necessários

Materiais requisitados
Materiais requisitados
Materiais requisitados
Materiais requisitados
Materiais requisitados
Materiais requisitados

Um micro: bit. Por exemplo. a 13 GBP / 16 euros na Pimoroni UK / DE.

Um conector de borda (Kitronic ou Pimoroni), 5 GBP. Usei a versão Kitronic.

Um sensor BMP / BME280. Usei um sensor BMP280 da Banggood, 4,33 euros para três unidades.

Cabos de jumpers para conectar o sensor e o conector de borda.

Uma excelente alternativa para a combinação de conector de borda / sensor acima poderia ser Pimoroni enviro: bit (ainda não testado, veja a última etapa).

Uma bateria ou LiPo para o micro: bit.

Um cabo de alimentação com um interruptor (opcional, mas útil). Bolsas impermeáveis claras. Usei uma bolsa de silicone para um telefone celular e uma ou duas pequenas bolsas ziploc. Certifique-se de que o material seja espesso o suficiente para que os pinos no conector da borda não danifiquem as bolsas.

Alguns pesos. Usei pedaços de peso de chumbo que são usados para pescar.

Arduino IDE e várias bibliotecas.

Etapa 4: Montagem

conjunto
conjunto
conjunto
conjunto
conjunto
conjunto
conjunto
conjunto

Instale o Arduino IDE e as bibliotecas necessárias. Os detalhes são descritos aqui.

(Não é necessário para o script MakeCode.) Se você usar o conector de borda Kitronik, solde os pinos nas portas I2C 19 e 20. Isso não é necessário para o conector de borda Pimoroni. Solde o cabeçalho para a ruptura do sensor e conecte o sensor e o conector de borda usando cabos de jumper. Conecte VCC a 3V, GND a 0 V, SCL à porta 19 e SDA à porta 20. Como alternativa, solde os cabos diretamente na divisão. Conecte o micro: bit ao nosso computador por um cabo USB. Abra o script fornecido e atualize-o no micro: bit. Use o monitor serial ou plotter, verifique se o sensor fornece dados razoáveis. Desconecte o micro: bit do computador. Conecte a bateria ou LiPo ao micro: bit. Pressione o botão B, leia o valor Pressione o botão A. Pressione o botão B, leia o valor. Coloque o dispositivo em duas camadas de sacos herméticos, deixando muito pouco ar nos sacos. No caso, coloque um peso para compensar a força de empuxo. Verifique se está tudo estanque. Vá para a piscina e brinque.

Etapa 5: o script MicroPython

O script apenas pega o valor da pressão do sensor, compara-o ao valor de referência e calcula a profundidade a partir da diferença. Para exibir os valores como um gráfico de barras, o inteiro e a parte restante do valor de profundidade são considerados. O primeiro define a altura da linha. O restante é dividido em cinco caixas, que definem o comprimento das barras. O nível superior é 0 - 1 m, o mais baixo 4 - 5 m. Como mencionado antes, pressionar o botão A define a pressão de referência, o botão B exibe a "profundidade relativa" em metros, exibida como um valor numérico. Neste momento, os valores negativos e positivos são apresentados como gráfico de barras na matriz de LED da mesma forma. Sinta-se à vontade para otimizar o script de acordo com suas necessidades. Você pode ativar o som de certas linhas para apresentar os valores no monitor serial ou plotadora do IDE do Arduino. Para emular a função, você pode construir o dispositivo que descrevi em um instrutível anterior.

Não escrevi a parte do script que lê o sensor. Não tenho certeza da fonte, mas gostaria de agradecer aos autores. Quaisquer correções ou dicas para otimização são bem-vindas.

#incluir

#include Adafruit_Microbit_Matrix microbit; #define BME280_ADDRESS 0x76 unsigned long int hum_raw, temp_raw, pres_raw; assinado longo int t_fine; uint16_t dig_T1; int16_t dig_T2; int16_t dig_T3; uint16_t dig_P1; int16_t dig_P2; int16_t dig_P3; int16_t dig_P4; int16_t dig_P5; int16_t dig_P6; int16_t dig_P7; int16_t dig_P8; int16_t dig_P9; int8_t dig_H1; int16_t dig_H2; int8_t dig_H3; int16_t dig_H4; int16_t dig_H5; int8_t dig_H6; press_norm duplo = 1015; // um valor inicial double depth; // profundidade calculada // -------------------------------------------- -------------------------------------------------- ---------------------- void setup () {uint8_t osrs_t = 1; // Sobreamostragem de temperatura x 1 uint8_t osrs_p = 1; // Sobreamostragem de pressão x 1 uint8_t osrs_h = 1; // Sobreamostragem de umidade x 1 uint8_t mode = 3; // Modo normal uint8_t t_sb = 5; // Tstandby 1000ms uint8_t filter = 0; // Filtrar uint8_t spi3w_en = 0; // Desativar SPI de 3 fios uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | modo; uint8_t config_reg = (t_sb << 5) | (filtro << 2) | spi3w_en; uint8_t ctrl_hum_reg = osrs_h; pinMode (PIN_BUTTON_A, INPUT); pinMode (PIN_BUTTON_B, INPUT); Serial.begin (9600); // define a velocidade da porta serial Serial.print ("Pressure [hPa]"); // cabeçalho para saída serial Wire.begin (); writeReg (0xF2, ctrl_hum_reg); writeReg (0xF4, ctrl_meas_reg); writeReg (0xF5, config_reg); readTrim (); // microbit.begin (); // microbit.print ("x"); atraso (1000); } // ----------------------------------------------- ---------------------------------------------- void loop () {dupla temp_act = 0,0, press_act = 0,0, hum_act = 0,0; assinado longo int temp_cal; sem sinal longo int press_cal, hum_cal; int N; int M; double press_delta; // pressão relativa int depth_m; // profundidade em metros, parte inteira double depth_cm; // resto em cm readData (); // temp_cal = calibração_T (temp_raw); press_cal = calibração_P (pres_raw); // hum_cal = calibração_H (hum_raw); // temp_act = (double) temp_cal / 100.0; press_act = (duplo) press_cal / 100.0; // hum_act = (double) hum_cal / 1024.0; microbit.clear (); // redefinir a matriz de LED // Botão A define o valor real como referência (P zero) // Botão B exibe o valor atual como profundidade em metros (calculado a partir da diferença de pressão) if (! digitalRead (PIN_BUTTON_A)) {// definir a pressão de ar normal como zero press_norm = press_act; // microbit.print ("P0:"); // microbit.print (press_norm, 0); // microbit.print ("hPa"); microbit.fillScreen (LED_ON); // pisca uma vez para confirmar delay (100); } else if (! digitalRead (PIN_BUTTON_B)) {// exibe a profundidade em metros microbit.print (depth, 2); microbit.print ("m"); // Serial.println (""); } else {// calcula a profundidade da diferença de pressão press_delta = (press_act - press_norm); // calcula a profundidade de pressão relativa = (press_delta / 100); // profundidade em metros depth_m = int (abs (depth)); // profundidade em metros profundidade_cm = (abs (profundidade) - profundidade_m); // resto / * // usado para desenvolvimento Serial.println (profundidade); Serial.println (profundidade_m); Serial.println (profundidade_cm); * / // Passos para o gráfico de barras if (depth_cm> 0.8) {// definir o comprimento das barras (N = 4); } else if (depth_cm> 0.6) {(N = 3); } else if (depth_cm> 0.4) {(N = 2); } else if (depth_cm> 0.2) {(N = 1); } else {(N = 0); }

if (depth_m == 4) {// definir nível == metro

(M = 4); } else if (depth_m == 3) {(M = 3); } else if (depth_m == 2) {(M = 2); } else if (depth_m == 1) {(M = 1); } else {(M = 0); // linha superior} / * // usado para fins de desenvolvimento Serial.print ("m:"); Serial.println (profundidade_m); Serial.print ("cm:"); Serial.println (profundidade_cm); Serial.print ("M:"); Serial.println (M); // para fins de desenvolvimento Serial.print ("N:"); Serial.println (N); // para fins de desenvolvimento delay (500); * / // desenhar o gráfico de barras microbit.drawLine (0, M, N, M, LED_ON); }

// envia o valor para a porta serial do plotter

Serial.print (press_delta); // desenha as linhas do indicador e fixa o intervalo exibido Serial.print ("\ t"); Serial.print (0); Serial.print ("\ t"); Serial.print (-500); Serial.print ("\ t"); Serial.println (500); atraso (500); // Meça duas vezes por segundo} // ----------------------------------------- -------------------------------------------------- -------------------------------------------------- -------- // o seguinte é necessário para o sensor bmp / bme280, mantenha como é void readTrim () {uint8_t data [32], i = 0; // Fix 2014 / Wire.beginTransmission (BME280_ADDRESS); Wire.write (0x88); Wire.endTransmission (); Wire.requestFrom (BME280_ADDRESS, 24); // Correção de 2014 / while (Wire.available ()) {data = Wire.read (); i ++; } Wire.beginTransmission (BME280_ADDRESS); // Adicionar 2014 / Wire.write (0xA1); // Adicionar 2014 / Wire.endTransmission (); // Adicionar 2014 / Wire.requestFrom (BME280_ADDRESS, 1); // Adicionar 2014 / data = Wire.read (); // Adicionar 2014 / i ++; // Adicionar 2014 / Wire.beginTransmission (BME280_ADDRESS); Wire.write (0xE1); Wire.endTransmission (); Wire.requestFrom (BME280_ADDRESS, 7); // Correção de 2014 / while (Wire.available ()) {data = Wire.read (); i ++; } dig_T1 = (dados [1] << 8) | dados [0]; dig_P1 = (dados [7] << 8) | dados [6]; dig_P2 = (dados [9] << 8) | dados [8]; dig_P3 = (dados [11] << 8) | dados [10]; dig_P4 = (dados [13] << 8) | dados [12]; dig_P5 = (dados [15] << 8) | dados [14]; dig_P6 = (dados [17] << 8) | dados [16]; dig_P7 = (dados [19] << 8) | dados [18]; dig_T2 = (dados [3] << 8) | dados [2]; dig_T3 = (dados [5] << 8) | dados [4]; dig_P8 = (dados [21] << 8) | dados [20]; dig_P9 = (dados [23] << 8) | dados [22]; dig_H1 = dados [24]; dig_H2 = (dados [26] << 8) | dados [25]; dig_H3 = dados [27]; dig_H4 = (dados [28] << 4) | (0x0F e dados [29]); dig_H5 = (dados [30] 4) & 0x0F); // Fix 2014 / dig_H6 = data [31]; // Corrige 2014 /} void writeReg (uint8_t reg_address, uint8_t data) {Wire.beginTransmission (BME280_ADDRESS); Wire.write (reg_address); Wire.write (dados); Wire.endTransmission (); } void readData () {int i = 0; dados uint32_t [8]; Wire.beginTransmission (BME280_ADDRESS); Wire.write (0xF7); Wire.endTransmission (); Wire.requestFrom (BME280_ADDRESS, 8); while (Wire.available ()) {data = Wire.read (); i ++; } pres_raw = (dados [0] << 12) | (dados [1] 4); temp_raw = (dados [3] << 12) | (dados [4] 4); hum_raw = (dados [6] 3) - ((int longo assinado) dig_T1 11; var2 = (((((adc_T >> 4) - ((int longo assinado) dig_T1)) * ((adc_T >> 4) - ((int longo assinado) dig_T1))) >> 12) * ((int longo assinado) dig_T3)) >> 14; t_fina = var1 + var2; T = (t_fino * 5 + 128) >> 8; return T; } calibração int longo sem sinal_P (int longo sinalizado_P) {int longo assinado var1, var2; int longo não assinado P; var1 = (((int longo assinado) t_fino) >> 1) - (int longo assinado) 64000; var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((int longo assinado) dig_P6); var2 = var2 + ((var1 * ((int longo assinado) dig_P5)) 2) + (((int longo assinado) dig_P4) 2) * (var1 >> 2)) >> 13)) >> 3) + ((((int longo assinado) dig_P2) * var1) >> 1)) >> 18; var1 = ((((32768 + var1)) * ((int longo assinado) dig_P1)) >> 15); if (var1 == 0) {return 0; } P = (((int longo sem sinal) (((int longo assinado) 1048576) -adc_P) - (var2 >> 12))) * 3125; if (P <0x80000000) {P = (P << 1) / ((int longo sem sinal) var1); } else {P = (P / (int longo sem sinal) var1) * 2; } var1 = (((int longo com sinal) dig_P9) * ((int longo com sinal) (((P >> 3) * (P >> 3)) >> 13))) >> 12; var2 = (((int longo assinado) (P >> 2)) * ((int longo assinado) dig_P8)) >> 13; P = (int longo sem sinal) ((int longo assinado) P + ((var1 + var2 + dig_P7) >> 4)); return P; } sem sinal longo int calibração_H (assinado longo int adc_H) {assinado longo int v_x1; v_x1 = (t_fine - ((int longo assinado) 76800)); v_x1 = (((((adc_H << 14) - (((int longo assinado) dig_H4) 15) * (((((((v_x1) * ((int longo assinado) dig_H6)) >> 10) * (((v_x1 * ((int longo assinado) dig_H3)) >> 11) + ((int longo assinado) 32768))) >> 10) + ((int longo assinado) 2097152)) * ((int longo assinado) dig_H2) + 8192) >> 14)); v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((int longo assinado) dig_H1)) >> 4)); v_x1 = (v_x1 419430400? 419430400: v_x1); return (int longo sem sinal) (v_x1 >> 12);

Etapa 6: Uma grande simplificação: o código MakeCode / JavaScript

Uma grande simplificação: o código MakeCode / JavaScript
Uma grande simplificação: o código MakeCode / JavaScript
Uma grande simplificação: o código MakeCode / JavaScript
Uma grande simplificação: o código MakeCode / JavaScript

Em maio de 2018, a Pimoroni lançou o enviro: bit, que vem com um sensor de pressão / umidade / temperatura BME280, um sensor de luz e cor TCS3472 e um microfone MEMS. Além disso, eles estão oferecendo uma biblioteca JavaScript para o editor MakeCode e uma biblioteca MicroPython para esses sensores.

Tenho usado sua biblioteca MakeCode para desenvolver scripts para o meu dispositivo. Em anexo você encontra os respectivos arquivos hexadecimais, que você pode copiar diretamente para o seu micro: bit.

Abaixo você encontra o código JavaScript correspondente. O teste no pool funcionou bem com uma versão anterior do script, portanto, presumo que também funcionará. Além da versão básica, em gráfico de barras, há também uma versão em cruz (X) e uma versão L, destinadas a facilitar a leitura, especialmente em condições de pouca luz. Escolha o que você preferir.

deixe Coluna = 0

let Meter = 0 let stay = 0 let Row = 0 let Delta = 0 let Ref = 0 let Is = 0 Is = 1012 basic.showLeds (`# # # # # # #… # #. #. # #… # # # # # # # `) Ref = 1180 basic.clearScreen () basic.forever (() => {basic.clearScreen () if (input.buttonIsPressed (Button. A)) {Ref = envirobit.getPressure () basic.showLeds (`#. #. #. #. #. #. # # # # #. #. #. #. #. #`) basic.pause (1000)} else if (input.buttonIsPressed (Button. B)) {basic.showString ("" + Row + "." + permanecer + "m") basic.pause (200) basic.clearScreen ()} else {Is = envirobit.getPressure () Delta = Is - Ref Meter = Math.abs (Delta) if (Medidor> = 400) {Linha = 4} else if (Medidor> = 300) {Linha = 3} else if (Medidor> = 200) {Linha = 2} else if (Medidor> = 100) {Linha = 1} else {Linha = 0} permanece = Medidor - Linha * 100 if (permanecer> = 80) {Coluna = 4} else if (permanecer> = 60) {Coluna = 3} else if (permanecer> = 40) {Coluna = 2} else if (permanecer> = 20) {Coluna = 1} else {Coluna = 0} para (deixe ColA = 0; ColA <= Coluna; ColA ++) {led.plot (C olA, Row)} basic.pause (500)}})

Etapa 7: O Enviro: versão bit

O Enviro: versão bit
O Enviro: versão bit
O Enviro: versão bit
O Enviro: versão bit
O Enviro: versão bit
O Enviro: versão bit

Entretanto recebi o enviro: bit (20 GBP) e o power: bit (6 GBP), ambos da Pimoroni.

Como mencionado antes, o enviro: bit vem com o sensor BME280 de pressão, umidade e temperatura, mas também um sensor de luz e cor (veja uma aplicação aqui) e um microfone MEMS.

O power: bit é uma boa solução para alimentar o micro: bit e vem com um botão liga / desliga.

O bom é que ambos são apenas clique e use, sem solda, cabos, placas de ensaio. Adicione o enviro: bit ao micro: bit, carregue seu código no micro: bit, use-o.

Neste caso usei micro, power e enviro: bit, coloquei em um saco Ziploc, coloquei em um saco plástico transparente impermeável para celulares, pronto. Uma solução muito rápida e organizada. Veja as fotos. O switch é grande o suficiente para ser usado através das camadas de proteção.

Foi testado na água e funcionou bem. A uma profundidade de cerca de 1,8 m, o valor medido foi de cerca de 1,7 m. Nada mal para uma solução rápida e barata, mas está longe de ser perfeita. O ajuste demora um pouco, então pode ser necessário permanecer em uma determinada profundidade por cerca de 10-15 segundos.

Etapa 8: Versão do cabo e da sonda do sensor

Versão da sonda de cabo e sensor
Versão da sonda de cabo e sensor
Versão do cabo e da sonda do sensor
Versão do cabo e da sonda do sensor

Na verdade, essa foi a primeira ideia que tive para um medidor de profundidade micro: bit, o último a ser construído.

Aqui eu soldei o sensor BMP280 a 5m de um cabo de 4 fios e coloquei o jumper fêmea na outra extremidade. Para proteger o sensor da água, o cabo foi passado através de uma rolha de vinho usada. As pontas da cortiça foram seladas com cola quente. Antes, eu havia feito dois entalhes na rolha, os dois contornando-a. Em seguida, envolvi o sensor em uma bola de esponja, coloquei um balão em volta dele e fixei a ponta do balão na rolha (entalhe inferior). em seguida, coloquei 3 peças de 40 g de pesos de chumbo em um segundo balão, enrolei-o ao redor do primeiro, os pesos colocados na parte externa e fixei a extremidade do balão no segundo entalhe. O ar foi retirado do segundo balão, depois tudo foi fixado com fita adesiva. Veja as imagens, outras mais detalhadas podem seguir.

Os jumpers foram conectados ao micro: bit por meio de um conector de borda, o dispositivo foi ligado e a pressão de referência foi ajustada. Em seguida, a cabeça do sensor foi liberada lentamente para o fundo da piscina (torre de salto de 10 m, cerca de 4,5 m de profundidade).

Resultados:

Para minha surpresa, funcionou mesmo com este cabo longo. Por outro lado, mas não surpreendentemente, o erro de medição parecia se tornar maior em pressões mais altas, e uma profundidade estimada de 4 m foi relatada como cerca de 3 m.

Aplicações potenciais:

Com algumas correções de erro, o dispositivo pode ser usado para medir a profundidade de cerca de 4 m.

Em conjunto com um Arduino ou Raspberry Pi, pode ser usado para medir e controlar o ponto de enchimento de uma piscina ou tanque de água, por exemplo. para evocar um aviso se os níveis de água ficarem acima ou abaixo de certos limites.

Desafio de condicionamento físico ao ar livre
Desafio de condicionamento físico ao ar livre
Desafio de condicionamento físico ao ar livre
Desafio de condicionamento físico ao ar livre

Vice-campeão no Desafio de Fitness ao Ar Livre

Recomendado: