pico analog read issue/stability

Posted on
  • I've just run a set of tests after noticing that the pico analog in reading is a lot less stable compared to the original.

    I've also done a set of range tests where both devices are given the same fixed ref voltage. The original rock solid. I've tried adding a cap to ground on pico, I've tried other ana pins and multiple picos same results.

    I'm not sure what I should expect I'm now considering and external ADC which is a shame.
    Any ideas?

    //For example he's the log pico where I've linked v3.3 to A6
    Mon, 15 Jun 2015 13:49:25 GMT,0.97535667963,4014
    Mon, 15 Jun 2015 13:49:35 GMT,0.97633325703,4014
    Mon, 15 Jun 2015 13:49:45 GMT,0.97804226749,4014
    Mon, 15 Jun 2015 13:49:55 GMT,0.99098191805,4055
    Mon, 15 Jun 2015 13:50:05 GMT,0.98902876325,4055
    Mon, 15 Jun 2015 13:50:15 GMT,0.99439993896,4055
    Mon, 15 Jun 2015 13:50:25 GMT,0.99439993896,4055
    Mon, 15 Jun 2015 13:50:35 GMT,0.99537651636,4096
    Mon, 15 Jun 2015 13:50:45 GMT,0.99537651636,4096
    Mon, 15 Jun 2015 13:50:55 GMT,0.98707560845,4055
    Mon, 15 Jun 2015 13:51:05 GMT,0.99537651636,4096
    Mon, 15 Jun 2015 13:51:15 GMT,0.97535667963,4014
    Mon, 15 Jun 2015 13:51:25 GMT,0.99439993896,4055
    Mon, 15 Jun 2015 13:51:35 GMT,0.99537651636,4096
    Mon, 15 Jun 2015 13:51:45 GMT,0.99098191805,4055
    Mon, 15 Jun 2015 13:51:55 GMT,0.99098191805,4055
    Mon, 15 Jun 2015 13:52:05 GMT,0.99537651636,4096
    Mon, 15 Jun 2015 13:52:15 GMT,0.99439993896,4055
    Mon, 15 Jun 2015 13:52:25 GMT,0.99098191805,4055
    Mon, 15 Jun 2015 13:52:35 GMT,0.99098191805,4055
    Mon, 15 Jun 2015 13:52:45 GMT,0.99537651636,4096


  • Thanks - yes, it does look bad. Just looked at this and it seems to be a problem with the STM32's cache grabbing more data while reading from analog.

    Try poke32(0x40023C00, peek32(0x40023C00)&~256); - you'll have to do it on onInit if you want it to stay working between power cycles - it disables prefetch.

    For instance, with B1 shorted to 3.3v:

    function test(pin) {
      var a = new Uint16Array(1000);
      var mean = 0;
      for (var i=0;i<a.length;i++) {
        a[i] = analogRead(pin)*4096;
        mean += a[i];
      mean /= a.length;
      print("Mean: "+mean);
      var variance = 0;
      for (var i=0;i<a.length;i++) {
        var d = a[i]-mean;
        variance += d*d;
      variance /= a.length;  
      print("Variance: "+variance);
    poke32(0x40023C00, peek32(0x40023C00)|256);
    console.log("With prefetch");
    poke32(0x40023C00, peek32(0x40023C00)&~256);
    console.log("Without prefetch");
    //With prefetch
    //Mean: 4080.495
    //Variance: 309.49997499999
    //Without prefetch
    //Mean: 4091.12
    //Variance: 49.1316

    So yeah, massive difference. I need to see how it affects performance before I put it in the actual firmware - I guess it's possible it could just be disabled while doing the analog read, but I wonder whether that would be good enough.

  • There's an article by ST on it here: http://www.st.com/web/en/resource/techni¬≠cal/document/application_note/DM00050879¬≠.pdf

    They suggest some other methods, but as far as I can tell they're actually not much better than turning prefetch off. Looks like the performance hit of disabling prefetch is about 3% so it's probably worth dropping it and getting the better accuracy.

  • @Gordon thanks the change makes a big difference but..
    Previous error rate was 48% now about 5%

    There is a consistency with a lot of the errors with & without prefetch most are
    41, -40, -81 , -122 to reference

    With prefetch off I did 600 readings ever 10 secs for a range of reference voltages
    17 times error was 41
    15 times error was -40
    1 time error was -81
    1 time error was -122

    This is still to high for some of my projects.
    So I might need the addition of Averaging of N-X ADC samples as ST artical?

  • It's frustrating - I'm not really sure why it's so bad when the F1 was fine. It's interesting that it is bad enough to warrant ST writing that document on it. I wonder whether if the whole CPU was clocked down it might be better.

    The other thing is Espruino reads an analog value giving the ADC the longest time period possible - which is supposed to mean the highest accuracy. However it's possible that if the problem is to do with voltage fluctuations, maybe getting the conversion done as soon as possible is the best bet!

    It strikes me that some of the glitchiness could actually be from USB... I'd be interested to know what happens if you power Espruino from a battery and log the error rates, then see how bad it is with and without USB connected.

    At least doing the N-X averaging is a lot easier in Espruino! Something like:

    function nxavr(pin) {
      var a = new Uint16Array(100);
      for (var i=0;i<a.length;i++) a[i] = analogRead(pin)*4096;
      var middle = new Uint16Array(a.buffer,25*2,50);
      return E.sum(middle)/middle.length;

    So that's 100 samples, dropping the 25 smallest and 25 largest.

  • Thanks for this will give it a try on battery tomorrow along with the N-X

  • I'm wondering if it's noise on the power supply too... if you have a scope, looking at the usb power, and the output of the regulator while doing this might be informative.

  • Just to add that it turns out prefetch adds ~10% to the power consumption, but only reduces performance by 3%. Looks like it's getting turned off by default unless anyone has any reasons not to?

    If anyone is interested, you can 'overclock' the flash memory by reducing the wait states to 1: poke32(0x40023C00, (peek32(0x40023C00)&~3) | 1);

    Seems to add around 8% performance. I'm not sure how reliable it is though - at least according to the datasheet you're not supposed to run it that fast.

  • Ok initial tests on battery only and No N-X averaging still getting the odd +40 error. Put a decoupling cap on ana in and is looking good.

    BTW using the Appcon LoRa module to send pico data to Node-RED on Raspberry PI for data logging.

  • Put a decoupling cap on ana in and is looking good.


    ST do mention in the app notes that to get a good reading you want a relatively low impedance on the input. A capacitor across the analog input would really help with that - I should have thought about that before.

  • Arr spoke too soon! error rate down and oddly all errors occurred at 2/3 vin 2.475v :: 3072 on ADC . In all cases the error was +41 the cap helps for sure but I'm going to try N-X avrg.

    BTW I looked at the original board log and it was erroring too at 2/3 vin when USB powered.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

pico analog read issue/stability

Posted by Avatar for LawrenceGrif @LawrenceGrif