This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

ADC input selection change time

I am using internal ADC to sample 2 (sometimes 3) channels on about 333Hz frequency. What I do is:

  • set channel 1 as input (always two-thirds prescaling, VBG reference)

  • start 3ms repeated timer

  • when timer triggers, sampling at chan1 starts and app goes to sleep

  • wakeup when adc finishes - check one more time if it really is not busy - store result

  • change ADC input to channel 2 and start sampling - then go to sleep

  • wait for wakeup again, check if not busy, store result - change input to chan 1 - go to sleep

  • wait for another 3ms timer trigger...

My problem is that sometimes (very rarely, but regularly!) my readings seems to be connected, ex. Chan1 should read value about 0, Chan2 should read value about 1000. In most cases it is ok, but sometimes chan1 reads value about 1000 (just like CONFIG.INPSEL mux react too slowly). It is possible that my code is buggy, but I am wondering if it is possible that ADC reacts REALLY slowly for its input changes when sampling really fast.

Parents
  • Hi Wojtek

    Your sequence of events seems to be reasonable, i.e. that you store the ADC result before reconfiguring to the second AIN pin. This problem is not familiar to me, I'm not sure if I tested consecutive sampling from two different pins.

    To see if it is a MUX problem, can you try to add delay between configuring and start sampling.

    Update 24.6.2015 Reviewing your case again I am thinking there might be a different reason for your observation. What I am suspecting is that occasionally your sampling sequence is not finished when the TIMER triggers again a new sampling sequence. This could happen if the CPU is doing other stuff for 2-3ms, then the TIMER interrupt may be pending for 2-3ms and you will have two timer interrupts executing very close to each other. Possible scenario:

    • when timer triggers, interrupt is pending but not executed because the CPU is busy

    • in ~3ms the CPU is no longer busy and the timer interrupt is executed, sampling at chan1 starts and app goes to sleep

    • wakeup when adc finishes - check one more time if it really is not busy - store result

    • another timer interrupt is triggered, and execution of timer handler is pending

    • change ADC input to channel 2 and start sampling - then attempting to sleep

    • CPU does not sleep because the second timer interrupt is pending, configuring the ADC again to the first channel while the ADC is supposed to sample for the second channel.

    From this scenario, you might get a false result.

    Could this possibly be happening in your case? What happens if you decrease the sampling frequency to say 10ms, does the problem go away? Are you using the CPU for something else than just the ADC sampling? Do you have softdevice enabled perhaps?

    If this is the problem, possible solution would be to just wait for the ADC to finish sampling instead of going to sleep (that is going to cost you increased current consumption) or you could maintain a state variable in order to prevent the above scenario.

  • Thank You Stefan,

    While testing I noticed that my timer handler function is scheduled, and even after stopping that timer, function executes few more times. That means You could be right, and my application is so overloaded with other operations (softdevice enabled, 2 or 3 services are in use... My scheduler queue is quite big) that sometimes it just have to take some time to execute all operations pending in scheduler.

    BUT on the other hand, my workaround with adding additional dummy readings (channel selection -> dummy reading -> proper reading) works fine, I see no more bad readings while using it. This is a bit confusing.

    I am not able to test it with longer interval right now - I'll try to do it some day and I will post results then.

Reply
  • Thank You Stefan,

    While testing I noticed that my timer handler function is scheduled, and even after stopping that timer, function executes few more times. That means You could be right, and my application is so overloaded with other operations (softdevice enabled, 2 or 3 services are in use... My scheduler queue is quite big) that sometimes it just have to take some time to execute all operations pending in scheduler.

    BUT on the other hand, my workaround with adding additional dummy readings (channel selection -> dummy reading -> proper reading) works fine, I see no more bad readings while using it. This is a bit confusing.

    I am not able to test it with longer interval right now - I'll try to do it some day and I will post results then.

Children
No Data
Related