Seamless data logging using UNO

I am using an FDS100 photodiode in reverse bias to detect light. The photodiode is connected to two op-amp stages for signal conditioning and amplification purposes. The output of the second op-amp is connected to the A0 pin on the Arduino UNO. I am having a ±0.1V noise. I understand that I should not be asking for better SNR but this is periodic noise which makes me think that it's because of aliasing. I have attached the code. How do I get rid of this effect?

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

void loop() {

int voltagein = analogRead(A0);
float PDV0 = voltagein * (5.0/1023.00);

Serial.println(PDV0,6);
delay(1000);
}

Arduino Search on over-sampling. It's using averaging to reduce noise ( "get extra precision" ).

You could get 5 or more samples in a millisecond and have cycles to run an average if you avoid using floats. AVR has no FPU and the floats are lousy 32-bit only, no doubles.

haristadena:
. . . this is periodic noise which makes me think that it’s because of aliasing. . . .

If it is in fact aliasing, say from 50/60 Hz flicker from a florescent light, then averaging periodic ADC samples over one or more complete cycles of the power line frequency will reduce that noise.

Code Snippet (not compiled or tested):

int msPerCycle = 20 ;       // 20 ms per 50 Hz powerline cycle
int iterations = 0 ;           // counter for sampling loop
uint adcSum = 0 ;           // sum of ADC samples
unsigned long startTime = millis() ;

while ((millis()-startTime) < msPerCycle) {
   adcSum += analogRead(A0) ;
   iterations += 1 ;
}

int voltagein = adcSum/iterations ;

The ADC section of AVR (like 328P) datasheets tells of error sources within the chip and IIRC the margin could be the low 2 bits of 10.

You can change ADC operation but what I've seen is about speeding it up without losing too much accuracy.

That and more by Nick: http://gammon.com.au/adc

I'm not sure you can do this at all but if you could change the Reference Voltage between reads, the dither points would also move.

An RC filter did the trick (1M ohm R with 0.1µF C).

Code-wise, I also went from

Serial.println(PDV0,6);

to

Serial.println(PDV0,2);

It was not aliasing from 50/60 Hz laser flicker. The frequency was 0.04 Hz actually. Still unsure where it came from.

Thanks for all the help though.

haristadena: It was not aliasing from 50/60 Hz laser flicker. The frequency was 0.04 Hz actually. Still unsure where it came from.

The aliased (if that's what it is) frequency in the output data is a beat frequency between the input signal's periodic variation and the sample clock, so it's not obvious that it isn't power line frequency a bit out of sync with the nominal 1 Hz sample rate. That is, the power line is periodic at 1 Hz (exactly 50/60 cycles) and should have the same value if sampled at that frequency. However, if sampled at (1+0.04/50) Hz, the resultant data stream would be periodic at 0.04 Hz.

If one were inclined to test this, collecting a snapshot of ADC samples at a "fast" (fast being maybe 10x or greater power line frequency) and plotting them should show if that's what's happening.

Regardless, if the analog filter suits your purpose, it may be time to move on.

Maybe testing with a steady light will tell? Filter some sunlight?