[RESOLVIDO] Executar captura de um dado I2C quando pressionados 2 botões simultaneamente (altímetro digital)

Boa tarde, pessoal!

Esta é minha primeira participação aqui depois de um tempo afastado do mundo DIY....resolvi fazer um altímetro digital.

A ideia é utilizando um TTGO (ESP32) com um BMP280 eu consiga apresentar a altitude relativa ao solo.

O problema é que não estou sabendo como adquirir o dado de pressão local e inserir na variavel bmp.readAltitude(x) onde o x é o valor referencia de pressão a ser descontado. outro ponto é que para essa aquisição acontecer, gostaria que os dois botoes do TTGO (GPIO 0 e 35) fossem pressionados simultaneamente por 5 segundos.

No codigo atual eu usei o serial.print para checar resultado do delay do botão, porém segue um loop com o envio de "apertou" pela serial a cada 10 segundos independentemente do botão estar pressionado ou não.

alguem consegue me ajudar?

Segue .ino anexo

assim como descrição do circuito e no link abaixo também um video mostrando o funcionamento do altimetro com a função tft.print(bmp.readAltitude(970.9872)); calibrado pra pressão da minha casa

https://youtu.be/cUavhl_21UM

obrigado desde ja!

Exibições: 844

Anexos

Responder esta

Respostas a este tópico

Olá, tudo bem?

Antes de mais nada, recomendo remover o código da postagem, e deixa-lo apenas no .ino (alti_1.ino, no seu caso).

Veja, quando você for usar a biblioteca de alguém, é importante que você tenha calma e tente entender um pouco a lib. Normalmente o autor fornece um "código exemplo", então é legal brincar com ele antes de anexa-lo ao seu código principal, e quando eu digo "brincar", é testa-lo no seu circuito de forma isolada. Isso evita muitas dores de cabeça no futuro.

Com relação ao seu código: 

1) Não entendi o motivo de você "re-declarar" "botao1" e "botao2" no loop (linha 55 e 56), pois eles já estão declarados no setup (linha 24 e 25).

2) Com relação a chamada da altitude pela lib, é interessante ver o código de exemplo. Talvez você tenha deixado algo passar.

3) com relação ao i2c, você usou um scaner para verificar o endereço do seu chip?

4) É interessante que você apresente um esquema do seu circuito. Não precisa ser nada profissional, até uma imagem simples no paint resolve.

5) na linha 73, você escreveu a seguinte condição: " if (digitalRead (botao1 == HIGH)){ ... } ", entretanto, não é desta forma que a função funciona.

A função é escrita desta forma: digitalRead(PINO). Ela retorna HIGH/ALTO/1 ou LOW/BAIXO/0, entretanto você fez uma comparação no local destinado ao pino. Veja o que, em principio, independente do pino que você escolher, apenas o pino 0 será selecionado, veja o que vai acontecer com seu código:

Situação 1: Botao1

if (digitalRead (botao1 == HIGH))  // "Qual o valor da variável botao1?" R: 0

if (digitalRead (0 == 1))  // "0 é igual a 1?" R: Não. Então retorna "false / ZERO"

if (digitalRead (0)) // "Qual a leitura do botão FALSE/ZERO?"

if (0/1) // Se.... 0/1?

Situação 2: Botao2

if (digitalRead (botao2 == HIGH))  // "Qual o valor da variável botao2?" R: 35

if (digitalRead (35 == 1))  // "35 é igual a 1?" Não. Então retorna "false / ZERO"

if (digitalRead (0)) // "Qual a leitura do botão FALSE/ZERO?"

if (0/1) // Se.... 0/1?

Pela terceira linha das situações, em principio, ele deveria funcionar APENAS para o pino ZERO, mas pode ter algo ai no meio que eu não entendi. Independente de qualquer coisa perceba que, não importa qual o estado do botão ou o pino selecionado, pois você não faz uma comparação com o estado deles e TODOS os pinos que você colocar será "ajustado" para o pino 0 (em principio). E não é isso que você quer.

A forma correta de escrever é assim:

if (digitalRead(botao1) == HIGH) { ........ }

if (digitalRead(botao1) == LOW) { ........ }

Caso você queira que os DOIS botões sejam pressionados, você pode fazer de duas formas:

Primeira forma: (serve para compreender)

if (digitalRead(botao1) == HIGH) { 

// Se verdadeiro

if (digitalRead(botao2) == HIGH) { caso ambos sejam verdadeiros }

}

Segunda forma (menos sujo):

f ((digitalRead(botao1) == HIGH) && (digitalRead(botao2) == HIGH)){ 

// se ambos forem verdadeiro.

Para fins de conhecimento, a leitura da função segue assim:

- if (digitalRead (botao2) == HIGH) // Qual o valor da variável botao2? Resposta: 35

- if (digitalRead (35) == HIGH) // Qual o estado do pino 35? Resposta: LOW (exemplo)

- if (LOW == HIGH) // Se, BAIXO for igual a ALTO, retornará verdadeiro, então será dada a sequência ao código (neste exemplo, o código não será executado, pois retornará "falso")

Olá Tiago!

   Concordo com tudo o que você escreveu, inclusive achei muito boa a explicação do digitalRead().

   Com relação a duplicidade de declaração dos pinos, da forma como o O. P. ( Original Poster ) fez, declarando-os dentro do setup() e do loop(), são variáveis locais, ou seja, só são visíveis dentro das rotinas em que são declaradas.

   Isto quer dizer que, se só fossem declaradas em uma das rotinas e não na outra, daria erro de compilação na rotina em que não fossem declaradas, algo do tipo 'botao1' was not declared in this scope.

   Poderiam ter valores diferentes de uma rotina para outra.

   O ideal, no caso dos pinos do Arduino, é que sejam declaradas fora de qualquer rotina. Assim, serão variáveis globais e são visíveis em qualquer ponto do programa.

   Também com relação a especificação original do O. P., de que "gostaria que os dois botoes do TTGO (GPIO 0 e 35) fossem pressionados simultaneamente por 5 segundos.", da forma como o código corrigido que você sugeriu na Primeira forma e na Segunda forma, não há necessidade de simultaneidade, i. e., um botão pode ser pressionado primeiro e depois o outro.

   Isto pode não ser relevante pois, dependendo do que o O. P. quer, pode ser que basta que haja coincidência de acionamento dos botões durante 5 s, não importando se foram acionados simultaneamente ou não.

   No caso de máquinas industriais é diferente, pois a NR-10 é bem específica quanto a operação de sistemas conhecidos como Bi-Manuais ( TWC Two Hands Control ). Neste caso a simultaneidade de pressionamento dos botões é obrigatória.

   Claro que, sob o ponto de vista físico, de acordo com o princípio de incerteza de Heisenberg, simultaneidade não existe. Então, para este caso, considera-se simultâneos eventos que ocorreram com uma diferença de tempo de, no máximo, Delat-t milisegundos ( Não lembro quanto é o Delta-t :-)

D.T. Ribeiro.

D.T. Ribeiro.

Bem observado sobre as Var's. Esqueci desse detalhe (var local), principalmente por não ter o hábito de declarar pinos como constante. Ainda que já tenha visto códigos escritos assim, mas nunca entendi a real vantagem, tendo em vista que podemos defini-lo no topo como um #define. É mais simples, mais prático, escreve menos, consome menos espaço.

"Também com relação a especificação original..."

Sim, mas observe que nesta situação o que ele considera é que os dois botões estejam como alto, independente do botão 1 ou o botão 2 ter sido pressionado primeiro. ( 00 = false ; 01 = false ; 10 = false ; 11 = true ), logo, se ele levar 1 hora com o "botão 2" ALTO, e depois também pressionar o "botão 1", retornará como verdadeiro. Evidentemente, não incrementei debounce ou contador/atraso para os 5 segundos, pois interpretei que o foco imediato do autor devesse ser a compreensão do bug. 

"Isto pode não ser relevante pois, dependendo do que o O. P. quer..."

Bem observado, mesmo olhando mais para frente, não fui capaz de imaginar essa condição. Na verdade, nunca imaginei essa condição. Achei bastante interessante.

"No caso de máquinas industriais...  ...quanto é o Delta-t :-)"

Essa área meu conhecimento é zero. Passou de 5A ou 24v, eu já começo a ficar preocupado. 

Toda via, vivendo e aprendendo.

As observações de vocês foram ótimas! 

Muito obrigado pela explicação detalhada da função, inclusive!

Eu também não fazia a menor ideia de que tinha uma NR definindo necessidade de aperto simultaneo, mas faz total sentido quanto a segurança né....se não o cara vai la e trava um acionador com um toco de madeira e fica usando só um deles pra ativação do sistema....imputando em, por exemplo, risco de amputação ou algo do tipo

"e não o cara vai la e trava um acionador com um toco de madeira" kkkkkkkkkkkkkkkkkkkkk
Eu ri muito com essa.

Mas é real.

Tiago;

   E se eu te disser que isto é a coisa mais comum na indústria, aqui no Brasil, você acredita?

D.T. Ribeiro

D.T. Ribeiro;

Agora você me deixou pensativo.

Cara, o que a gebte recebe de amputado por isso no hosp não é brincadeira =/ 

Ola Tiago!!

Muito obrigado pela ajuda! Desculpe algumas falhas, estou começando aqui no forum hahaha

em relação a suas perguntas:

1) redeclarei errado ahahahah

2)então, eu vi que consigo o valor da pressão em Pa com a função bmp.readPressure(), mas não sei como posso fazer com que ao pressionar os dois botões por 5 segundos o programa tome como Pa_atual = esse valor e insira no tft.print(bmp.readAltitude(Pa_atual))

3) Sim, e ele retornou o endereço 0x76 declarado em status = bmp.begin(0x76)

4)Botei aqui como anexo

5)Pensei em usar a função millis dando mais uma estudadinha aqui....dai não para o programa né...

Nesse caso ficaria algo como

long tempo_acionado = 5000;
unsigned long ultimo_tempo = 0

unsigned long tempo_atual = millis();

if ((digitalRead(botao1) == HIGH) && (digitalRead(botao2) == HIGH)){ 

// se ambos forem verdadeiros.

if(tempo_atual - ultimo_tempo >= tempo_acionado)
{

dai ele pega o valor de bmp.readPressure() e declara como valor de Pa_atual

To engatinhando nisso ainda ahauhauahuahua mas tamo tentando 

Anexos

2)então, eu vi que consigo o valor da pressão em Pa com a função bmp.readPressure(), mas não sei como posso fazer com que ao pressionar os dois botões por 5 segundos o programa tome como Pa_atual = esse valor e insira no tft.print(bmp.readAltitude(Pa_atual))

Veja, eu não parei para estudar o código do autor, olhei apenas o exemplo (link aqui), em todo caso, ele fornece apenas 3 funções:

bmp.readTemperature(): 

bmp.readPressure(): 

bmp.readAltitude(var): 

O primeiro retornará em ºc, o segundo retorna em PA, e o terceiro retorna em metros.

Gostaria de lhe pedir que rodasse o exemplo do autor, e me informasse o que é impresso na serial.

Estou curioso para saber o valor que ele retorna em bmp.readPressure(), pois em princípio você poderia fazer algo como:

float valor_PA; //global

valor_PA = bmp.readPressure(): // quando pressionado os dois botões

bmp.readAltitude(valor_PA);

5)Pensei em usar a função millis dando...

Essa função é muito legal, recomendo você conhece-la para usar neste e em projetos futuros.

No monitor serial as informações retornam da seguinte forma:

Temperature = 31.43 *C
Pressure = 92894.78 Pa
Approx altitude = 726.78 m

Bom dia, 

Se você esta iniciando, sugiro que estude e teste tutorais sem mudar nada. 

https://randomnerdtutorials.com/solved-could-not-find-a-valid-bme28...

Depois que tudo estiver funcionando e você ter aprendido como o sensor funciona, ai sim, desenvolva seu projeto. 

Bons estudos. 

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço