Incorrect analogread readings

I tried using a bit of code i found somewhere on the arduino forum (as seen below) but for some reason im not getting the right values.

arduino code:

const int numReadings = 100; 
int inputReading [numReadings];

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

void loop()
{
  for (int i = 0; i < numReadings; i++) {
    inputReading [i]= analogRead(A0); // roughly 9kHz sampling
  }
  
  for (int i = 0; i < numReadings; i++) {    
    float voltage = ((inputReading[i]/1023.0)*5.0);                             
    Serial.println(voltage);  
  }
}

Its sampling a 60hz as signal, and is suppose to output a smooth steam of releveant data but throughout the data it seems to skip or jump like this:

3.73
3.81
3.87
3.90
3.91
3.94
3.98
4.01
2.14

It just jumps down, and in other parts of the data stream it jumps back up or to any random sampling point and continues from there.

Also, usually right after i run the sketch i get a couple off values like these:

4.152.31 or 3)H·­Qéð2.90

Dont know if thats common or not, but anyway if someone could help me troubleshoot this program id greatly appreciate it.

What is the nature of the 60Hz signal?

I was just going to ask much what AWOL did...

How do you know the readings are wrong?- what's going in? The nature of the readings is dictated by the shape of the input so to say the readings are jumping up and down is of no help- maybe that's just the nature of the input?

It is an attenuated 120V ac signal, which should vary from about 0.9-3.7V.

Also note when i was getting the correct cycle of data my values were still off (instead of 3.7 i was getting 4.3 or so, my lower end was around 0.9 like it should be though)

Also AWOL i do believe this was a code that you made up in this forum: Arduino Forum

Also, don't forget, when I wrote that code, it was just to demonstrate a method of burst-sampling - the output may well leap around, because the sampling will be discontinuous at the end of each 100 samples.
If you tell us what you want to do, we may be able to help better.

The signal is rectified, isn't it?

I know my readings are wrong because im using a scope (a digital flukemeter actually) and i know its giving me the correct values.

What i want the code to do is sample the ac signal at a fast(100+ samples per cycle), and constant rate, and get the same values as the flukemeter is (why the upper range is off i have no idea).

Note: When i use just the normal loop and not the for loop i get the correct cycle of data (albeit at a drastically reduced sampling rate), but again my upper range is off.

NickPatey:
I know my readings are wrong because im using a scope (a digital flukemeter actually) and i know its giving me the correct values.

Your concept of reading a 60Hz signal and getting a predictable pattern of numbers is flawed as there is no synchronization of the input signal to your sampling of the voltage of the analogRead functions, you will just get random numbers that won't mean anything useful. Your flukemeter has automatic internal triggering such that it can show a true sequence of the input signal over time which is what the final display is showing you.

Lefty

Your concept of reading a 60Hz signal and getting a predictable pattern of numbers is flawed as there is no synchronization of the input signal to your sampling of the voltage of the analogRead functions, you will just get random numbers that won't mean anything useful.

That's what I was trying to say....

Especially if it's rectified, with all values positive: You might get two voltages on say the down slope of 2 and 1, then the next reading might be on the next up slope at 1.5 and so it looks like 2, 1, 1.5 and you "think" the 1.5's wrong. Of course if it wasn't rectified, it would have been -1.5 and you would have realised it was still on the down slope, just on the other side of 0.

Ok that was perfectly clear in my head.... 8)

Of course if it wasn't rectified,

...you've probably smoked your Arduino.

Derp forgot to mention the signal is DC shifted above the axis (such that the trough of the signal is around 0.9V) and is not rectified.

But anyway is there any way i can properly sample the signal? Its really important that im able to do so as i have an entire college project based around these readings.

NickPatey:
Derp forgot to mention the signal is DC shifted above the axis (such that the trough of the signal is around 0.9V) and is not rectified.

But anyway is there any way i can properly sample the signal? Its really important that im able to do so as i have an entire college project based around these readings.

Possibly. It would require having an external zero crossing detector looking at the input signal and the arduino using that as a timing signal to start sampling in a fixed rate and fast enough to get enough sample points to build the pattern up. Zero crossings happen at every 8.333 milliseconds on a 60Hz signal and you would have to work out how many sample points you need to measure between zero crossings to extract the information you are trying to determine about the input signal, which is not clear to me at all.

The input signal contains:
A frequency
A minimum and maximum voltage value

So what are you trying to measure from the signal? Or do you wish to just store enough snap shots samples to be able to recreate the signal or graph it?

Processing AC voltages directly is not one of an arduino's strong suits.

Lefty

My goal is to sample the ac signal, transfer the samples to a computer, and get the RMS value for each cycle. I would like to be able to sample the cycle at at least 100 samples per cycle if at all possible, as i would like to try and be accurate to around 1%.

Especially if it's rectified, with all values positive: You might get two voltages on say the down slope of 2 and 1, then the next reading might be on the next up slope at 1.5 and so it looks like 2, 1, 1.5 and you "think" the 1.5's wrong. Of course if it wasn't rectified, it would have been -1.5 and you would have realised it was still on the down slope, just on the other side of 0.

No as the sampling rate is far higher than the signal frequency!

It's a 60Hz signal so a run of 100 samples at 9000Hz will only see part of one cycle. 1/90th of a second V 1/60th of a second. So there are two things to do.

  1. Increase the number of samples, and/or

  2. Extend the sampling time by adding a small delay using micros().

Mark

NickPatey:
My goal is to sample the ac signal, transfer the samples to a computer, and get the RMS value for each cycle. I would like to be able to sample the cycle at at least 100 samples per cycle if at all possible, as i would like to try and be accurate to around 1%.

Well you have some math to do to see if that is all possible. You have to factor the communications datarate which might add a upper timing limit in how many samples you can process and send within a 8.333 millisecond window. You might be able to do your 'zero' crossing detection within your sketch, in that you continuously read the input voltage but don't start saving the results until you detect that the voltage has crossed a zero point. As you are using an offset AC signal to stay within the DC voltage limits for a arduino analog input pin you will have to figure out what that specific offset value is. Anyway once you detect the zero crossing point you then start reading/sending the values out until the next zero crossing point. You will have to determine how many samples that allows given the ADC processing speed and any sketch overhead time taken sending the data out the serial port.

For your purposes you probably only have to process just the positive or just the negative portion of the AC signal as the alternate 'polarity' can be assumed to be identical for the purposes of just calculating the true RMS value of the AC signal. I also assume the signal is not a pure sine wave? because if one is dealing with a pure sine wave, RMS voltage can be calculated just based on the peak voltage seen and detecting a peak voltage is a simpler process then trying to sample a complete waveform and sending the individual readings to a PC for calculating the RMS value of the signal . RMS = Peak X .707 for a sine wave signal.

Good luck;

Lefty

It's a 60Hz signal so a run of 100 samples at 9000Hz will only see part of one cycle.

Yes, but you don't know where it started, so "part of one cycle" doesn't mean all on the same slope

But it does mean 100 reading taken over part of one cycle.

Mark

Actually i think it would be pretty easy to incorporate a peak detection aspect into my sketch, that would detect the positive peak, start streaming data, then restart the stream at the next positive peak (might have to have it detect the first positive peak, then the following trough, and THEN the end peak though).

Im still not fully sure WHY i need this synchronization though, unless the phase of the AC signal is shifting aroung, which might be what you guys are getting at.

Try 700 readings in a burst not just 100.

Mark

Holy sweet mother of god, 700 give me a perfectly cyclic stream of data, i dont know how to thank you man, this saved me.

ALTHOUGH, the upper range on my data is still above the correct value by around 0.5V which baffles me honestly.