getADC() returns 0.0 with TMR5 active

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
pjc30943
Posts: 220
Joined: 01 December 2005, 18:45 PM

getADC() returns 0.0 with TMR5 active

Post by pjc30943 »

I looked in the resource usage section, but I'm still uncertain why I'm seeing this specific effect:

When TMR5 is untouched, the getADC() function works all the time.
After setting up TMR5, getADC() often returns 0.0.

What shared resources do they have?

At first though it seemed to be an interrupt-related issue since some are enabled, but interrupts are disabled around the getADC() command with no change.
Paul
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: getADC() returns 0.0 with TMR5 active

Post by dkinzer »

pjc30943 wrote:After setting up TMR5, getADC() often returns 0.0.
In what way is Timer5 being set up? Do you have a small test case that demonstrates the problem.

It could be an undetected problem with task suspension/resumption relating to the ADC. You can test this hypothesis by locking the task before the GetADC() call and unlocking it afterward.
- Don Kinzer
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

It could also be caused by a resource conflict if multiple tasks attempt to use the ADC. There is only one ADC in the system and if a conversion is underway when another call to GetADC() is made the latter call will silently return 0.

The locking method described in my previous response will guard against this problem unless an ISR uses the ADC. The alternate method to protect against this problem is to create a semaphore variable representing the ADC. Then, in each place that you call GetADC() you'll want to first acquire the semaphore, call GetADC() and then clear the semaphore. This technique can be used on any resource that must be used serially. Note, however, that you probably do not want to use this technique in an ISR because of the delay that it will introduce.

Code: Select all

Public adcSem as Boolean
...
  Do While Not Semaphore(adcSem)
  Loop
  Call GetADC(chan, adcVal)
  acdSem = False
- Don Kinzer
Post Reply