Cómo estabilizar la pantalla de salida de adc en 7 segmentos

1

Estoy diseñando un voltímetro simple. Estoy usando ADC de 8 bits de PIC16F72 y el compilador Mikro C con una pantalla multiplexada de 7 segmentos. Estoy obteniendo un valor ADC en la pantalla de 7 segmentos, pero su fluctuación continua (por ejemplo, 1670mV fluctúa entre 1660 y 1680mV). He intentado todo en hardware, agregando un límite en ADC y tierra, etc.

Aquí está mi código:

void StabilizeVoltage()
{
     unsigned int ADS;
     if (flgAC)
      {
      ADS = ADC_Get_Sample(0);
      Voltage_FLOAT =(float)ADS *19.6078431372549;
      a= Voltage_FLOAT;
      Voltage_INT=a;
      //if(63<Voltage_INT && Voltage_INT<78 )
       if(Voltage_INT <=1050 )
      {
      Relay1=0;
      Relay2=0;
      Relay3=0;
      Relay4=0;
      }
      else if (1050<Voltage_INT && Voltage_INT<=1150)
      {
      Relay1=1;
      Relay2=0;
      Relay3=0;
      Relay4=0;
      }
      else if (1150<Voltage_INT && Voltage_INT<=1350)
      {
      Relay1=1;
      Relay3=1;
      Relay2=0;
      Relay4=0;
      }
      else if (1350<Voltage_INT && Voltage_INT<=1450)
      {
      Relay1=1;
      Relay3=1;
      Relay2=1;
      Relay4=0;
      }
      else if (1450<Voltage_INT )
      {
      Relay1=1;
      Relay3=1;
      Relay2=1;
      Relay4=1;
      }
      }
      flgAC = 1;
}
void main()
{
      InitIO();
      ADC_Init();
      InitTimer2();
      InitDisplay();
     while(1)
     {
         UpdateDisplay();
         StabilizeVoltage();
     }
}

¿Necesito algún filtro de software?

    

2 respuestas

2

Una posible solución de software es la media móvil exponencial muy simple ( enlace ). Solo requiere una variable global y unas pocas líneas de código. Es un poco más de trabajo que realizar, pero esto también puede hacerse con un código de punto fijo (es decir, int.) Para una eficiencia mucho mayor (no me preocuparía si todo lo que haces es leer un ADC y mostrarlo).

Por ejemplo:

//K is the filter coefficient and must be smaller than 1 and greater than zero (0<K<1)
//The smaller the K is, the more the filter will smooth, but it will also take longer
//to reach its value when the input changes.
#define K 0.01f

float filter( float aData )
{
    static float memory;
    memory = memory*(1-K) + aData*K;
    return memory;
}
    
respondido por el Mathieu L.
0

Estás viendo el dithering de ese bit menos significativo cuando intenta decidir si es un 1 o un 0; es algo con lo que tendrá que lidiar escalando la entrada al ADC, a menos que pueda ignorar la fluctuación de la pantalla.

El último bit siempre vacilará un poco a menos que sea la medición de voltajes que sea MUY estable y no capte NINGÚN ruido de fuentes externas. Puede hacerlo un poco más silencioso si puede reducir la impedancia de entrada, si la distorsión es el resultado de un ruido exterior. Sin embargo, cada vez que el voltaje que mides no sea estable dentro del 1.2%, verás ese tipo de interpolación en el bit menos significativo, sin embargo.

A 1670mv, su ADC le da datos = 85 + - 1. Multiplicado por su ~ 19.6, datos de 84 = 1646.4 (1646), datos de 85 = 1666, y datos de 86 = 1685.6 (1686), entonces verá desde 1646 hasta 1686, dependiendo de si su bit menos significativo elige 1 o 0.

Escale la entrada al ADC con un opamp con una ganancia de 19.6, y puede eliminar la multiplicación de software y amp; lea los voltajes directos ... Y su atenuación debe ser aliviada.

    
respondido por el TDHofstetter

Lea otras preguntas en las etiquetas