Interrupt on external counter

edmunds

Senior Member
Dear all,

I know interrupts are not the most favorite topic around here :). Anyway, I have debugged things as far as I could and it still does not work as I expect it to (maybe wrongly), so here is the question.

I'm trying to count pulses on C.0 on 40X2 and interrupt on certain number of them counted. I can see pulses happening on the scope, I can measure them to the same as on the scope with pulsin and I can see the timer variable increment as expected, but no interrupt ever happens. The pulses are about 1.1ms long, code below.

Code:
[color=Blue]setfreq em64

setintflags [/color][color=Navy]%10000000[/color][color=Black], [/color][color=Navy]%10000000[/color]

[color=Blue]settimer count [/color][color=Navy]65000          [/color][color=Green]'Timer in count mode, preload to increment on every x pulse[/color]

[color=Blue]high C.2
low D.5[/color]

[color=Black]main:[/color]
[color=Green];  pulsin C.0,1,w0
;  sertxd(#w0,LF,CR)
  [/color][color=Blue]pause [/color][color=Navy]200[/color]
[color=Blue]goto [/color][color=Black]main[/color]

[color=Blue]interrupt:
  [/color][color=Purple]toflag [/color][color=DarkCyan]= [/color][color=Navy]0
  [/color][color=Blue]inc [/color][color=Purple]b0
  [/color][color=Blue]sertxd ([/color][color=Black]#[/color][color=Purple]b0[/color][color=Black],[/color][color=Red]"."[/color][color=Black],#[/color][color=Purple]timer[/color][color=Black], [/color][color=Blue]LF[/color][color=Black], [/color][color=Blue]CR)
  setintflags [/color][color=Navy]%10000000[/color][color=Black], [/color][color=Navy]%10000000[/color]
[color=Blue]return[/color]

What did I do wrong?

Thank you for your time,

Edmunds
 

stan74

Senior Member
Try modifying this
Code:
init:
setint or %00000000,%00001001,C ; C.0 or C.3
symbol lpwm = w7
symbol rpwm = w8
symbol lcount = b12
symbol rcount = b13
let lpwm = 474 ;95%
let rpwm = 474
main:
sertxd ("lcount = ",#b12,cr,lf)
sertxd ("rcount = ",#b13,cr,lf)
goto main


interrupt:
if pinC.0 = 1 then
	inc lcount
endif
if pinC.3 = 1 then
	inc rcount
endif
if lcount = 100 or rcount = 100 then
	if lcount < rcount then
		let lpwm = lpwm + 5 max 499 ; 100% pwm
		let rpwm = rpwm - 5 min 449 ; 90% pwm
	elseif lcount > rcount then
		let rpwm = rpwm + 5 max 499 ; 100% pwm
		let lpwm = lpwm - 5 min 399 ; 90% pwm
		pwmduty C.1,lpwm : pwmduty C.2,rpwm ; adjust speed
	endif
let lcount = 0 : let rcount = 0
endif
setint or %00000000,%00001001,C ; C.0 or C.3
return
It's to read encoder wheels and change pwm motor speed to maintain a straight course.
Stan.
The interrupt doesn't need enabling like a timer overflow interrupt does.
 
Last edited:

stan74

Senior Member
That's the page I copied it from. You're using c.7 I think. I'm usually wrong though. It's the thought that counts :)
 

stan74

Senior Member
I think you are using a timer overflow interrupt edmunds.
Code:
#picaxe 28x2
setfreq m16

symbol servocount= b0
symbol deadtime= b1
symbol servopoz=b2
symbol either=b3
Init:
let servopoz=10
let servocount=servopoz
let deadtime=100
let either=1
;---------- interrupt      
TOFlag = 0
Timer = 65535             '
SetTimer 65524
SetIntFlags %10000000,%10000000
;----------

Main:
do
high b.5
pause 1
low b.5
pause 1
loop  

 
Interrupt:
if either=1 then
	dec servocount
	if servocount=0 then
		low b.6
		let servocount=servopoz
		let either=0
	endif
else	dec deadtime
	if deadtime=0 then
		high b.6
		let deadtime=50
		let either=1
	endif
endif

Int_Enable:
TOFlag = 0
Timer = 65535
SetIntFlags %10000000,%10000000
return
This runs each tick.well a few
 
Last edited:

stan74

Senior Member
edmunds, please consider the time an interrupt takes on a picaxe. It's like putting pauseus 50 between every line of the main code. OK for a one off but 2 encoder wheels is a lot of interrupts and in my view not worth doing on a picaxe. All the things an interrupt should do you can't because of it's speed. The above was to simulate the servo command.rubbish. and pwm can't vary duty enough and too fast. shame.
 

stan74

Senior Member
ps you didn't enable the interrupt anyway. Like this maybe.
Code:
setfreq em64

setintflags %10000000, %10000000

settimer count 65000          'Timer in count mode, preload to increment on every x pulse
gosub enableinterrupt
high C.2
low D.5

main:
;  pulsin C.0,1,w0
;  sertxd(#w0,LF,CR)
  pause 200
goto main
enableinterrupt:
interrupt:
  toflag = 0
  inc b0
  sertxd (#b0,".",#timer, LF, CR)
  setintflags %10000000, %10000000
return
and you can't??? use sertxd in an interrupt
 

stan74

Senior Member
Try this for pulses on c.1
Code:
init:
setint %00000000,%00000010,C ; C.1
symbol counter = w0
main:
sertxd ("counter = ",#w0,cr,lf)
goto main
;
interrupt:
inc counter
setint %00000000,%00000010,C 
return
sorry,count is a reserved word. I just tried this and it works on a 28x2...honest
 
Last edited:

edmunds

Senior Member
Dear Stan,

Your example in post #6 did the trick. I did not set the timer variable to 65535. As soon as I did that, all works like a charm. This is not how I read the manual it should work, but now I know and I'm happy :).


Thank you,

Edmunds
 

stan74

Senior Member
Try putting pwm on c.1 like this. 1KHz pwm, I scoped c.1 and it's 1KHz. worth playing with
Code:
#picaxe 28x2
init:
setint %00000000,%00000010,C ; C.1
pwmout pwmdiv16, C.1, 124, 249 ; 1000Hz at 50% @ 8MHz
pwmduty c.1,249
symbol counter = w0
main:
;
goto main
;
interrupt:
inc counter
toggle c.2
setint %00000000,%00000010,C 
return
 

stan74

Senior Member
Strange,if you run the above code it's c.2 that's toggled but there's 1KHz on c.1 and 249.3Hz on c.2.
Try it. what's that about?
 

edmunds

Senior Member
In your original code you pulsin w0 but the interrupt incs b0??
Yeah, because you need a word variable to capture the length of a pulse and I don't need to see anything else than that all pulses are counted in the interrupt. Non-related. The code is not supposed to do anything useful except to show it works (or does not) and allow me to check actual timings of pulses compared to calculated that I have designed for.

Calling it a night.

Thanks again,

Edmunds
 
Top