Artemis Nano ADC input impedance

First, I’m new with the Artemis Nano, though I’ve been using the “Standard” SparkFun RedBoard for many years.

I had naively expected the input impedance of the “A” ports would be high when in input mode, but I was seeing results suggesting otherwise, and then I found this post:

viewtopic.php?f=169&t=51834&p=211044#p211052.

Is it possible to configure the analog inputs in the Arduino IDE to ensure they have high input impedance?

thanks,

-Steve

you will have to make a hardcode change in the Sparkfun library. Which version do you use (1.2.1 or 2.0.x) ?

It appears to be 1.2.1 I guess. I don’t see 2.0.x listed as an option in the Board Manager in the IDE (see attached screen shot).

Any hints would be appreciated!

thanks,

-steve

paulvha:
you will have to make a hardcode change in the Sparkfun library. Which version do you use (1.2.1 or 2.0.x) ?

Find your library location (different on windows, linux or IOS).

In /1.2.1/cores/ arduino/ard-sup/analog/ap3_analog.cpp :

In function ap3_change_channel() around line 424 , change the parameter 0 to 1, so :

if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_slot(g_ADCHandle, 0, &ADCSlotConfig))

to

if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_slot(g_ADCHandle, 1, &ADCSlotConfig))

Does this change need to be compiled into a new version of the library? Or does that happen automatically using the default Makefile/Compile process using the Arduino IDE?

Also, I’m wondering if I should create an alternative to analogRead() that accepts a slot number as an argument and passes that down to this function? I’m dealing with students who I fear will be completely confused by needing to make alterations to the library. Does that seem like a reasonable solution?

thanks!

-Steve

when you rebuild your sketch it will be compiled and taken into account. Of course it is easy to make an additional call . Make sure to make backup of your current files.

in attached zip

a new ap3_analog.cpp : copy to /1.2.1/cores/ arduino/ard-sup/analog/ to replace the current

a new ap3_analog.h : copy to /1.2.1/cores/ arduino/ard-sup to replace the current

A sample sketch sketch_jan24b.ino to new the new function analogSetADCSlot() to set the slot 0 - 7

adcslot.zip (10.2 KB)

Thank you!

paulvha:
when you rebuild your sketch it will be compiled and taken into account. Of course it is easy to make an additional call . Make sure to make backup of your current files.

Hi,

Sorry to resurrect an old post, but I think I am running into the same issue (the result from the ADC is lower than expected). I have a custom board using the Artemis module and version 2.1.1 of the Sparkfun package. I didn’t find the path given above but I did find something similar here:

~\AppData\Local\Arduino15\packages\SparkFun\hardware\apollo3\2.1.1\cores\arduino\sdk\core-implement\CommonAnalog.cpp

I modified the suggested function call to use slot 1 instead of slot 0

if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_slot(g_ADCHandle, 1, &ADCSlotConfig)){ 

but it doesn’t seem to have changed anything.

Is there anything else I need to do to get the ADC to use the high-impedance slot?

Thanks,

Phil

HI

what does your circuit/ schema looks like ?

Why do you think it does not make a difference ?

Hi Paul,

I have two resistor dividers (200K, 100K) to divide the two voltages I am monitoring by 3. They are connected to GPIO11 (adcse2) and GPIO16 (adcse0).

After making the change to switch to slot 1 I still get the same voltage readings as I did for slot 0. That is, about 30% less than the true value after multiplying by 3 and scaling to 2V for the 14-bit range. Here is the code I use to convert the ADC value to millivolts:

int vbatt_mv = (vbatt_3 * 3 * 2000) / (1<<14); // full scale is 2000mV at 2^14

Thanks,

Phil

According to the datasheet, the slot 0 impedance is typical 720K, whereas for slots 1 to 7 it is 3600M. Slot 0 impact would make the 100K (connected to GND) around 87K (due to parallel resistors). Slot 1 will have far less, nearly neglectable, impact on your circuit.

Are you setting the ADC measurement for 14 bits (default is 10)?

If you have a voltmeter, have you been able to measure the real input?

Maybe you have an Arduino around. What does it say?

I think I found the issue. The Apollo3 sheet indicates that the ADC uses a 4pF sampling cap

https://ambiq.com/wp-content/uploads/20 … asheet.pdf

19.3.2 ADC Sample-and-Hold Time

The ADC on the Apollo3 Blue is a successive approximation register (SAR) ADC with 4 pF input capacitance. If there is large input impedance to the ADC input, then the sample-and-hold time must be increased to ensure the 4 pF sampling capacitor has time to settle.

The Apollo3 Blue ADC sample-and-hold time is fixed at 5 ADC clock cycles. The ADC has two options for ADC sampling clock, HFRC or HFRC/2. This results in a sample-and-hold time of approximately 0.2 µs for 24 MHz HFRC/2 ADC clock or about 0.1 µs for the default 48 MHz HFRC ADC clock.

The time constant calculation is given here: https://ambiq.com/wp-content/uploads/20 … elines.pdf

A rough estimation of time constant is:

TC (nsec) = input impedance (kohm) x input capacitance (pF)

Assuming no external capacitance on the ADC input, a conservative value of 6 pF (the 4 pF ADC capacitance plus a couple pF for package pin impedance) can be used.

TC = 200k * 6 = 1.2uSec

The required hold time to guarantee that the capacitance has settled (charged/discharged) to meet target accuracy is:

5% accuracy (3TC): 3 * 1.2 µs = 3.6 µs

1% accuracy (5TC): 5 * 1.2 µs = 6 µs

10-bit accuracy (7TC): 7 * 1.2 µs = 8.4 µs

Therefore the sample and hold time is about 20 times too short even for 5% accuracy.

The solution is fairly simple for slow moving inputs like mine. Just add a cap between the ADC input and ground. I used a 1uF cap and the results now agree with my measured voltage.

good catch !

Thanks for this post, it solved my problem.

I am new to SpurkFun and just started working with the Artemis Thing Plus. I have a similar voltage divider from 3.3V to A0.

The ADC conversion was calculating 2.65V, then I adjusted for the ADC impedance and I got 2.9V.

After adding a cap on the voltage divider, I got the expected 3.3V.