Reading ADC inputs on a BluePill board

Hello all,

   just a small question on RIOT-OS on the bluepill board.

I’m not getting any ‘actual’ values when using ADC8 and ADC9. The values are somewhat constant. I’m basicly using the example as mentioned in the periph_adc test program. Only using 12 bit resolution and only ADC inputs 8 and 9. I’ve connected the inputs via a potentiometer to the 3.3V supply. I’ve verified that the input value changes via a voltmeter.

So does any have an idea what could be the problem? Has any one used the ADC’s 8 or 9 on the blue pill?

Thanks. John

Maybe make a bug report on github. It might get more traction.

Hi Kevin. Thanks for the tip.

I’m a newbie on RIOT-OS so I thought that a bug report might be too much. Assumed that I probably made a mistake somewhere down the line. I’ve `modified - changed from m10 bit to 12 bit resolution - and recompiled the perihp_adc example from the RIOT test folder. And got the same results. Exchanged the bluepill PCB with another one. Again the same results. So I get a value in the range of 1823 … 1822 for ADC 8 and 1527 … 1530 for ADC 9. No change when I modify the voltage levels at the input pins of PB0 and PB1. Changing to other pins have the identical behavior, only other values.

I think bug reports would be easier to search for others having the same issues. Either way I will look into it today!

Looking into this I found:

Running test/periph_adc with the #define RES ADC_RES_12BIT

ADC_LINE(8) is constant (as that is the internal temperature) and ADC_LINE(9): is also constant as that is the internal voltage reference. As indicated https://github.com/RIOT-OS/RIOT/blob/master/boards/common/blxxxpill/include/periph_conf.h#L66

Now I guess you are talking about ADC_LINE(6) and ADC_LINE(7) which are connected to PB0 (ch 8) and PB1 (ch9) respectively.

I do see an issue with that, the values are not responding. -> They seem to work fine, just make sure you are on the B0 and B1 and not B10 and B11 :laughing:

I will continue to look into that.

In conclusion I believe you were just looking at the internal temperature ref and voltage ref. Please consult the above link for mapping of ports to line numbers (it is just an array that counts up).

Hi Kevin. Thanks for the help so far.

I did place the analogue signal on the B0 and B1 as the pinout diagram of the Bluepill indicates. In the meantime I’ve added some ‘peek’ commands and I noticed that the ADC regular sequence register 3 (ADC_SQR3) of the STM32 was set to 0x41. Which would indicate channels 1 and 4 are to be used. Adc regular sequence number register 1 (ADC_SQR1) is however set to 0. Which would indicate 1 conversion is to be done of the regular sequence being channel 1.

When I change my test program to use ADC1 (= pin A1) instead and apply the signal level to pin A1. It works! I can see data returning that when multiplied results into the value of the signal level. So yes the ADC’s work, only why are they not the inputs that I want to use (being PB0 and PB1)?

So I would conclude at this moment that the Bluepill is/gets setup incorrect.

With kind regards, John

Hi Kevin, found the source! The adc_config table of the STM as used (RIOT/boards/common/blxxxpill/include/periph_conf.h) specifies: /**

  • @name ADC configuration
  • @{ / static const adc_conf_t adc_config[] = { { .pin = GPIO_PIN(PORT_A, 0), .dev = 0, .chan = 0 }, { .pin = GPIO_PIN(PORT_A, 1), .dev = 0, .chan = 1 }, { .pin = GPIO_PIN(PORT_A, 4), .dev = 0, .chan = 4 }, { .pin = GPIO_PIN(PORT_A, 5), .dev = 0, .chan = 5 }, { .pin = GPIO_PIN(PORT_A, 6), .dev = 0, .chan = 6 }, { .pin = GPIO_PIN(PORT_A, 7), .dev = 0, .chan = 7 }, { .pin = GPIO_PIN(PORT_B, 0), .dev = 0, .chan = 8 }, { .pin = GPIO_PIN(PORT_B, 1), .dev = 0, .chan = 9 }, / ADC Temperature channel / { .pin = GPIO_UNDEF, .dev = 0, .chan = 16 }, / ADC VREF channel */ { .pin = GPIO_UNDEF, .dev = 0, .chan = 17 }, }; So not all channels as mentioned by the pinout of the bluepill can be used as such. The code above shows that only the ADC’s 0,1,4,5,6,7,8,9,ADC temperature channel and ADC VREF channel can be addressed as line 0,1,2,3,4,5,6,7,8 and 9.

The writers of RIOT most likely wanted to not assign ADC’s 2 and 3 because these can also be used by the serial port (serial shell).

So a newbie mistake after all…

John

1 Like