Go Down

Topic: Media ponderada con tiempo y números negativos (Read 74 times) previous topic - next topic

svallejoa

Hola buen día.
Estoy trabajando con un dispositivo que determina la dirección del viento mediante dos Encoders ópticos y necesito hacer un código que me calcule la media ponderada de la posición en un intervalo de tiempo determinado y que me lo guarde en una SD, pero estoy teniendo problemas cuando la posición es negativa, y tampoco estoy seguro de si estoy calculando bien la media ponderada, lo que llevo hasta ahora es lo siguiente:

Code: [Select]

//Código para la dirección del viento
//Importar librería de la tarjeta SD
#include <SD.h>

//Declarar el archivo en la SD
File DViento;

//Declaración de variables
int EncoderA = 2;
int EncoderB = 4;
long PosicionRueda = 0;
int UltimoEstadoA = LOW;
int EstadoA = LOW;
long Total;
unsigned long TiempoInicial;
int Intervalo = 10000;
float Divisor = 0;
int EstadoAnterior = 0;
int Estado;
float Suma;
unsigned long Tiempo;
float MediaPonderada;
float Grados;
volatile bool Activar;
volatile bool Adicion;


// Cambio de estado en los Encoders para determinar si se suma o resta en la posición
void Cambio()
{
  if (digitalRead (EncoderA)){
    Adicion = digitalRead (EncoderB);
  }else{
    Adicion = !digitalRead (EncoderB);
  }
  Activar = true;


void setup (){
  pinMode (EncoderA, INPUT_PULLUP);     
  pinMode (EncoderB, INPUT_PULLUP);
  Serial.begin (9600);
  Serial.print (F("Iniciando..."));
  if (!SD.begin(5)) {
   Serial.println("No se pudo iniciar");
   return;
   }
  Serial.println("  Inicio exitoso");
  TiempoInicial = millis();
  Tiempo = millis(); 
  attachInterrupt (digitalPinToInterrupt (EncoderA), Cambio, CHANGE);


void loop (){
  //Se crea el archivo "DViento"
  DViento = SD.open("DViento.txt", FILE_WRITE);

  //Se utiliza la función creada anteriormente para detectar los cambios
  if (Activar){
    if (Adicion){
      PosicionRueda++;
    }else{
      PosicionRueda--;
    }
    Serial.print("PosicionRueda = ");
    Serial.print(PosicionRueda);
    Serial.print(" Grados = ");
    Serial.println(PosicionRueda * 2);
    Activar = false;
  }
 
 //Definición de los valores para sacar la media ponderada
   Estado = PosicionRueda;
   if (EstadoAnterior = Estado){
    Suma = PosicionRueda * Tiempo;
    Total = Total + Suma;
    Divisor = Divisor + Tiempo;
    if (EstadoAnterior != Estado){
     Tiempo = millis();
     EstadoAnterior = Estado;
    }
   } 
   
  //Se calcula la media ponderada de la posición en un lapso de tiempo determinado
  if (millis () - TiempoInicial >= Intervalo) {
    MediaPonderada= Total / Divisor;
   
    //Conversión de los datos obtenidos a grados
    Grados = MediaPonderada* 2;

    //Almacenamiento de los datos obtenidos en la SD
    DViento.print (F("Grados = "));
    DViento.println (Grados);

   
    Serial.print (F("Media Ponderada Grados = "));
    Serial.println (Grados);
    Total = 0;
    Divisor = 0;
    TiempoInicial = millis ();
    DViento.close();
    }
}


Les agradezco por su ayuda.

surbyte

Encontré dos errores en tu código.
El primero este

Code: [Select]
if (EstadoAnterior = Estado){

y debe ser asi

Code: [Select]
if (EstadoAnterior == Estado){


El segundo es como tomas la variable Tiempo que luego se va sumando a Total. Lo haces mal.
Tiempo debería llevar la diferencia de tiempo entre una lectura de millis() y la siguiente, en cambio solo cargas la variable Tiempo con el valor de millis() lo que hace que tu variable Total resuelte en cualquier cosa.


Go Up