trick and tips

jyb

Senior Member
i need to generate an interrupt for any variation of a potentiometer, positive or negative; does somebody knows the way to do this ?
used picaxe is 40x2 new:):)
 

premelec

Senior Member
Perhaps along these lines: [not a real interrupt!]

DO
Readadc A
pause x
Readadc B

If A<>B then gosub change
LOOP

change:

'code look at A & B differences and do something accordingly

RETURN
 

Milos

Member
I am afraid that this idea is not right. I tried to read a potentiometer repeatedly without touching it and the read valued varied. I would get something like 126,126,127,126,127 ... .
 

womai

Senior Member
I can't see a way to do this on a Picaxe (or a PIC for that matter). Apart from the fact that there is no "interrupt on ADC change" (as opposed to an "interrupt on change" of a digital pin), it would not make much sense to have such an interrupt in the first place: Just imagine the input level sits right between ADC value 100 and 101. The slightest amount of random noise (and there will always be SOME noise) will make the ADC value vary randomly between 100 and 101, causing a string of interrupts even though the input isn't really changing in any direction.

What you could do instead is set up a timer interrupt, e.g. every 1/100th second which then checks the ADC value compared to the previously stored. If it has change by more than 2 (or more steps, depending on the noise, but never make it just 1), then do what you want to do on ADC change and then update your reference (stored) value with the new one. That will accomplish what you wanted to do in the first place.

Wolfgang
 

Milos

Member
There is another thing that should be considered - time. I measured the time needed for readadc command on 28X2@8MHz. It was about 2 msec and there was no difference between readadc and readadc10. I would read the value not so often (100 per second) or use higher setfreq.
 

hippy

Ex-Staff (retired)
There is no 'interrupt on analogue change' capability on PICAXE so a change can only be detected by polling and comparing with previous reading.

On the 18M2 it would be possible to put this in a separate task while the main program runs in its own task. The 40X2 doesn't however have multi-tasking capabilities.

Another possibility is to use a separate PICAXE which monitors for change and generates an interrupt when that occurs. The pot can go to analogue inputs on both the master PICAXE and that monitoring. As noted, analogue inputs can change very frequently due to noise but this could be filtered out in the monitoring PICAXE. This is the approach I would most likely take.
 

jyb

Senior Member
sharpened mind gives fine ideas

There is no 'interrupt on analogue change' capability on PICAXE so a change can only be detected by polling and comparing with previous reading.

On the 18M2 it would be possible to put this in a separate task while the main program runs in its own task. The 40X2 doesn't however have multi-tasking capabilities.

Another possibility is to use a separate PICAXE which monitors for change and generates an interrupt when that occurs. The pot can go to analogue inputs on both the master PICAXE and that monitoring. As noted, analogue inputs can change very frequently due to noise but this could be filtered out in the monitoring PICAXE. This is the approach I would most likely take.
fortunately i bought a 18m2 for some tests so i am going to do so
one task pulsing out to the stepper and second task watching pot
i presume tasks can communicate together by accessing to same registers ?,
an adc input filter to kill noise and "le tour est joué"
thanks a lot to hippy and everybody
jyb
 

jyb

Senior Member
yes but....

I can't see a way to do this on a Picaxe (or a PIC for that matter). Apart from the fact that there is no "interrupt on ADC change" (as opposed to an "interrupt on change" of a digital pin), it would not make much sense to have such an interrupt in the first place: Just imagine the input level sits right between ADC value 100 and 101. The slightest amount of random noise (and there will always be SOME noise) will make the ADC value vary randomly between 100 and 101, causing a string of interrupts even though the input isn't really changing in any direction.

What you could do instead is set up a timer interrupt, e.g. every 1/100th second which then checks the ADC value compared to the previously stored. If it has change by more than 2 (or more steps, depending on the noise, but never make it just 1), then do what you want to do on ADC change and then update your reference (stored) value with the new one. That will accomplish what you wanted to do in the first place.

Wolfgang
your principle is surely good but mi stepper is heavy to move and i need to push it up to 1000rpm , so, for that ,pulse loop must be as shorter as possible, so shorter ,that program part dedicated to potentiometer watching would be out of pulse loop to gain time : like interrupt or paralell (?) tasks
 

MartinM57

Moderator
How will you know that 126, 127, 127. 127, 126, 126, 127 etc is noise from a stationary potentiometer, or required and valid signals from a moving one?
 

jyb

Senior Member
interrupt on adc change

I can't see a way to do this on a Picaxe (or a PIC for that matter). Apart from the fact that there is no "interrupt on ADC change" (as opposed to an "interrupt on change" of a digital pin), it would not make much sense to have such an interrupt in the first place: Just imagine the input level sits right between ADC value 100 and 101. The slightest amount of random noise (and there will always be SOME noise) will make the ADC value vary randomly between 100 and 101, causing a string of interrupts even though the input isn't really changing in any direction.

What you could do instead is set up a timer interrupt, e.g. every 1/100th second which then checks the ADC value compared to the previously stored. If it has change by more than 2 (or more steps, depending on the noise, but never make it just 1), then do what you want to do on ADC change and then update your reference (stored) value with the new one. That will accomplish what you wanted to do in the first place.

Wolfgang
it seems that interrupt on adc change theoreticaly exist
i done a compsetup on adc1 which give in compvalue a result which itself
set compflag on setintflags .This is explained on manual 2, i tryed it, and result i obtained is : " it works but a bit erratic"
hippy said there is an issue with this command and picaxe ' s staff is brainstorming on subject:eek:
 

hippy

Ex-Staff (retired)
Using comparators can determine when an ADC goes above or below a certain level but is hard to use as a 'changed from last time' indicator. One could possibly create a 'feedback loop' with DAC output or PWM but that would get complicated and may not have enough stability.

Though multi-tasking can solve the problem in some cases, it might not be ideal if specific timing is required in an application; motor drive pulse timings would be affected through interleaving the analogue handling task. Motor speed could then become variable and jittery.

The best approach would seem to be to run the PICAXE as fast as possible, poll the analogue and handle changes within a loop which keeps as constant timing as it can. If this loop time is not fast enough some other approach may be necessary.
 

BeanieBots

Moderator
Make yourself a "window comparitor" (Google will give a circuit).
Feed one input with your POT, the other with PWM from the PICAXE.
The comparitor output can then be used to trigger a logic interrupt pin.
 

srnet

Senior Member
it seems that interrupt on adc change theoreticaly exist
Really, how does that work, cant recall seeing it mentiopned in PIC data sheets ?

Neither does it make sense, the very nature of the environment means that the very lower bits of the ADC value will be in a constant state of change due to electrical noise etc.
 

womai

Senior Member
You could try something like this (not tested, I just whipped up the code blindly) - basically my original suggestion translated into Picaxe Basic:

Code:
symbol oldval = w0
symbol newval = w1
symbol thresh_high = w3
symbol thresh_low = w4
symbol mindiff = 2 ' minimum change before action is taken
symbold ADC_CHAN = 1 ' whatever channel you want to use

.... init thresh_low and thresh_high

myloop:

   readadc10 ADC_CHAN, newval

   if newval >= thresh_high or newval <= thresh_low then

      gosub DO_WHAT_YOU_WANT_TO_DO_ON_A_CHANGE

      if newval >= mindiff ' avoid wraparound
            thresh_low = newval - mindiff
      else
            thresh_low = 0
      endif

      thresh_high = newval + mindiff

   endif

goto myloop
As long as there isn't any (sufficiently large) change this loop should execute around 700 times at 8 MHz, or 3500 times at 40 MHz (the max. speed for the old 28X2; new one could even go to 64 MHz). So that looks like it could be fast enough for what you want to achieve.

Increase the value of mindiff if you see a lot of noise.

Wolfgang
 
Last edited:

womai

Senior Member
an adc input filter to kill noise and "le tour est joué"
No, that won't work. No analog filter in the world can prevent the least significant bit of the result from potentially wiggling around randomly from one reading to the next. But you can catch that in software, see my example in the previous post.

To provide pulses to the servo you could use the pwmout command and adjust the duty cycle as needed. The PWM is implemented in dedicated hardware so it keeps running at a steady pace completely independent of what the program does.

Make sure you use pwmduty to change the duty cycle (pwmout is needed only once, to start the pwm). It is much faster to execute than pwmout, and pwmout resets the pwm counter which would cause the servo to flutter.
 
Last edited:

premelec

Senior Member
@jyb I don't know if you've got it solved yet but perhaps try running at fastest clock speed and then tailor pulsouts to the readadcs in the loop -

DO
READADC x 'pot in
x = x * k 'scale factor
PULSOUT x
LOOP

If this is too slow at least you can find out how much so... I'm not fully understanding your situation - hope this helps...
 

jyb

Senior Member
you are right

No, that won't work. No analog filter in the world can prevent the least significant bit of the result from potentially wiggling around randomly from one reading to the next. But you can catch that in software, see my example in the previous post.

To provide pulses to the servo you could use the pwmout command and adjust the duty cycle as needed. The PWM is implemented in dedicated hardware so it keeps running at a steady pace completely independent of what the program does.

Make sure you use pwmduty to change the duty cycle (pwmout is needed only once, to start the pwm). It is much faster to execute than pwmout, and pwmout resets the pwm counter which would cause the servo to flutter.
about analog filter, you are right ,i try it ,i get some stabilisation but the least significant bit keep toggleling and only solution is software
for pwm i began with it but between motor stepper and picaxe is a driver which gives power and it accepts only varying frequency not varying period
thanks for your time
 

jyb

Senior Member
it's just what i done

@jyb I don't know if you've got it solved yet but perhaps try running at fastest clock speed and then tailor pulsouts to the readadcs in the loop -

DO
READADC x 'pot in
x = x * k 'scale factor
PULSOUT x
LOOP

If this is too slow at least you can find out how much so... I'm not fully understanding your situation - hope this helps...
hi premelec
what you say is what i done and it is the faster method i found
what i am doing is to drive a big stepper motor by a potentiometer and using a sunshine driver which deliver power , its command signal
must be a varying frequency(not varying period like pwm do)
thanks for your help:)
 
Top