Bom dia pessoal!

Estou com um probleminha para implementar numa estação meteorológica que está utilizando alguns sensores, como barômetro, um DHT22, um anemômetro, um indicador de direção do vento, um pluviômetro e posteriormente enviando os dados para um servidor.

O problema básico consiste em que, posso determinar dentro do loop um certo tempo para a leitura de todos os sensores, exceto um, o pluviômetro, pois é ele que irá enviar o pulso para o contador e não posso saber ao certo quando isso vai acontecer. Então, a probabilidade de ele fazer a leitura é mínima, pois o pulso pode vir a qualquer hora em que esteja sendo executado outra parte do código, que usa delay.

Sendo assim, eu teria que ter um buffer externo ao Arduino para posterior leitura nesta configuração. Porém, deve existir uma forma de eliminar esta parte e fazer tudo via software, deixando o Arduino sempre pronto para receber o pulso e fazer a leitura dos outros sensores em tempos determinados pelo loop (até porque o tempo tem que ser considerado na questão do anemômetro, para cálculo calcular as RPMs e transformar em KM/h). 

Se alguém tiver uma ideia e puder me auxiliar no projeto, seria muito grato.

Att, Paulo Luis Steinhauser

Exibições: 843

As respostas para este tópico estão encerradas.

Respostas a este tópico

Olá Paulo!

O uso do comando delay não é aconselhado. O melhor é usar millis ou programar interrupções.

Acabei de postar um tutorial sobre controle de intervalos de tempo que você pode adaptar para o seu projeto.

A biblioteca que estou usando usa millis, mas de forma transparente e fácil.

No seu caso, você programaria um tempo para leitura dos sensores. Essa leitura pode ficar dentro de funções para deixar o código mais limpo e, dentro do loop, você faria a leitura do pluviômetro.

Veja o post aqui:

http://josecintra.com/blog/arduino-controlando-intervalos-tempo/

Olá José!

Então, ao invés de utilizar o delay, utilizarei millis que não congela todo o sistema enquanto o tempo não estipulado não é alcançado, mais ou menos isso? E a leitura do pluviômetro ficaria dentro do próprio loop ao invés de ser uma função a parte, e o restante que eu estava utilizando dentro do loop faço funções externas...

Realmente é uma ótima solução, vou verificar aqui, escrever um código novo a partir do zero, pois o outro já está muito poluído, e começo com os testes.

Obrigado pela ajuda...

Assim que tiver conseguido fazer o novo sistema funcionar dou um toque...

Abraço!

Bom dia, 

No meu parecer, o mais indicado é usar interrupções para fazer a leitura dos pulsos do Pluviômetro. 

Favor informar mais informações sobre o sensor pluviômetro.( Link, fotos, etc) 

https://www.arduino.cc/en/Reference/AttachInterrupt

https://playground.arduino.cc/Code/PingInterruptCode

Bom dia José Gustavo.

Vejamos os fontes de três itens da estação, o Pluviômetro, o Anemômetro e o indicador de direção do vento, conforme veio do vendedor (obviamente no meu código tentei juntar tudo e mais um pouco mas perco alguns pulsos do Pluviômetro:

--------------------------------------------------------------------------------------------------------------------------

ANEMÔMETRO:

// Pin definitions
# define Hall sensor 2         //  Pino digital 2

// Constants definitions
const float pi = 3.14159265;           // Numero pi
int period = 5000;               // Tempo de medida(miliseconds)
int delaytime = 2000;             // Time between samples (miliseconds)
int radius = 147;      // Raio do anemometro(mm)

// Variable definitions
unsigned int Sample = 0;   // Sample number
unsigned int counter = 0; // magnet counter for sensor
unsigned int RPM = 0;          // Revolutions per minute
float speedwind = 0;         // Wind speed (m/s)
float windspeed = 0;           // Wind speed (km/h)



void setup()
{
  // Set the pins
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);     //internall pull-up active
    
  //Start serial
  Serial.begin(9600);       // sets the serial port to 9600 baud
  }

void loop()
{
  Sample++;
  Serial.print(Sample);
  Serial.print(": Start measurement...");
  windvelocity();
  Serial.println("   finished.");
  Serial.print("Counter: ");
  Serial.print(counter);
  Serial.print(";  RPM: ");
  RPMcalc();
  Serial.print(RPM);
  Serial.print(";  Wind speed: ");
 
//*****************************************************************
//print m/s  
  WindSpeed();
  Serial.print(windspeed);
  Serial.print(" [m/s] ");              
 
//*****************************************************************
//print km/h  
  SpeedWind();
  Serial.print(speedwind);
  Serial.print(" [km/h] ");  
  Serial.println();


  delay(delaytime);                        //delay between prints
}



// Measure wind speed
void windvelocity(){
  speedwind = 0;
  windspeed = 0;
 
  counter = 0;  
  attachInterrupt(0, addcount, RISING);
  unsigned long millis();       
  long startTime = millis();
  while(millis() < startTime + period) {
  }
}


void RPMcalc(){
  RPM=((counter)*60)/(period/1000);  // Calculate revolutions per minute (RPM)
}

void WindSpeed(){
  windspeed = ((4 * pi * radius * RPM)/60) / 1000;  // Calculate wind speed on m/s
 
}

void SpeedWind(){
  speedwind = (((4 * pi * radius * RPM)/60) / 1000)*3.6;  // Calculate wind speed on km/h
 
}

void addcount(){
  counter++;
}

-----------------------------------------------------------------------------------------------------------------------------------------

PLUVIÔMETRO (desconsiderar a parte do LCD)...

#include <LiquidCrystal.h> //Inclui a biblioteca do LCD
 
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Configura os pinos do Arduino para se comunicar com o LCD

// Constantes:
  const int REED = 6;              //The reed switch outputs to digital pin 9
 
  // Variáveis:
int val = 0;                    //Current value of reed switch

int old_val = 0;                //Old value of reed switch

int REEDCOUNT = 0;              //This is the variable that hold the count of switching

 // as variaveis a seguir sao do tipo long pois o tempo, medido em milissegundos,
 // rapidamente se tornara em um numero grande demais para ser armazenado em uma int.
 
 
 void setup() {
   // initializa o pino do switch como entrada
   pinMode (REED, INPUT_PULLUP); //This activates the internal pull up resistor

   // initializa a comunicaçao serial:
   Serial.begin(9600);
   digitalWrite(2,HIGH);
lcd.begin(16, 2); //Inicia o LCD com dimensões 16x2(Colunas x Linhas)
lcd.setCursor(0, 0); //Posiciona o cursor na primeira coluna(0) e na primeira linha(0) do LCD
lcd.print("Pulsos "); //Escreve no LCD "Olá Garagista!"
lcd.setCursor(0, 1); //Posiciona o cursor na primeira coluna(0) e na segunda linha(1) do LCD
lcd.print("Chuva "); //Escreve no LCD "LabdeGaragem"
 }
 
 void loop() {
   // ler o estado do switch pelo pino de entrada:
  val = digitalRead(REED);      //Read the status of the Reed swtich


 if ((val == LOW) && (old_val == HIGH)){    //Check to see if the status has changed

   delay(10);                   // Delay put in to deal with any "bouncing" in the switch.

   REEDCOUNT = REEDCOUNT + 1;   //Add 1 to the count of bucket tips

   old_val = val;              //Make the old value equal to the current value
       Serial.print("Medida de chuva (contagem): ");
       Serial.print(REEDCOUNT);//*0.2794);
       Serial.println(" pulso");
       Serial.print("Medida de chuva (calculado): ");
       Serial.print(REEDCOUNT*0.25);
       Serial.println(" mm");
       lcd.setCursor(8, 0); //Posiciona o cursor na décima quarta coluna(13) e na segunda linha(1) do LCD
       lcd.print(REEDCOUNT); //Escreve o valor atual da variável de contagem no LCD
       lcd.setCursor(8, 1); //Posiciona o cursor na décima quarta coluna(13) e na segunda linha(1) do LCD
       lcd.print(REEDCOUNT*0.25); //Escreve o valor atual da variável de contagem no LCD
       lcd.setCursor(14, 1); //Posiciona o cursor na primeira coluna(0) e na segunda linha(1) do LCD
       lcd.print("mm"); //Escreve no LCD "LabdeGaragem"
       }
 
     else {

   old_val = val;              //If the status hasn't changed then do nothing

 }

}

-----------------------------------------------------------------------------------------------------------------------

INDICADOR DE DIREÇÃO DO VENTO (este código original deles não traz muitas informações...)

// Const def
int pin=0;
float valor =0;
int Winddir =0;
int cont =0;


void setup() {
  //  inicializa a comunicação serial a 9600 bps:
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  digitalWrite(LED_BUILTIN, HIGH);
}

void loop() {
 valor = analogRead(pin);
 
 if (valor >= 0.50){
 
 Serial.print("leitura do sensor :");
 Serial.print(valor);
 Serial.println(" volt");
 delay (1000);
 digitalWrite(LED_BUILTIN, LOW);
 Serial.println();
 Serial.print("Pino 13 desligado... :");
 cont++;
 Serial.println();
 Serial.print(cont);
 
 } else {
 
 valor = analogRead(pin);
 Serial.print("leitura do sensor :");
 Serial.print(valor);
 Serial.println(" volt");
 delay (1000);
 digitalWrite(LED_BUILTIN, HIGH);
 Serial.println();
 Serial.print("Pino 13 ligado... :");
 Serial.println();
 Serial.print(cont);
 }
 Serial.println();

}

Olá!

Complementando o que o Murta falou:

Você pode usar interrupções, mas deve substituir os delays por millis.

O comando delay interfere com as interrupções.

Pois então José Augusto, vou eliminar os delays e utilizar millis... ainda vou ter que ler um pouco a respeito de interrupções, uma vez que nunca utilizai esta técnica...

Mais uma vez agradeço a colaboração!

Olá pessoal!

Ainda não coloquei 100% do código para funcionar e ainda não liguei o sensores corretamente, mas em testes, seguindo as orientações tanto do José Augusto Cintra quanto do Murta, consegui resolver o problema acima citado.

Grato a todos!

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço