HI,
I'm using INPUT_PULLUP via a 10k resistor to enable a dc-dc converter and therefore I need 3.3V at the pin. Now when I'm doing a analogRead it seems the pull-up vanishes. Is there a way round? I'm using this method with a 328 without any problems.
A good trick, I would like to see a video of that happening. However I suspect you don't mean it literality.
You are providing very little information here.
As a minimum you need to post a schematic of what you have and also the code you are using. As well as what makes you think this oh so real component is vanishing.
Hi @timtailors
There's a bit of an anomaly on the SAMD21, in that the ADC works by default even though the pin is configured as a GPIO. This happens without having to switch pin's peripherial multiplexer over to the ADC at position B, (see SAMD21 Datasheet Multiplexering Table, Section 7-1). In this case both the ADC and the GPIO pull-up resistor will work together.
However, if you do move the multiplexer switch over to ADC at position B, like the analogRead() function does, the digitial circuitry loses control over that pin. Therefore you'll lose the pull-up resistor.
The workaround is to manually configure the ADC in your sketch. The example below cofigures the ADC with the same (slow) conversion time as analogRead() on pin A0, however in this case the pull-up resistor will work:
// Set-up the ADC to read analog input on A0 with 12-bit resolution
void setup() {
SerialUSB.begin(115200); // Set-up the native serial port at 115200 bit/s
while(!SerialUSB); // Wait for the console to open
pinMode(A0, INPUT_PULLUP); // Activate the pull-up resistor on A0
ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV512 | // Divide Clock ADC GCLK by 512 (48MHz/512 = 93.7kHz)
ADC_CTRLB_RESSEL_12BIT; // Set ADC resolution to 12 bits
while(ADC->STATUS.bit.SYNCBUSY); // Wait for synchronization
ADC->SAMPCTRL.reg = 0x3f; // Set max Sampling Time Length to half divided ADC clock pulse times SAMPCTRL (341.33us)
ADC->INPUTCTRL.bit.MUXPOS = 0x0; // Set the analog input to A0
while(ADC->STATUS.bit.SYNCBUSY); // Wait for synchronization
ADC->CTRLA.bit.ENABLE = 1; // Enable the ADC
while(ADC->STATUS.bit.SYNCBUSY); // Wait for synchronization
}
void loop() {
ADC->SWTRIG.bit.START = 1; // Initiate a software trigger to start an ADC conversion
while(ADC->STATUS.bit.SYNCBUSY); // Wait for write synchronization
while(!ADC->INTFLAG.bit.RESRDY); // Wait for the conversion to complete
ADC->INTFLAG.bit.RESRDY = 1; // Clear the result ready (RESRDY) interrupt flag
while(ADC->STATUS.bit.SYNCBUSY); // Wait for read synchronization
int result = ADC->RESULT.reg; // Read the ADC result
SerialUSB.println(result); // Output the result
delay(500); // Wait for 500ms
}
Hi @MartinL,I guess that could be the solution.
I assumed something like that and what you describe would fit spot-on to the behaviour.
In your example you're using A0. How can I change this so it's working with PORTA21?
ADC->INPUTCTRL.bit.MUXPOS = 0x0;
My declaration for PORTA21 in variant.cpp looks like
{ PORTA, 21, PIO_ANALOG, 0, ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // ADC/AIN[1]
Originally it was
{ PORTA, 21, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 },
Do I need to do other changes in variant.h as well and what do I need to write to
ADC->INPUTCTRL.bit.MUXPOS = ?; ?
Hi @timtailors,
Unfortunately, port pin PA21 doesn't have any ADC input functionality, irresepective of how it's defined in the "variant.cpp" file.
The key to which pin offers what functionality is covered by the SAMD21 Datasheet's "Port Function Multiplexing" table, in section (chapter) 7.
It's not necessary to change the variant.h or variant.cpp to gain ADC functionality through the registers.
If you're using an Arduino Zero the analog Arduino to port pin mapping is as follows:
A0 => AIN0 (MUXPOS = 0x00)
A1 => AIN2 (MUXPOS = 0x02)
A2 => AIN3 (and so on...)
A3 => AIN4
A4 => AIN5
A5 => AIN10
Hi @MartinL , thanks for your reply. Oh no, obviously I made a mistake there. There is a chance that I could change my circuit to another pin. I will try this and give a feedback if your suggestion worked
Edit;
it's working!!! Great, thank you. How did you figure out or know that "There's a bit of an anomaly on the SAMD21" ?
By accident, one time I forgot to add the port configuration for the ADC, but found that it still worked.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.