programming with registers in arduino

i am working on reading analog signals from analog pin and sent it through my serial port.but it seems that despite my efforts of keeping my baud at maximum and reseting the prescale factor of adc,it seems that analogRead is just too slow to read my samples.Can anyone suggest a better method of sampling my data faster?

Use a Due.

It would help if you said what sort of data rate you were after so we can see the limits you have to work with.

well,i want to sample a 1 khz signal.As per the write up which i had read about setting the adc prescaler right now i am getting a sample about 22 microsecond.i need to remap my original signal for which the samples that i am getting now is inadequate.i need a faster sampling speed

i want to sample a 1 khz signal.

OK

As per the write up

What write up?

i am getting a sample about 22 microsecond

What is wrong with that for sampling a 1KHz signal? That will be oversampling it by twenty times!

sherin994: well,i want to sample a 1 khz signal.

That does not tell us how many samples per second you wish to take.

According to the Atmel datasheet an Atmega 328 can take 15,000 sps at full resolution and a max of 76.9 at low resolution.

I have not experimented to see whether the Arduino analogRead() can match the 15ksps rate, but it would only take a few lines of code to find out. If it isn't fast enough it is easy to read the registers ADCH and ADCL directly.

...R

Is the signal repetitive (AC sinusoidal, triangular, etc)?

You know you can use a baud rate of 1,000,000 (yes a million). But the analogRead is another issue. What exactly are you trying to read?

the write up that i checked was
www.microsmart.co.za/technical/2014/03/01/advanced-arduino-adc/
i had given a test frequency of 150hz sinusoidal ,triangle and square waves.the square wave went all right but sine and triangular wave showed only about 8 samples for one complete cycle.i tried to plot them to see the resulting waveform but the waveforms were not correct

KenF i am trying to read analog signals from function generator and i am trying to plot them,that is ,a software implementation of oscilloscope

So post your code and post the diagram of how you wired up the signal generator to the analogue input. Did you bias the input signal to 2.5V?

... but sine and triangular wave showed only about 8 samples for one complete cycle.i tried to plot them to see the resulting waveform but the waveforms were not correct

If the goal is to accurately measure then recreate the waveform, this can be done with a low sample rate and high precision. If the goal is to re-create the waveform at the same rate (frequency) of the input, then you're limited by the sample rate.

sherin994: KenF i am trying to read analog signals from function generator and i am trying to plot them,that is ,a software implementation of oscilloscope

Ah right. You'll find the arduino's ADC pretty limiting then. It'll only do about 10K readings per second and that is without any serial.printing or eeprom writing. Might be worth adding an external ADC chip to your project to improve results. For a few dollars you could improve results a great deal.

here is my code that i set up for reading
const unsigned char PS_16 = (1 << ADPS2);
const unsigned char PS_32 = (1 << ADPS2) | (1 << ADPS0);
const unsigned char PS_64 = (1 << ADPS2) | (1 << ADPS1);
const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);

void setup(){

serial.begin(115200);
ADCSRA &= ~PS_128;
ADCSRA |= PS_16;

}

void loop()
{
iNT a = analogRead(A0);
serial.println(a);

dlloyd:

... If the goal is to accurately measure then recreate the waveform, this can be done with a low sample rate and high precision. If the goal is to re-create the waveform at the same rate (frequency) of the input, then you're limited by the sample rate.

so is it i should lower down my baudrate?

If you have an AC sinusoidal input at 1kHz, and have only 8 samples/cycle and you require a 1 sec update response, then:

You could get the precision of 8,000 samples per cycle by progressively time-skewing your samples over the 1 second period.

dlloyd: If you have an AC sinusoidal input at 1kHz, and have only 8 samples/cycle and you require a 1 sec update response, then:

You could get the precision of 8,000 samples per cycle by progressively time-skewing your samples over the 1 second period.

i dint quite understand what you said now.could you please explain it with a sample program if you are suggesting an addition in the program?

i dint quite understand what you said now.could you please explain it with a sample program if you are suggesting an addition in the program?

If you look at the signal in the link you've provided, it shows 13 samples for 1 cycle. If the sgnal frequency is 1kHz, then this would mean reading from the ADC at 13,000 sps.

What I'm suggesting is that you can get a more accurate picture of the waveform with a type of oversampling.

Imagine accumulating the data at 13 samples per cycle, then the next group of 13 samples is delayed by 10µs from the positive zero-crossing, then the next group of 13 samples is delayed by 20µs from the positive zero-crossing, and so on for 100 times.

Now the data can be organized correctly to re-create the waveform and updated once per second. This waveform will consist of 1,300 samples per cycle, but it was sampled at 13,000 sps (over 1 second) instead of 1,300,000 sps (over 1 cycle).

Its not an easy solution ... just showing what's possible.

EDIT: Note that many energy metering IC's use similar techniques - they have very little ram, can sample as low as 3.5Ksps, measure and calculate many quantities get results within 0.1% accuracy class.

I think if you want to get the maximum out of the ADC on a Uno or Mega you will need to use an interrupt routine to manage the ADC. That way the conversion can be started (within the ISR) and left to work in the background. When the conversion is complete it will trigger the ISR which can copy the value to a suitable variable and re-trigger the next conversion.

Or you could use free-running mode in which a new conversion starts automatically as soon as the current one finishes. Again, the completion of the conversion needs to trigger an interrupt so you can harvest the value.

By using interrupts the Arduino can do other stuff (such as sending the result to the PC) at the same time as the ADC is working. The Arduino analogRead() is a blocking function that waits until the conversion is complete. My tests suggest that analogRead() takes about 112 usecs.

You must also be aware that an Uno cannot store very many samples in its 2k of SRAM so you need to ship the data out to the PC as quickly as it is harvested. At 1,000,000 baud you could transmit about 50,000 INTs per second so it should be doable.

...R

I asked:-

Grumpy_Mike: So post your code and post the diagram of how you wired up the signal generator to the analogue input. Did you bias the input signal to 2.5V?

You responded with a bit of code, not in code tags that will not even compile. You totally ignored my question about biasing the input signal. Are you after help or what?