Tiempo de Lecturas Sensores

Hola amigos! quisiera consultarles lo siguiente :

  • Tengo un DHT leyendo cada 10 segundos, con funcionarios milis. y necesito agregar un ACS712 que lea cada 5 minutos.

Debo crear otra función independiente para este sensor?

Saludos y gracias

puedes tener algo asi

void loop() {

   if (millis() - tiempo1 > 10000UL) {  // 10 seg = 10*1000;
      leo_dht();
      tiempo1 = millis();
   }
   if (millis() - tiempo2 > 300000UL) { // 5 min = 5 * 60 *1000
      leo_acs712();
      tiempo2 = millis();
   }

}


void ledo_dht() {
  // aca leo el sensor DHT
}

void leo_acs712() {
  // aca leo el sensor acs712
}

gracias surbyte!!! lo pruebo y te cuento como ve va.

Saludos

Hice algunas modificaciones, pero me gustaría saber si estoy bien.

La idea es que se mantenga en Serial.print DHT por 3 segundos en la consola y despues pase al ACS por 5 segundos y se mantenga asi en loop.

pero se vuelve medio loco al segundo enviando datos :frowning: :o

20/11/2018 modificado

int tiempo1;
int tiempo2;

void setup() {

    Serial.begin(9600);

    }

void loop() {

   if (millis() - tiempo1 > 10000UL) {  // 10 seg = 10*1000;
      leo_dht();
      tiempo1 = millis();
   }
   if (millis() - tiempo2 > 20000UL) { // 5 min = 5 * 60 *1000
      leo_acs712();
      tiempo2 = millis();
   }

}


void leo_dht() {
  Serial.println("DHT");           // se mantiene la funcion  leo_dht en el monitor serial por 6 segundos, 
                        //funcion que lee el sensorDHT cada 2 segundo y lo imprime
 
}

void leo_acs712() {
  Serial.println("ACS");           // se mantiene la funcion leo_acs en el monitor serial por 5 segundos
                        //funcion que lee el sensor ACS cada 1 segundo y lo imprime
}

Vaya hombre, el hecho de agregar delay() a un código donde uso millis() implica que no te tomaste el tiempode leer nada acerca de lo que te he sugerido.

Solo dire esto, delay detiene la ejecución del programa por el tiempo que le indiques en milisegundos.
millis() en cambio es un contador en milisegundos y esos if te permiten comparar y tomar acciones cuando se cumplen las condiciones. No debes mezclar ambas cosas porque tendrás coportamientos anómalos.
Lo mejor es seguir la idea que te propuso y agregar una secuencia nueva para que muestre o imprima cada 3 segundos o 3000 milisegundos.

Ve a Documentación => Indice de temas tutoriales => Millis()

Sorry surbyte, creo que fue la hora en que estaba trabajando pero tienes razón.

Ahora bien probando anoche el código, este no logra imprimir bien por 6 segundos ya sea DHT o ACS.

Lo que después logró que me venciera el cansancio.

int tiempo1;
int tiempo2;

void setup() {

    Serial.begin(9600);

    }

void loop() {

   if (millis() - tiempo1 > 10000UL) {  // 10 seg = 10*1000;
      leo_dht();
      tiempo1 = millis();
   }
   if (millis() - tiempo2 > 20000UL) { // 5 min = 5 * 60 *1000
      leo_acs712();
      tiempo2 = millis();
   }

}


void leo_dht() {
  Serial.println("DHT");           // se mantiene la funcion  leo_dht en el monitor serial por 6 segundos, 
                                            //funcion que lee el sensorDHT cada 2 segundo y lo imprime
 
}

void leo_acs712() {
  Serial.println("ACS");           // se mantiene la funcion leo_acs en el monitor serial por 5 segundos
                                          //funcion que lee el sensor ACS cada 1 segundo y lo imprime
}

Surbyte, lo madure y quedo asi.

creo que la cosa va bien , que opináis?

Saludos!

long previousfuncion1 = 0;        
long funcion1 = 6000;            
long previousfuncion2 = 0;     
long funcion2 = 1000;         






void setup() {
     Serial.begin(9600); 
  
}

void loop(){
      F1();
      F2();
  
}


void F1(){
  unsigned long currentMillis = millis();
   if(currentMillis - previousfuncion1 > funcion1) {
     leo_dht();
     previousfuncion1 = currentMillis;   
}
}


void F2(){
  unsigned long currentMillis = millis();
   if(currentMillis - previousfuncion2 > funcion2) {
     leo_dht2();
     previousfuncion2 = currentMillis;   
}
}


void leo_dht() {
  Serial.println("funcion 1");           
               }

void leo_dht2() {
  Serial.println("funcion 2");           
                }

Si esta bien pero nunca entenderé para que sirve esto

unsigned long currentMillis = millis();

y que cambia si no usas currentMillis() en el if

digo porque asignas una variable consumiendo memoria para usarla inmediatamente luego? No veo que se gane nada.

Claro SurByte, todo surge por el siguiente planteamiento :

Tengo un DHT11 y un ACS721, programados para enviar los datos mediante MQTT con una ethernet shield operando.
La cosa con el DHT y su publicación va como cañón, pero decidí incluir un medidor de Corriente y Potencia, intente con el SCT013 pero no logre la configuración y los parámetros correctos, y cuando lograba darlos entraban las corrientes parásitas, el magnetismo y no andaba ni pa delante.

Por eso opté por el ACS712, aca la cosa mejoró y logre los parámetros adecuados para que la corriente y potencia concordaran con las cargas.

El problema surge que el sketch requiere de lecturas rápidas de la corriente por un periodo de segundos 3 o 4 minimos, para que tome valores reales, ahora bien.

Lo que necesito en definitiva es que el DHT se imprima en el serial cada 3 o 4 segundos, y el ACS712 mande lecturas en el periodo de 5 segundos con lo cual lograre (espero) tomar el valor real de la corriente medida. Pero si este sensor debe mandar lecturas durante ese periodo de tiempo.

probe los sketch por separado y andan full, por eso la complejidad se me presento al juntarlos ya que el ACS para tomar una buena medición necesita de este periodo de tiempo probado.

todo esto según pruebas nada mas, no se si tienes una mejor experiencia con estos elementos.

ahora no se si estaré bien al 100%

Saludos y gracias!

EL DHT requiere 2 segundos entre lecturas, si le das mas es tema de cada uno.
El ACS no tiene problemas porque es un sensor de salida analógica.

La forma en que presentas la información es algo a gusto del consumidor como digo yo.
La única restricción está en darle los 2 segundos al DHT y aún asi, a veces puede presentar fallos.

:frowning: SurByte, aca el código ya final ... pero no logro que el tiempo en la función 2 se detenga en el tiempo indicado, este tiempo es el que maneja el ACS712, que debería detener la toma de muestras a los 3 o4 segundos, sin embargo no para.

toma el DHT , sigue el ACS y no para mas. tengo un if con milis() en la función corriente, el cual me da los tiempos de lecturas

#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT11 
#include <Filters.h>

 
long previousfuncion1 = 0;        
long funcion1 = 3000;            
long previousfuncion2 = 0;      
long funcion2 = 4000;          
 
float testFrequency = 60;                    
float windowLength = 20.0/testFrequency;     
int sensorValue = 0;
float intercept = -0.1029; 
float slope = 0.0865; 
float current_amps; 
float current_pot; 
 
 
DHT dht(DHTPIN, DHTTYPE);
unsigned long readTime;
 
//------------------------------------------------------------------------- 
 
void setup() {
     Serial.begin(9600);
     dht.begin();
}
 
void loop(){
      F1();
      F2();
 
}
 
 
void F1(){
  unsigned long currentMillis = millis();
   if(currentMillis - previousfuncion1 > funcion1) {
     sensorRead();
     previousfuncion1 = currentMillis;  
}
}
 
 
void F2(){
  unsigned long currentMillis = millis();
   if(currentMillis - previousfuncion2 > funcion2) {
     corriente();
     previousfuncion2 = currentMillis;  
}
}
 
//-------------------------------------------------------------------------
 
void sensorRead(){
  readTime = millis();
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  float f = dht.readTemperature(true);
 
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
 
  float hif = dht.computeHeatIndex(f, h);
  float hic = dht.computeHeatIndex(t, h, false);
 
  char buffer[10];
  dtostrf(t,0, 0, buffer);
  char buffer1[10];
  dtostrf(h,0, 0, buffer1);
  
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("temp: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Heat i: ");  //heat index
  Serial.print(hic);
  Serial.print(" *C ");
  Serial.print(hif);
  Serial.println(" *F");
} 
 
//------------------------------------------------------------------------- 
 
void corriente(){
   
   unsigned long printPeriod2 = 1000; 
   unsigned long previousMillis2 = 0;

  RunningStatistics inputStats;                 
  inputStats.setWindowSecs( windowLength );
  
   
    while( true ) {   
      sensorValue = analogRead(A0);  
      inputStats.input(sensorValue);  
        
      if((unsigned long)(millis() - previousMillis2) >= printPeriod2) {
      previousMillis2 = millis();   
      

      Serial.print( "\n" );
      Serial.print( "\tsigma: " ); Serial.print( inputStats.sigma() );
      current_amps = intercept + slope * inputStats.sigma();
      Serial.print( "\tamps: " ); Serial.print( current_amps );
      current_pot = 220 * current_amps;
      Serial.print( "\twatts: " ); Serial.print( current_pot );Serial.println( " W" );
  }

  }
  
  
  }

Veo que no tienes claros algunos conceptos.

En la funcion2 F2() tienes esto

void F2(){
  if (millis() - previousfuncion2 > funcion2) {
      corriente();        // <=== llama a corriente
      previousfuncion2 = currentMillis;  
  }
}

y en corriente que tienes?

while( true ) {

que hace un while(1) se queda ahi indefinidamente!!!

Intente borrarlo surbyte, pero no me despliega la corriente por el tiempo de F2.

En ese punto estoy entrampado

Yo no dije que lo borres, dije que esa acción hace que se quede el código ahi indefiniidamente.
Debes poner una condición para que luego de cierto tiempo o cierta cantidad de muestras salga del loop o while

uuff ya se me acaban las ideas :slight_smile: intentaré ahora avanzar surbyte, les voy contando

La condición debiera ponerla dentro de la función corriente cierto surbyte?

Saludos

NO lo se.. no se que quieres hacer con la corriente. Si no lo explicas bien uno no puede aportar mas desde este lado.

Yo sencillamente no entiendo que estas haciendo.
Iniciaste con algo que tenia dos tiempos, luego lo vuelves a meter dentro de funciones donde vuelven a tener tiempos cosa que no comprendo para qué?

Asi que se explicito, DHT cada 10 segundos dijiste y ACS712 cada 5 segundos.
Si es cada 5 segundos para que dentro lo pones en un loop infinito?

Luego en el último código sales con esto

RunningStatistics inputStats;

lo que es un error si lo intenta cualquier al compilar tu código porque el objeto RunningStatistics no existe o no esta definido.

surbyte, leyendo losmpost debo decirte que tienes toda la razón, :confused: tratare de ser lo mas claro posible para aclarar esta inquietud que se me presenta

Lo que quiero representar es que en base a este sketch que pertenece al ACS712 el cual funciona sin problemas

Sketch 1 - Corriente
#include <Filters.h>

float testFrequency = 60;                     // test signal frequency (Hz)
float windowLength = 20.0/testFrequency;     // how long to average the signal, for statistist
int sensorValue = 0;
float intercept = -0.1029; // to be adjusted based on calibration testing
float slope = 0.0865; // to be adjusted based on calibration testing
float current_amps; // estimated actual current in amps
float current_pot; // estimated actual current in amps

unsigned long printPeriod2 = 1000; // in milliseconds
// Track time in milliseconds since last reading 
unsigned long previousMillis2 = 0;

void setup() {
  Serial.begin( 9600 );    // start the serial port
}

void loop() {
  RunningStatistics inputStats;                 // create statistics to look at the raw test signal
  inputStats.setWindowSecs( windowLength );
   
  while( true ) {   
    sensorValue = analogRead(A0);  // read the analog in value:
    inputStats.input(sensorValue);  // log to Stats function
        
    if((unsigned long)(millis() - previousMillis2) >= printPeriod2) {
      previousMillis2 = millis();   // update time
      
      // display current values to the screen
      Serial.print( "\n" );
      // output sigma or variation values associated with the inputValue itsel
      Serial.print( "\tsigma: " ); Serial.print( inputStats.sigma() );
      // convert signal sigma value to current in amps
      current_amps = intercept + slope * inputStats.sigma();
      Serial.print( "\tamps: " ); Serial.print( current_amps );
      // calculo Potencia
      current_pot = 220 * current_amps;
      Serial.print( "\twatts: " ); Serial.print( current_pot );Serial.print( " W" );
      
    }
  }
}

lo junto con el sketch del DHT11 que me imprime la temperatura mas menos cada 2 segundos.

hasta aca todo bien.

el problema es que al juntarlos, no logro o no lograba que me entregara la temperatura y despues la corriente, ya que la corriente si tengo intervalos de medida muy largos no toma una buena medición.

Lo que se me ocurrió es que el DHT entregara normalmente la temperatura ya sea cada 2 segundos y para lograr una buena medicion de corriente y potencia tomarlo cada 5 segundos.

Esto quiere decir que comienza el sketch mostrando la temperatura, y al segundo muestre la corriente por un periodo de 5 segundos ( ya que en este periodo debiera tomar las muestras necesarias para una buena toma de la medición) y volviera a mostrarse le temperatura .

Notese que el sketch del ACS712 toma de manera constaste una medición cada 1 segundo, lo cual funciona de maravillas.

mi problematica que al juntarlos se me produce el problema, apuntado mas que nada a la toma de las muestras de corriente

aca el sketch unido, si bien es cierto tienes toda la razón y el sketch se queda pegado en la función corriente, entrega una medición de DHT y luego se queda en la corriente.

#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT11 
#include <Filters.h>

 
long previousfuncion1 = 0;        
long funcion1 = 3000;            
long previousfuncion2 = 0;      
long funcion2 = 4000;          
 
float testFrequency = 60;                    
float windowLength = 20.0/testFrequency;     
int sensorValue = 0;
float intercept = -0.1029; 
float slope = 0.0865; 
float current_amps; 
float current_pot; 
  
DHT dht(DHTPIN, DHTTYPE);
unsigned long readTime;
 
//------------------------------------------------------------------------- 
 
void setup() {
     Serial.begin(9600);
     dht.begin();
}
 
void loop(){
      F1();
      F2();
 
}
 
 
void F1(){
  unsigned long currentMillis = millis();
   if(currentMillis - previousfuncion1 > funcion1) {
     sensorRead();
     previousfuncion1 = currentMillis;  
}
}
 
 
void F2(){
  unsigned long currentMillis = millis();
   if(currentMillis - previousfuncion2 > funcion2) {
     corriente();
     previousfuncion2 = currentMillis;  
}
}
 
//-------------------------------------------------------------------------
 
void sensorRead(){
  readTime = millis();
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  float f = dht.readTemperature(true);
 
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
 
  float hif = dht.computeHeatIndex(f, h);
  float hic = dht.computeHeatIndex(t, h, false);
 
  char buffer[10];
  dtostrf(t,0, 0, buffer);
  char buffer1[10];
  dtostrf(h,0, 0, buffer1);
  
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("temp: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Heat i: ");  //heat index
  Serial.print(hic);
  Serial.print(" *C ");
  Serial.print(hif);
  Serial.println(" *F");
} 
 
//------------------------------------------------------------------------- 
 
void corriente(){
   
   unsigned long printPeriod2 = 1000; 
   unsigned long previousMillis2 = 0;

  RunningStatistics inputStats;                 
  inputStats.setWindowSecs( windowLength );

  sensorValue = analogRead(A0);  
      inputStats.input(sensorValue); 
   
    while( true ) {   
       
        
      if((unsigned long)(millis() - previousMillis2) >= printPeriod2) {
      previousMillis2 = millis(); 
        
      Serial.print( "\n" );
      Serial.print( "\tsigma: " ); Serial.print( inputStats.sigma() );
      current_amps = intercept + slope * inputStats.sigma();
      Serial.print( "\tamps: " ); Serial.print( current_amps );
      current_pot = 220 * current_amps;
      Serial.print( "\twatts: " ); Serial.print( current_pot );Serial.println( " W" );
  }

  }
   
  }

Resumiendo...
Tenes que leer DHT11 cada 10 segundos y ACS712 cada 5 segundos con muestras cada 1 segundo?

eso mismo

A ver que tal funciona esto

#include <Filters.h>

RunningStatistics inputStats;                 

#include <DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT11 

DHT dht(DHTPIN, DHTTYPE);
unsigned long readTime;

unsigned long previousfuncion1 = 0;        
unsigned long funcion1         = 3000;            
unsigned long previousfuncion2 = 0;      
unsigned long funcion2         = 4000;          
unsigned long printPeriod2 = 1000; 
unsigned long previousMillis2;
 
float testFrequency   = 60;                    
float windowLength    = 20.0/testFrequency;     
int sensorValue       = 0;
float intercept       = -0.1029; 
float slope           = 0.0865; 
float current_amps; 
float current_pot; 
  
void setup() {
  Serial.begin(9600);
  dht.begin();
  inputStats.setWindowSecs( windowLength );
}
 
void loop(){

  F1();
  F2();    
}
 
void F1(){
  if (millis() - previousfuncion1 > funcion1) { // funcion2  = 3000;   
      sensorRead();
      previousfuncion1 = millis();  
  }
}
 
void F2(){
  muestras();
  if (millis() - previousfuncion2 > funcion2) { // cada funcion2  = 4000;   
      corriente();
      previousfuncion2 = millis();  
  }
}
 
void sensorRead(){
  readTime = millis();
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  float f = dht.readTemperature(true);
 
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("temp: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.println(f);
} 
 
void muestras() {
  if (millis() - previousMillis2 >= printPeriod2) { // Cada 1000 mseg
      sensorValue = analogRead(A0);  
      inputStats.input(sensorValue); // cargo los valores
      previousMillis2 = millis();           
  }
}

void corriente(){
  Serial.print( "\n" );
  Serial.print( "\tsigma: " ); Serial.print( inputStats.sigma() );
  current_amps = intercept + slope * inputStats.sigma();
  Serial.print( "\tamps: " ); Serial.print( current_amps );
  current_pot = 220 * current_amps;
  Serial.print( "\twatts: " ); Serial.print( current_pot );Serial.println( " W" );
}