UNO R4 analogRead() code, where is it?

Where is the UNO R4 analogRead() code under IDE 2.1?

I need to split it so I can set off a conversion on a specified channel, then read the result later (after a longer than conversion period).

Otherwise the analogRead() is blocking whilst the conversion takes place.

I have done this for the original UNO.

BTW I have an external 4.096V reference (ADR4540) as ADC jitter is pants on the internally set reference even at 10 bits when powered off USB.

analogReference(AR_EXTERNAL); // Note AR_ prefix

Thanks.
Best,
Susan.

1 Like

in analog.cpp

1 Like

Many thanks.

C:\Users\susan\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.1\cores\arduino

Best,
Susan.

Note, single bit accurate with flicker in 12 bit mode, on USB power. :slight_smile:

Have got the ADC value acquire down from 23/25uS to under 1.5uS (including the standard port bit set-high and set-low for the scope).
it's all a bit rough and ready, but good enough for a next step.

From digging in analog.ccp it looks like the ADC is always run in 14 bit mode, then scaled down according to the resolution setting.

Okay, success :slight_smile:
I have my R4 direct register access version running now at c. 420nS, which is over 50 times faster than using the default CPP library with a blocking ADC call.
This reads the current ADC result, then kicks off a new conversion.
It goes inside an interrupt called function from a timer, the timer rate obviously must be slower than the ADC conversion time.
I will write it up, need to tidy up and do comments etc.

1 Like

As an aside, on the USB port from my computer the R4's nominal +5V on-board is 4.72V when running off VUSB; with something like 150mV variation when using a HT16K33 4 digit seven segment display as a display.

Okay, here is how to do a fast non-blocking ADC cycle, and how to attach an ADC completed interrupt call.

This interrupt method allows access to ALL the UNO R4's interrupt sources; timers, serial, etc. without needing any libraries.

Fast ADC and example of attaching an interrupt

2 Likes

Glad to see someone digging-in to the r4... I saved your github link for future reference, as my current requirement is more-than-met by sampling on 100µs boundaries, the storing in a 500-sample array. (but my routine resulted in just over 1µs of sampling/storing overhead... which was nice!)

But for the moment, the AnalogRead() tag got my attention... as I'm looking for guidance on using an external reference for the ADC, and can't seem to find any details. I'm planning on moving to a 4.1v shunt regulator (TI LM4040) - since using the 5V reference is of limited use (for my application).

Have you found the magic potion to get the AREF to work?

/edit/ Somehow I glossed over your very first post... MY BAD... I'll go try it now, thanks!

1 Like

Have you found a way to set the Clock of the MCU to 64MHz for an even faster sampling rate?

If you look at my low-power example, it shows how to change the clocking rates.

I haven't specifically tried the 64MHz... but my code shows how to unlock access to be able to change the clocking registers.

Also the ADC parameters can be changed to alter the conversion time:

Finally to note that with my code running fast ADC cycles in a fast interrupt loop, one can over-trigger the ADC conversion which will be ignored if the conversion hasn't finished, and read the results register on the fly. If the conversion isn't finished, then one just gets the old result.

Note however the standard Arduino IDE for readAnalog() has the reset register to zero on reading enabled.

Hope this helps.

:slight_smile:

3 Likes

Mine was just a curiosity to see how far the R4 family can go. I drawn inspiration from yours sketch to set up the ADC for the mine. I see you use timers (AGPT). Unfortunately I find out that those timers interfere with delay(), millis() and micros(). There is also GCNT timers, but I tried to initialise without success here . Do you know if it miss something?

With my AGPT Hijack you can write your own delay routines.

If you let the millis counter run in the background, and you are doing fast anything, it will add jitter to your code.

One really-really don't want to code with these brute-force delays.

If you need to wait for something, why not put the processor into Wake on Interrupt sleep mode?

Best,
Susan.

Hi,
I see your advice to use an analogic reference (ADR4540) pin for better noise handling on analogic measurement. I bought the ADR4550 and 4533 but the precision of the measurement doesn't grow remaining more or less identical as using the USB power. Do you know why?

Hi,
I assume you have enabled the external Aref function.
The RA4M1 will not be totally stable in its output, but the variation should be about halved. With an ATmega processor the 10 bit resolution becomes completely solid, with only the expected LSB flicker at the voltage level transitions.
I also stick in 4x hardware averaging.
Most important, the source impedance to the analogue channel should be low. Anything more than a few hundred ohms could cause poor readings.
Can you give us some information as to the exact circuit configuration?
Thanks.
Best,
Susan.

Tomorrow I can give you better details. By now the the sensor is this one used as is. Tomorrow I will check source impedance

Well, that's another annoying incompatibility with the AVR Unos!

Yes, I was disappointed with the 14bit performance... using a Vref does however also stabilize the readings against changes in the +5V supply (or c. 4.75V if off the USB).

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.