Converting a Digital Pin to Analog

I got sloppy and made some assumptions when I designed a board based upon the Zero. In the Variants file I saw that PA08 (Arduino pin 4) was also analog capable (ADC/AIN[16]). So I went ahead and routed an analog signal to it. Now, it looks like I need to do some non-standard configuration to get that pin to operate as an analog input.

Do I need to do it in the Variants files, or can I do it in my sketch. I'd like to avoid creating a "unique" variants file for my project.

Can this be done?

Has anyone successfully done it?

Any pointers?



I tried the following in the Variants files:

#define NUM_ANALOG_INPUTS    (9u)

#define PIN_A8               (4ul)

static const uint8_t A8  = PIN_A8 ;


But that didn’t work.

As I was typing his I noticed this:

#define analogInputToDigitalPin(p)  ((p < 6u) ? (p) + 14u : -1)

I need to figure out if that’s the cause behind it not working…

Well, I got lucky.

I couldn't get any of that to work, so I was looking around at mechanically swapping pins (cutting traces, etc.) Looking at my schematic I noticed I hadn't used a couple of the Arduino native AN pins. And... I had actually brought them out to test points for cases just like this. Looks like there'll be at least a rev3 of this board.

However, I'd still like to know how to do this for those times when 8 analogs aren't enough.

Any bright ideas?

Well, I came up with an ugly hack. It is a modified copy of the analogRead function that is in the wiring_analog.c file. Use at your own peril.

void syncADC() {
  while (ADC->STATUS.bit.SYNCBUSY == 1)

uint32_t analogRead_custom( byte adc_channel_number )
  uint32_t valueRead = 0;

  ADC->INPUTCTRL.bit.MUXPOS = adc_channel_number; // Selection for the positive ADC input

  ADC->CTRLA.bit.ENABLE = 0x01;             // Enable ADC

  // Start conversion
  ADC->SWTRIG.bit.START = 1;

  // Clear the Data Ready flag

  // Start conversion again, since The first conversion after the reference is changed must not be used.
  ADC->SWTRIG.bit.START = 1;

  // Store the value
  while ( ADC->INTFLAG.bit.RESRDY == 0 );   // Waiting for conversion to complete
  valueRead = ADC->RESULT.reg;

  ADC->CTRLA.bit.ENABLE = 0x00;             // Disable ADC

  return valueRead;