Interrupts issues again

greencardigan

Senior Member
Hi, I'm having trouble with timer interrupts again with my 28x2.

The interrupt code is below. Is there anything wrong with it? I have it set for 100 interrupts per second to do some slow PWM while the rest of my code keeps going.

After running OK for approximately 5 minutes, the second_counter variable stops increasing, but my background code keeps running. What would be stopping my interrupts from occurring?

My code has background hardware serial in, hardware serial out, hardware i2c in and out.

I have already split up all the hserout so they send one byte at a time. Could the hi2c transfers be causing the interrupts to be delayed or missed?


Code:
interrupt:

	if started = 1 then
		inc hundredth_counter
	    
		if hundredth_counter > OUT then	'set output low for remainder of second when reached out/PID value
		low c.5
		endif
	    
		if hundredth_counter >= EVENTS_PER_SEC then
			hundredth_counter = 0 'maybe make hundredth_counter = hundredth_counter - EVENTS_PER_SEC
			OUT = PID	'load new PID value into OUT at start of new second
			if OUT <> 0 then	'set output high at start of new second
				high c.5
			endif
			inc second_counter
		endif    
	
	elseif button1 = 1 then
		do : loop until button1 = 0
		started = 1
	endif
	
	gosub timer_setup
    
return


''''''''''''''''''''''''''''''''''''''

timer_setup:
    timer = 0xffff ' generate interrupt at next overflow
    toflag = 0 ' clear timer overflow flag
    setintflags %10000000,%10000000 ' interrupt on timer overflow
return
Full code also attached if required.
 

Attachments

Last edited:

inglewoodpete

Senior Member
I have to admit that I haven't tried to understand your whole program. There is a lot of code.

An interrupt every 10mS is very frequent. It could take almost that amount of time to negotiate the interrupt routine. Given the limitations of the PICAXE, it may be better to use a different coding method, like sampling the clock value when required.
 

greencardigan

Senior Member
I don't really understand what is actually happening. I can't see why the interrupts would just stop after 5 minutes of running.

If I knew what was happening, I might be able to find why it's happening.
 

Svejk

Senior Member
I'm not sure if this would solve your issue:

The way I've solved the slow PWM required for SSR (100 Hz) was to delegate it to another IC and instruct it through serial comms. A 08M can be easily programmed to do that.

My application is undefloor heating: a 3 ph 12kW heater heats the water and a pump dumps it into the pipes. I'm controlling the return temperature. Also, when an external storage HWC, wood fired, reaches a set temperature, it switches from electric to that and the control is made with a valve driven by a step motor.

Your application looks similar (lack of comments makes harder to guess).
 
Last edited:

hippy

Ex-Staff (retired)
At high speed there can be timing issues so it may be worth moving your interrupt re-enabling to earlier in the interrupt routine.

As it is now, if there is a delayed interrupt ( held off while doing SERTXD or similar ) the interrupt could be activated close to when a further interrupt is about to occur and if the toFlag is set by the firmware to indicate that has happened, just before you clear the toFlag, then it may never occur again ( for a long while anyway ).
 

greencardigan

Senior Member
Will hi2c in or out delay interrupts too?

I can probably reduce the frequency to 50 interrupts per second to see if that helps.
 

westaust55

Moderator
At high speed there can be timing issues so it may be worth moving your interrupt re-enabling to earlier in the interrupt routine.
Will that achieve anything?
From manual 2
2) When the interrupt occurs, the interrupt is permanently disabled. Therefore to re-enable the interrupt (if desired) a SETINT command must be used within the interrupt: sub-procedure itself. The interrupt will not be enabled until the ‘return’ command is executed.
 

westaust55

Moderator
Will hi2c in or out delay interrupts too?

I can probably reduce the frequency to 50 interrupts per second to see if that helps.
i2c comms by the standard specification can be delayed/held by pulling the appropriate comms line low while the master (PICAXE in this case) is otherwise busy. As such there would seemingly be no specific need for i2c comms to delay/pause interrupts - the interrupts just need to put the i2c comms into hold state for a period.

PICAXE manual 2 Appendix 4 discusses some conflicts with timers and interrupts.
 

hippy

Ex-Staff (retired)
Will that achieve anything?
From manual 2 ...
You're right about the interrupts being disabled and interrupt not being re-entered until the whole sequence of re-enabling events is completed but there's a dual step process in the firmware setting the flags which will cause interrupts and the subsequent invocation of the interrupts.

Normally -

Timer overflows, sets toFlag
Firmware finishes a PICAXE command and checks interrupt flags
toFlag is seen as high so the interrupt is entered
The interrupt does its thing then ...
Resets the timer variable
Clears the toFlag
Re-enables interrupts pending the return
Then returns
Things then run until the timer overflows again.

The subtle thing is that the timer overflow checking and setting of toFlag will still continue during the interrupt routine itself. There's a possibility that the minor tick counter is just about to overflow, the user sets timer=$FFFF, the overflow happens, timer increments to $0000, toFlag is set, just before the toFlag is cleared by the user.

That's often a pretty small period in which things can 'go wrong', but Sod's Law suggests it can happen at some point and that may be the case here. Once toFlag has been cleared it requires the timer to have completely cycled back round past $FFFF again for toFlag to become set again and a subsequent interrupt to happen.

Moving the reset of the timer variable and clearing toFlag to the start of interrupt means there's less chance of the timer setting toFlag only to have it cleared.

The other alternative is to stop the timer ( SETTIMER OFF ) and restart it again as the interrupt routine is exited.
 

greencardigan

Senior Member
Thanks for the explanation.

I tried moving the toflag = 0 back up to the start of the interrupt routine but it did not help.

Changing to 50 interrupts per second seems to have worked though.

One other strange thing I noticed. As I add code to the main program, the interrupt issues comes and goes. Adding a bit ofvcode might make it occur. Adding a bit more code might fix it or make it less likely to occur etc.
 

MartinM57

Moderator
When running close to the edge on PICAXE with regard timing issues, often best to wind up the frequency - I see you have a SETFREQ m16 ... with an external 10Mhz resonator you could be doing a SETFREQ em40 and running the code 2.5x faster
 
Top