The Smell of Molten Projects in the Morning

Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.

The New Hotness

  • Arduino Analog Input Averaging

    The Hall effect LED current controller measures a bunch of analog signals that have a lot of PWM ripple, so I average ten readings:

    //-- Read AI channel
    //      averages several readings to improve noise performance
    //		returns value in volts assuming known VCC ref voltage
    
    #define NUM_T_SAMPLES    10
    
    float ReadAI(byte PinNum) {
    
      word RawAverage;
    
      digitalWrite(PIN_SYNC,HIGH);					// scope sync
    
      RawAverage = (word)analogRead(PinNum);		// prime the averaging pump
    
      for (int i=2; i <= NUM_T_SAMPLES; i++) {
        RawAverage += (word)analogRead(PinNum);
      }
    
      digitalWrite(PIN_SYNC,LOW);
    
      RawAverage /= NUM_T_SAMPLES;
    
      return Vcc * (float)RawAverage / 1024.0;
    
    }
    

    The PIN_SYNC output produces the upper trace, with the LED current in the lower trace at 50 mA/div:

    Arduino Analog 10x sample avg - ILED 50 mA-div
    Arduino Analog 10x sample avg – ILED 50 mA-div

    In round numbers, ten samples require 1.1 ms and cover about 35 PWM pulses (using 32 kHz PWM, as you really should if you need an actual analog voltage).

    Because the samples occur asynchronously with respect to the PWM pulses, the computed average comes out surprisingly close to the actual average. Fewer samples would probably be just as good, but I’m in no hurry.