PDA

View Full Version : DT-Interrupts - Is there a clash between ExtInt and IntOnChange?



Balachandar
- 29th April 2020, 17:55
Recently I completed a home project for controlling a light and a fan with an IR remote.
Some relevant details are given below.
PIC used: 16F689 - 20-pin device OSC: 8MHz
PicBasicPro Version 2.60C MicroCodeStudio Version 4.0.0.0

Thanks to Darrel Taylor, I am using three DT interrupts.
1. ExtInt is used for receiving IR commands
2. PortB IntOnChange is used for detecting the mains zero crossings (100 ZC per second). A random phase triac driver is used to fire the triac that controls the fan.
3. Timer1 Interrupt is for the Elapsed Timer. Fan speed is changed after the selected duration. The duration can be from 30 minutes to 15 hours and 30minutes in steps of 30 minutes (31 Steps).

Ext Int works perfectly. The commands from the IR remote used for switching on/off the light/fan and to change the fan speed or the fan duration are working perfectly.
PortB IntOnChange works as expected. The fan can be operated at 10 different speeds and this also works nicely.
The problem I am facing is that the the Elapsed Timer does not work properly. There seems to be a clash between the Timer1 interrupt used by the Elapsed Timer and PortB IntOnChange.
They both occur once in 10mS (100 Interrupts in a second). If I set Elapsed Timer duration for 2 hours so that the fan gets switched off after 2 hours, the switching off takes place after more than 3 hours.
If I disable PortB IntOnChange, the Elapsed Timer works perfectly.

What can I do to solve this problem?
Is there a version of Elapsed Timer that uses Timer0 instead of Timer1?
I would highly appreciate any solution / suggestion / guidance to sort out the issue.

- Bala

mpgmike
- 29th April 2020, 21:26
The best anyone could is merely guess without being able to review your code. Please post what you did, adding generous comments, so others can review & critique.

MOUNTAIN747
- 1st May 2020, 18:05
I agree with Mike, please post your code, inquiring minds want to know...

Balachandar
- 8th May 2020, 18:03
Here's my code. Sorry about the delay.

I just realised, the title for this thread should have been "DT-Interrupts - Is there a clash between Timer1 Int and IntOnChange?"
Both Timer1 Int and IntOnChange occur 100 times a second.

Anyway, please go through the code and tell me where the issue could be. The comments hopefully make the code clear.

- Bala



'-------------------------------------------------------------------------------
' 16F689 Fan Light Remote Control.pbp Date: 02-Apr-20 No. of words: 1817
'
' This code is for controlling the fan speed and light with an IR remote.
' - A 7-Segment display shows the current fan speed.
' - The remote used is one that is used for controlling a TV (RR RC-405).
' - There are 2 triacs (BT136); one controls the light and the other the fan.
' - Three DT's Instant Interrupts are used.
' ExtInt for IR sensor
' Port Change Int for detecting zero crossing
' Timer1 Int for Elapsed Timer
' - There are 2 PB switches. One for On/Off and Speed Change of fan and the other
' for On/Off control of light.
'
'Working as expected? Everything is working fine except that the Elapsed
'Timer's accuracy is far from accurate.
;---------------------------------------------------------------------------

'************************************************* *******
' Pinout of 16F689:
' Vdd 1 ---u--- 20 Gnd
' BluLED A.5 2 | | 19 A.0 AmbLED
' PBSwLightIn A.4 3 | | 18 A.1 GrnLED
' PBSwFanIn A.3 4 | | 17 A.2 IRSensorIn
' Seg_dp C.5 5 | | 16 C.0 Seg_b
' Seg_c C.4 6 | | 15 C.1 Seg_a
' Seg_d C.3 7 | | 14 C.2 Seg_f
' Seg_e C.6 8 | | 13 B.4 ZeroCrossIn
' Seg_g C.7 9 | | 12 B.5 LightTriac
' RedLED B.7 10 ------- 11 B.6 FanTriac
'************************************************* *******
' 1 inch 7 segment display (Top view)
' g f Com a b
' | | | | |
' ----------------
' | ______ |
' | | a | |
' | f| |b |
' | |______| |
' | | g | |
' | e| |c |
' | |______| 0 |
' | d dp|
' ----------------
' | | | | |
' e d Com c dp


'PIC used: 16F689
ASM
ifndef __16F689
error "16F689 not selected"
endif
ENDASM

'asm
' __CONFIG _FOSC_INTOSCIO & _MCLRE_OFF & _WDTE_OFF & _PWRTE_ON & _LVP_OFF & _CPD_OFF & _BODEN_ON
'endasm

OSCCON = %01110000 'Oscillator speed: 8MHz
define OSC 8

'Port direction
TRISA = %00011100 'PortA: 2,3 & 4: Inputs; rest are outputs.
TRISB = %00010000 'PortB: 4: Input; rest are outputs.
TRISC = %00000000 'PortC: All are outputs.

ANSEL = 0 'ADC is disabled.
ANSELH = 0 'ADC is disabled.

CM1CON0.7 = 0 'Disable Comparator1
CM2CON0.7 = 0 'Disable Comparator2

IOCB.4 = 1 'Interrupt-on-change enabled for PortB.4

OPTION_REG = %00000001 ' (TMR0 Prescaler to 1:4), External Interrupt on falling edge of RA2, Pull-ups enabled
'WPUA.2 = 1 ' Weak pull-up for PortA.2 Not enabled since the output of the IR receiver is pulled high internally.)
'(For PortA.3, a physical resistor is to be used as there is no weak pull-up option for PortA.3.)
WPUA.4 = 1 ' Weak pull-up for PortA.4 is enabled for PBSwLightIn.
WPUA.5 = 1 ' Weak pull-up for PortA.5 is enabled for PBSwFanIn.
'WPUB.4 = 1 ' Weak pull-up for PortB.4 is enabled for ZCin

'Constants
WaitPeriod1 con 150 'Wait period 1 (Around 1.5 Seconds)
WaitPeriod2 con 250 'Wait period 2 (Around 2.5 Seconds)

'List of variables
Cnt Var Byte 'For use in FOR loops
LFTByte var byte 'Temporary byte to store status of Light, Fan & Timer in EEPROM
LFTByte = 0 'Default value is 0.
FanSpeed var byte 'Fan speed shown on the display (1 to F; 10 settings)
FanSpeed = 5 'Default value of FanSpeed
LightStatus var bit '1 = Light is on; 0 = Light is off
LightStatus = 0 'Default value is 0.
FanStatus var bit '1 = Fan is on; 0 = Fan is off
FanStatus = 0 'Default value is 0.
TimerStatus var bit '1 = Timer is on; 0 = Timer is off
TimerStatus = 0 'Default value of TimerStatus
FanDurn var byte 'Current 'On' Duration of fan - from 1 to 31 (0.5 to 15.5 hours)
FanDurn = 4 'Default value of FanTimer (corresponds to 2 hours)
CurDurnInMins var word 'Word variable - Current Fan Duration in minutes (FanDurn multiplied by 30)
SpeedDisplayOn var bit 'This bit is 1 if the display shows fan speed; it is 0 if the timer duration is on the display.
SpeedDisplayOn = 1 'Default value of SpeedDisplayOn
ButtonDown var word 'Word variable - Used for tracking the duration of a button held down
BtnDnPeriod var byte 'Button down wait period
WaitPeriod var word 'Word variable - Used in keeping track of the length of the wait period
SpeedByteValue var byte 'Used in showing the fan speed on the 7 segment display
DurnByteValue var byte 'Used in showing fan timer value on the 7 segment display
IncomingPulse var word 'Word variable - Variable used in the section for IR signal detection
IRCommand var byte 'variable for IR code received
ElapsedMins var word 'Word variable - Elapsed minutes - used in timer operation
TriacDelay var word 'Word variable - Duration in uS after which the triac is fired after zero crossing - used in fan speed control
TriacDelay = 5000

'List of aliases
AmbLED var PORTA.0 'Output for Amber LED (Timer Function)
GrnLED var PORTA.1 'Output for Green LED (Fan)
IRSensorIn var PORTA.2 'Input for IR commands
PBSwFanIn var PORTA.3 'PB Switch input for Fan
PBSwLightIn var PORTA.4 'PB Switch input for Light
BluLED var PORTA.5 'Output for Blue LED (Timer Duration Display)
ZCIn VAR PORTB.4 'Input for Zero Crossing
LightTriac var PORTB.5 'Output for Light Triac
FanTriac VAR PORTB.6 'Output for Fan Triac
RedLED var PORTB.7 'Output for Red LED (Light)

;---------------------------------------------------------------------------
;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
;wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------
'************************************************* ******************************

INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"
INCLUDE "Elapsed_INT.bas" ; Elapsed Timer Routines

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ClockCount, PBP, yes
INT_Handler RABC_INT, _RunTheFanAtCurrentSpeed, PBP, yes
INT_Handler INT_INT, _GetTheIRCommand, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM


@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
@ INT_ENABLE RABC_INT ; Enable A,B Port Change Interrupts
@ INT_ENABLE INT_INT ; Enable external (INT) interrupts
'************************************************* ******************************
'EEPROM Byte0 Bit0 = Light status Bit1 = Fan status Bit2 = Timer status
' Byte1 Fan speed
' Byte2 Fan duration
' Byte3 High byte of Elapsed Minutes
' Byte4 Low byte of Elapsed Minutes

data @0,0,5,4,0,0 'Store at locations 0, 1, 2, 3 & 4 of EEPROM.
goto ReadEEPROM 'Default FanSpeed is 5. Default FanDurn is 4.

'---[RBC - interrupt handler]---------------------------------------------------
'BlinkGrnLED: 'Blue LED
'grnled = 1 : pause 50 : grnled = 0 : pause 50
'INTCON.0 = 0 ' RBIF is cleared.
'@ INT_RETURN
'************************************************* ******************************
'-------------------------------------------------------------------------------

ReadEEPROM:
'Read EEPROM locations 0, 1 & 2 (LFT Status, Fan Speed & Fan Durn) and load the
'values into respective variables.
read 0, lftbyte
read 1, fanspeed : gosub showfanspeed
read 2, fandurn

'Read EEPROM location 0. Bits 0, 1 & 2 correspond to LightStatus, FanStatus & TimerStatus.
if lftbyte > 0 then 'If all 3 bits are 0, start with DiagRoutine.
lightstatus = lftbyte.0 'If any of the 3 status bits is 1, restore the values of
redled = lightstatus 'status variables and resume operation, including
LightTriac = lightstatus 'Timer operation.

fanstatus = lftbyte.1
grnled = fanstatus

timerstatus = lftbyte.2
ambled = timerstatus

if lftbyte >= 6 then 'If the fan and timer are on...
GOSUB InitialiseTheTimer ' Initialise the Timer
read 3, ElapsedMins.highbyte 'Load the current value of elapsed time from EEPROM
read 4, ElapsedMins.lowbyte 'to the high and low bytes of word variable ElapsedMins.
endif
goto start
endif
'-------------------------------------------------------------------------------

'Start-up Diagnostic Routine: Blink the red, green and amber LED 2 times each.
DiagRoutine:
For cnt = 1 to 2
redled = 1 : pause 50 : redled = 0 : pause 50 'Blink Red LED.
grnled = 1 : pause 50 : grnled = 0 : pause 50 'Blink Grenn LED.
ambled = 1 : pause 50 : ambled = 0 : pause 50 'Blink Amber LED.
Next cnt

PortA = 0
PortB = 0

gosub stoptimer
GOSUB ResetTime ' Reset Time to 0d-00:00:00.00
MinutesChanged = 0
ircommand = 0

goto start

'Subroutines
LookupTableFanSpeed:
lookup fanspeed,[0,17,203,155,149,158,222,19,223,159,215],speedbytevalue 'Byte values for digits 1 to 9 and A (11)
return

LookupTableFanDurn:
lookup fandurn,[95,127,17,49,203,235,155,187,149,181,158,190,222,2 54,19,51,223,255,159,191,215,247,220,252,78,110,21 7,249,206,238,198,230],durnbytevalue 'Byte values for 0 to 15.5 in half hour steps (32)
return

LookupTableTriacDelay:
lookup2 fanspeed,[0,6500,6000,5600,5300,5100,4600,3900,3000,1900,700],TriacDelay 'Delay Values in uS for Fan Speed Updated on 02-Apr-20
return

BlinkRedLED200mS:
redled = ~ lightstatus
pause 200
redled = lightstatus
RETURN

BlinkGrnLED200mS:
grnled = ~ fanstatus
pause 200
grnled = fanstatus
RETURN

BlinkAmbLED200mS:
ambled = ~ timerstatus
pause 200
ambled = timerstatus
RETURN

BlinkRedLED50mS:
redled = ~ lightstatus
pause 50
redled = lightstatus
RETURN

BlinkGrnLED50mS:
grnled = ~ fanstatus
pause 50
grnled = fanstatus
RETURN

BlinkAmbLED50mS:
ambled = ~ timerstatus
pause 50
ambled = timerstatus
RETURN

StayThereFanButton:
if pbswfanin = 0 then staytherefanbutton
return

StayThereLightButton:
if pbswlightin = 0 then staytherelightbutton
return

ShowFanSpeed:
BluLED = 0
gosub LookupTableFanSpeed
GOSUB lookuptabletriacdelay
PortC = SpeedByteValue
return

ShowFanDurn:
BluLED = 1
gosub LookupTableFandurn
PortC = durnByteValue
return

InitialiseTheTimer:
ElapsedMins = 0
gosub converttomins
gosub stoptimer
GOSUB ResetTime ' Reset Time to 0d-00:00:00.00
MinutesChanged = 0
GOSUB StartTimer ' Start the Elapsed Timer
return

ConvertToMins:
curdurninmins = fandurn * 30 'Duration in minutes = FanDuran multiplied by 30
return

UpdateLightVariables:
redled = lightstatus
LightTriac = lightstatus
lftbyte.0 = lightstatus
gosub writelfttoeeprom
return

UpdateFanVariables:
grnled = fanstatus
lftbyte.1 = fanstatus
gosub writelfttoeeprom
if fanstatus + timerstatus = 2 then gosub InitialiseTheTimer
return

UpdateTimerStatus:
ambled = timerstatus
lftbyte.2 = timerstatus
gosub writelfttoeeprom
if fanstatus + timerstatus = 2 then gosub InitialiseTheTimer
return

WriteLFTToEEPROM:
write 0,lftbyte : pause 10
return
'-------------------------------------------------------------------------------


START:
if ircommand <> 0 then goto interpretircommand

if fanstatus + timerstatus = 2 then 'If both Fan & Timer are on...
if MinutesChanged = 1 then
MinutesChanged = 0
ElapsedMins = ElapsedMins + 1 ' Keep track of elapsed minutes.
gosub blinkambled200ms
write 3,ElapsedMins.highbyte : pause 10
write 4,ElapsedMins.lowbyte : pause 10
if elapsedmins >= curdurninmins then
fanstatus = 0
gosub updatefanvariables
gosub stoptimer
GOSUB ResetTime ' Reset Time to 0d-00:00:00.00
write 3,0 : pause 10
write 4,0 : pause 10
endif
endif
endif

if pbswlightin = 0 then
gosub blinkredled50ms
buttondown = 0
DurnLoop1:
if pbswlightin = 1 then
lightstatus = ~ lightstatus 'Toggle the Light status.
gosub UpdateLightVariables
goto start
endif
pause 10
if pbswlightin = 0 then buttondown = buttondown + 1
if buttondown > waitperiod1 then setfandurn
goto DurnLoop1
endif

if pbswfanin = 0 then
gosub blinkgrnled50ms
buttondown = 0
SpeedLoop1:
if pbswfanin = 1 then
fanstatus = ~ fanstatus 'Toggle the Fan status.
gosub updatefanvariables
goto start
endif
pause 10
if pbswfanin = 0 then buttondown = buttondown + 1
if buttondown > waitperiod1 then setfanspeed 'If button is held down for 1 second, goto SetFanSpeed.
goto SpeedLoop1
endif

goto start

SetFanSpeed:
gosub blinkgrnled200ms
speeddisplayon = 1
WaitPeriod = 0

TimerStatusLoop:
pause 10
if pbswfanin = 0 then
buttondown = buttondown + 1
if buttondown > waitperiod2 then timeronoroff
goto TimerStatusLoop
endif

SpeedLoop2:
if pbswfanin = 0 then
pause 200
fanspeed = fanspeed + 1
if fanspeed > 10 then fanspeed = 1
gosub showfanspeed
WaitPeriod = 0 'Reset the wait period.
endif
pause 10
WaitPeriod = WaitPeriod + 1
if WaitPeriod > waitperiod2 then 'If 3 seconds have elapsed, blink the red led and goto START
write 1,fanspeed : pause 10
gosub blinkgrnled200ms
goto start
endif
goto Speedloop2

TimerOnOrOff: 'Turn the Timer On or Off
gosub blinkgrnled200ms
timerstatus = ~ timerstatus 'Toggle the Timer status.
gosub UpdateTimerStatus
gosub staytherefanbutton
goto start

SetFanDurn:
gosub blinkgrnled200ms
speeddisplayon = 0
WaitPeriod = 0
gosub showfandurn 'Show current setting of Fan duration.
gosub staytherelightbutton 'Wait till the Light button is released.
DurnLoop3:
if pbswlightin = 0 then
pause 200
fandurn = fandurn + 1
if fandurn > 31 then fandurn = 1
gosub showfandurn
WaitPeriod = 0 'Reset the wait period.
endif
pause 10
WaitPeriod = WaitPeriod + 1
if WaitPeriod > waitperiod2 then 'If 3 seconds have elapsed, blink the green led,
gosub converttomins 'revert to Fan Speed display and goto START
gosub blinkgrnled200ms
write 2, fandurn : pause 10
goto FanSpeedDisplayMode
endif
goto durnloop3
goto start

FanDurnDisplayMode:
write 2, fandurn : pause 10

FanDurnDisplayMode2:
ircommand = 0
gosub converttomins
waitperiod = 0
speeddisplayon = 0
pause 50
gosub showfandurn
SpeedLoop3:
pause 10
waitperiod = waitperiod + 1
if ircommand <> 0 then goto interpretircommand
if waitperiod > waitperiod2 then
gosub blinkgrnled50ms
goto FanSpeedDisplayMode
endif
goto SpeedLoop3

FanSpeedDisplayMode:
ircommand = 0
speeddisplayon = 1
pause 50
gosub showfanspeed
goto start

InterpretIRCommand:

pause 50

if ircommand = 235 then 'Red button
lightstatus = ~ lightstatus
gosub UpdateLightVariables
ircommand = 0
goto start
endif

if ircommand = 217 then 'Green button
fanstatus = ~ fanstatus
gosub UpdatefanVariables
ircommand = 0
goto start
endif

if ircommand = 203 then 'Sleep Button - Toggle the Timer status and amber LED.
timerstatus = ~ timerstatus
gosub UpdateTimerStatus
ircommand = 0
goto start
endif

if ircommand = 255 then fanspeeddisplaymode 'Mute Button - Change to Fan Speed Display mode
if ircommand = 211 then FanDurnDisplayMode2 'TV/AV Button - Change to Fan Timer Display mode2

if ircommand = 195 then 'Recall button - Switch off both light and fan without changing the fan speed.
lightstatus = 0
gosub UpdateLightVariables
fanstatus = 0
gosub UpdatefanVariables
goto start
endif

if ircommand = 251 then 'P-Up Button to increase
if speeddisplayon = 1 then
fanspeed = fanspeed + 1
if fanspeed > 10 then fanspeed = 1
else
fandurn = fandurn + 1
if fandurn > 31 then fandurn = 1
goto FanDurnDisplayMode
endif
endif

if ircommand = 219 then 'P-Down Button to decrease
if speeddisplayon = 1 then
fanspeed = fanspeed - 1
if fanspeed < 1 then fanspeed = 10
else
fandurn = fandurn - 1
if fandurn < 1 then fandurn = 31
goto FanDurnDisplayMode
endif
endif

' Select the fan speed directly by pressing buttons 1 to 9 and 'F.T -' on the remote for 1 to 10 speed.
if ircommand = 253 then fanspeed = 1
if ircommand = 221 then fanspeed = 2
if ircommand = 237 then fanspeed = 3
if ircommand = 205 then fanspeed = 4
if ircommand = 245 then fanspeed = 5
if ircommand = 213 then fanspeed = 6
if ircommand = 229 then fanspeed = 7
if ircommand = 197 then fanspeed = 8
if ircommand = 249 then fanspeed = 9
if ircommand = 215 then fanspeed = 10 'Display shows 'A'
write 1,fanspeed : pause 10
gosub showfanspeed
ircommand = 0
goto start

END

'---[INT - interrupt handler]---------------------------------------------------
GetTheIRCommand:
' Remote used: RR RC-405 Used for controlling TV
' At 8MHz Osc, PULSIN pulse width is returned in 5uS increments.
pulsin irsensorin,1,IncomingPulse 'Record the width of the Header2 pulse (high).
if IncomingPulse < 640 THEN abort 'Header2 pulse is high and its width is 3.3mS
FOR cnt = 1 TO 24 'Skip the first 16 high pulses and measure
pulsin irsensorin,1,IncomingPulse 'the width of the next 8 high pulses. If width
if cnt < 17 THEN donothing 'is greater than 1.6mS, the bit is 1; or else
ircommand = ircommand << 1 'don't change the bit (it is zero). Since the
if incomingpulse > 320 then ircommand.0 = 1 'most significant bit arrives first, keep left
DoNothing: 'shifting the bits from the 1st bit to the 7th.
NEXT cnt 'The 8th bit that will arrive last will be
Abort: 'loaded to IRCommand.0.
@ INT_RETURN

'---[INT - interrupt handler]---------------------------------------------------
RunTheFanAtCurrentSpeed:
if fanstatus = 0 then donotfiretriac
pauseus TriacDelay
pulsout FanTriac, 20 'A 100mS pulse is needed to fire the triac. (At 8MHz Clock, PULSOUT sends pulses of 5uS width each; 20 * 5uS = 100uS)
DoNotFireTriac:
@ INT_RETURN

end

Dave
- 8th May 2020, 19:18
Looking at your code I do not see the IRQ routine "ClockCount".

Balachandar
- 9th May 2020, 02:20
Looking at your code I do not see the IRQ routine "ClockCount".

The routine "ClockCount" is part of the included file "Elapsed_INT.bas".

richard
- 9th May 2020, 02:23
Is there a clash between Timer1 Int and IntOnChange?

no , thats just not the way to manage time critical interrupt routines.

interrupts on a pic16 cannot be interrupted therefore for the entire duration of
RunTheFanAtCurrentSpeed: and the GetTheIRCommand: routines the timer is effectively stalled
it simply cannot keep time.

Balachandar
- 9th May 2020, 05:05
interrupts on a pic16 cannot be interrupted therefore for the entire duration of
RunTheFanAtCurrentSpeed: and the GetTheIRCommand: routines the timer is effectively stalled
it simply cannot keep time.

Thanks Richard, for clearly stating where the problem is.

When one interrupt is being serviced, if another interrupt occurs, the second one either gets ignored (in PIC16 and lower) or is acted upon after a delay (in PIC18). That's what I understand from your post.

When I use my IR remote, if I have to press the button 2 or 3 times or there is a delay of a few milliseconds in executing that command, it is not an issue. But when the error margin is around 80% or higher in the operation of the Elapsed Timer, that is definitely a big problem.

I feel, using another PIC like 12F683 for the Elapsed Timer is one solution. If I use an 18F device, I will have the option to assign priority to interrupts but the Timer accuracy will still be an issue.

Are there other ways of solving the problem?

- Bala

richard
- 9th May 2020, 05:57
generally the best solution is to absolute minimum processing in the isr like set a flag to indicate to main code that a task must be performed

ie
your triac isr can hold processing up for over 6mS
you could instead use zero cross to start another timer for "speed delay" that timer can then cause an interrupt to fire triac
both of these isr's could be very simple and done as asm type for absolute minimum overhead.
the "ir" isr could similarly start a timer and reset for another edge trigger set state 1. with the timer set for a period greater than the ir start pulse time
if the timer int goes off then its a false trigger if the timer value is to low when the edge triggers then its a false trigger otherwise
for a good trigger set a state so the foreground processing can decode the ir stream.
this would be a state managed process
state 0 ir idle
state 1 ir active
state 2 ir start pulse detected ,manage in foreground
it can all be done in uS no bogging down with delays

Balachandar
- 9th May 2020, 06:12
Thank you Richard, for the suggestions. I will try and implement whatever I can.

I haven't written any code in Asm so far. I guess, when it comes to using multiple interrupts, learning to code in Asm may be a necessity.

What about using a second PIC for the Elapsed Timer with a common clock? Is it worth trying?

- Bala

richard
- 9th May 2020, 06:16
i doubt its really necessary , it still leaves the issue of transferring data between chips with lots of isr's running

Ioannis
- 9th May 2020, 10:22
The tricky part as I see it, under Richard's directions, is the processing of ir in the foreground. But states will help, as long as your routines are fast enough.

Better start with one task at the time and if it works ok, add another. All together might complex things and prevent debugging.

Ioannis

mpgmike
- 9th May 2020, 16:02
Here's a crazy thought; if you have 2 interrupts doing virtually the same thing, why not do both functions with only 1 interrupt? If your 100 Hz mains interrupt is clocking the same as your Timer 1, can you put your Timer 1 code in your ExtInt interrupt?

Ioannis
- 9th May 2020, 16:57
With 100Hz, I think there is a lot of time for this. Have done much worse things in ISR!

Ioannis

Balachandar
- 10th May 2020, 17:19
Here's a crazy thought; if you have 2 interrupts doing virtually the same thing, why not do both functions with only 1 interrupt? If your 100 Hz mains interrupt is clocking the same as your Timer 1, can you put your Timer 1 code in your ExtInt interrupt?

Your thought is not at all crazy; it's quite logical.

Both IOC Int for firing the triac and Timer1 Int for the Elapsed Timer occur 100 times per second. But I cannot use the Timer1 Int for the triac since the timing should be in sync with the zero crossings of the mains. It is possible to use the zero crossings for keeping time, but the timing accuracy may not be satisfactory.

But coming to think of it, if the timer accuracy is + or - 10% it is still good enough for me.
Thanks mpgmike. Based on your suggestion, I will try out using IOC Int for both firing the triac and the Elapsed Timer.

- Bala

Balachandar
- 10th May 2020, 17:28
With 100Hz, I think there is a lot of time for this. Have done much worse things in ISR!

Ioannis

You are right Ioannis. With 100Hz, there is a lot of time. It's all a question of what needs to be done by the ISR and how quickly it can be done.

- Bala

Ioannis
- 10th May 2020, 20:44
The ISR will be triggered by the Z.C. detector and set a flag. I do not see what else should be there.

The other stuff is not critical for being in the ISR

Ioannis