DT-Interrupts - Is there a clash between ExtInt and IntOnChange?


Closed Thread
Results 1 to 17 of 17
  1. #1
    Join Date
    May 2011
    Location
    Bangalore, India
    Posts
    33

    Default DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    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

  2. #2
    Join Date
    Apr 2014
    Location
    OK
    Posts
    557


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    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.

  3. #3
    Join Date
    Jan 2009
    Location
    Alabama,USA
    Posts
    219


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    I agree with Mike, please post your code, inquiring minds want to know...

  4. #4
    Join Date
    May 2011
    Location
    Bangalore, India
    Posts
    33


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    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

    Code:
    '-------------------------------------------------------------------------------
    ' 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,254,19,51,223,255,159,191,215,247,220,252,78,110,217,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

  5. #5
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    Looking at your code I do not see the IRQ routine "ClockCount".
    Dave Purola,
    N8NTA
    EN82fn

  6. #6
    Join Date
    May 2011
    Location
    Bangalore, India
    Posts
    33


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    Quote Originally Posted by Dave View Post
    Looking at your code I do not see the IRQ routine "ClockCount".
    The routine "ClockCount" is part of the included file "Elapsed_INT.bas".

  7. #7
    Join Date
    May 2013
    Location
    australia
    Posts
    2,379


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    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.
    Warning I'm not a teacher

  8. #8
    Join Date
    May 2011
    Location
    Bangalore, India
    Posts
    33


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    Quote Originally Posted by richard View Post

    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

  9. #9
    Join Date
    May 2013
    Location
    australia
    Posts
    2,379


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    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
    Last edited by richard; - 9th May 2020 at 06:59.
    Warning I'm not a teacher

  10. #10
    Join Date
    May 2011
    Location
    Bangalore, India
    Posts
    33


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    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

  11. #11
    Join Date
    May 2013
    Location
    australia
    Posts
    2,379


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    i doubt its really necessary , it still leaves the issue of transferring data between chips with lots of isr's running
    Warning I'm not a teacher

  12. #12
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,793


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    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
    Last edited by Ioannis; - 9th May 2020 at 11:24.

  13. #13
    Join Date
    Apr 2014
    Location
    OK
    Posts
    557


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    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?

  14. #14
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,793


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    With 100Hz, I think there is a lot of time for this. Have done much worse things in ISR!

    Ioannis

  15. #15
    Join Date
    May 2011
    Location
    Bangalore, India
    Posts
    33


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    Quote Originally Posted by mpgmike View Post
    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

  16. #16
    Join Date
    May 2011
    Location
    Bangalore, India
    Posts
    33


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    Quote Originally Posted by Ioannis View Post
    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

  17. #17
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,793


    Did you find this post helpful? Yes | No

    Default Re: DT-Interrupts - Is there a clash between ExtInt and IntOnChange?

    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

Similar Threads

  1. External Interrupts Vs. RB/KBI Interrupts?
    By kevj in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 1st September 2008, 08:52
  2. help: TMR0 interrupts disabling PORTAchange interrupts???
    By xnihilo in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 19th August 2008, 16:10
  3. Need help with INTerrupts
    By Srigopal007 in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 3rd August 2007, 01:53
  4. Why use Interrupts
    By lerameur in forum General
    Replies: 4
    Last Post: - 13th May 2007, 23:12
  5. too many interrupts
    By trying in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 23rd February 2006, 14:38

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts