Interrupt advice please?

I have a simple circuit monitoring four magnets on a pulley wheel to measure the speed and direction of the shaft it's attached to.
Prop-SD-v2.jpg
The circuit diagram above shows how it works, the two Hall Effect sensors being mounted close together so that as a magnet passes them, it activates first one and then the other with a bit of overlap which allows the direction to be established. The whole thing seems to work very well in my tests so far.

Using the PULSEIN command to measure the high period of the pulse train seems to be ideal. It times out after 0.65536 s which equates to a shaft speed of about 23 rpm below which I'm not too worried about how fast it's going. At the other end of the scale I can measure rates up to 999 rpm with sufficient accuracy which should also be fine. That side of it I've tested and everything looks very good. The output from the calculations is sent to a remote receiver via a simple 433 MHz link as eight characters which define where the transmission has come from as well as the speed and direction of the shaft.

Data from other devices is also sent to the same remote receiver, so when the shaft is stationary, I don't want to clog up the airwaves with lots of repeated zero data, but once it's moving I do want regular updates.

So I thought I'd try using the interrupt facility (which is new to me in PicAxe) in order to exit a ten second delay between repeated transmissions of the stationary message:
Code:
Main:
;
SETINT %00010000, %00010000
;
PULSIN Count_in , 1 , puls_ln ; Measure the positive part of the square
					; wave which represents 1/4 of a revolution.
IF puls_ln = 0 THEN 
	SEROUT TxData_out, N2400, ("PS  0rpm") 
	PAUSE 10000 		; Only output the stopped data every ten secs.
					; An interrupt will break out of this pause.
	GOTO main   		; A zero value implies the rate is too slow
					; to measure, i.e. less than about 23 rpm
					; or stationary.
ENDIF
;
SETINT OFF  			; 
;	Rest of the program here
;
;
interrupt:
					; Come here when the shaft is rotating.
PAUSE 650   			; Wait until the PULSIN measurement is complete.
;
SETINT %00010000, %00010000
;
RETURN
It does sort of work but has a major problem because when the pulses slow down and stop, the 4013 output can be left in either a high or low state. Clearly, if it's in the high state, it will keep triggering the interrupt, so what I'd ideally like is an edge triggered interrupt which looks only for a +ve going edge. This doesn't appear to be possible on an 8M2 though.

I'd be grateful for any thoughts please on a work-around for this to escape from the ten second (or longer) delay?

Thanks.
 

inglewoodpete

Senior Member
You have a couple of options. One, of course, is to reset the CD4013 with the PICAXE if you have a spare pin (unfortunately the 08M2 doesn't have many!!).

You can have the interrupt reverse the condition by inverting the "input's" bit for the input pin. So, when you get an interrupt when the pin goes high, you change the SetInt command with the opposite condition. Continue toggling the "input" byte with each successive interrupt.

With situations like this, it will pay to keep copies of previous data so that the PICAXE never gets out of synch with the shaft. Also, keep a copy of the shaft speed since you don't want to repeatedly send unchanging data. Many countries have quite restrictive (duty cycle) regulations for the use of "unlicenced" radio frequencies like 433MHz. Your neighbours may not be able to lock and unlock their cars!! :)

As an aside, the "Pause 650" will not be of benefit to your code, since the PulsIn command is blocking. Good design should keep the proportion of time spent in an interrupt routine to a minimum. Time critical code goes in the interrupt routine; routine work is best done in the main code.
 
One, of course, is to reset the CD4013 with the PICAXE if you have a spare pin (unfortunately the 08M2 doesn't have many!!).
That's a useful idea though I'd prefer not to modify the hardware now.

You can have the interrupt reverse the condition by inverting the "input's" bit for the input pin. So, when you get an interrupt when the pin goes high, you change the SetInt command with the opposite condition. Continue toggling the "input" byte with each successive interrupt.
Even better idea, very elegant and easy to implement just in software. Very many thanks.

Am I right in believing that if an interrupt happens during a 10 second PAUSE, the RETURN command will restart the program from the following instruction? It won't finish off the PAUSE?

Also, keep a copy of the shaft speed since you don't want to repeatedly send unchanging data.
I had been thinking about how best to do that and your suggestion is another extremely helpful point. I'll need to send occasional updates as the receiver may not be switched on or might be viewing data from another transmitter, but keeping a copy (in the receiver) of the latest transmitted 8-byte data will be the way to go and reduce the need to repeatedly transmit null or unchanging data. Many thanks again.
 

inglewoodpete

Senior Member
Am I right in believing that if an interrupt happens during a 10 second PAUSE, the RETURN command will restart the program from the following instruction? It won't finish off the PAUSE?
That's correct. An interrupt aborts a pause. If you still need to finish off a pause (give or take a bit), you can make a loop structure like the following:

Code:
'This will give a 10 second pause in 100mS chunks
For b10 = 1 to 100
   Pause 100
Next b10
 
Top