Interrupt on change for IR input - is it a good way to go


Closed Thread
Results 1 to 9 of 9
  1. #1
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    838

    Question Interrupt on change for IR input - is it a good way to go

    Hi Guys ,
    I have not tried using this feature as yet , but wondering if its going to be a practical way to trigger a input routine to go and get an IR input


    Currently , the IR routine is part of the main loop and it has to wait for other routines to finish before its able to have a go , which can be an issue unless i change things and call it more now.

    if i make it an " on Interrupt" routine instead it maybe a better way to go , please advise

    only issue i see is the like most IR receivers , they tend to pickup rubbish and send random pulses , thus false triggering an interrupt check ,

    but may be better than just looping the routine more

    is the way to go for IR service routines , that are in standby for most of the time ?

    Cheers

    Sheldon

  2. #2
    Join Date
    Nov 2009
    Location
    London
    Posts
    251


    Did you find this post helpful? Yes | No

    Default Re: Interrupt on change for IR input - is it a good way to go

    Sheldon, for IR pulses, interrupt is definitely the way forward. If you are making your own communication routine then it is better to have a longer start pulse and can also use a define pulsin statement on top (check manual) to limit the wait time for the start pulse. It will every now and then get false triggers, I don't think there is any way you can avoid that as I tried a lot before but could not do it unless I missed something. You can use DT_INT for this.

  3. #3
    Join Date
    Oct 2004
    Posts
    448


    Did you find this post helpful? Yes | No

    Default Re: Interrupt on change for IR input - is it a good way to go

    Quote Originally Posted by longpole001 View Post

    only issue i see is the like most IR receivers , they tend to pickup rubbish and send random pulses , thus false triggering an interrupt check ,
    Do you have a resistor in series (100 ohms should be okay) with the module's Vss and the +5 volts, and a capacitor (10 uF) across the module's Vss and Ground?

    These two would help tremendously reduce the noise you refer to.

  4. #4
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    838


    Did you find this post helpful? Yes | No

    Default Re: Interrupt on change for IR input - is it a good way to go

    The IR sig is " clean " for the most part , the random signal it seems to pickup are mainly from lights around ,

    i have not done that much with interrupts say more than just check a timer has expired flag , i am also short of program space , but ill have to work around that issue . will remove other code routines to see if the COI detected ok

    The get IR routine has pulsin_max set to the max time of valid pulse length before timing out, which helps but you still need to go call the routine very regular , and thats killing me

    I do have 2 other items on a makeshift SPI bus that will eventually i like to use a pin for interrupts , instead of polling a register flag , but will have to wait till i have a bigger pic chip to arrive( 16F1825) , with the new programmer

    i am assuming that i can services other interrupt routines in the same way as what i am looking at with the IR routine on IOC ?

    managing multi interupts from 2 or more pins would be something new also to me for pics , so code ref examples on the best way to do this would be Very helpful.

    Il go get DT_int14 routines and study them a bit more today

    The learn curve continues


    Cheers

    sheldon

  5. #5
    Join Date
    Dec 2005
    Posts
    1,073


    Did you find this post helpful? Yes | No

    Default Re: Interrupt on change for IR input - is it a good way to go

    IR tends to be very clean, especially so if you use a resistor/cap as Anand suggested.

    It's been several years since I did a lot of hands on testing but sunlight and some old-line fluorescent tubes created problems. I've never tested with CFLs but suspect they could cause a lot of problems if their switching power supply uses a frequency that's a near multiple of the IR carrier frequency.

  6. #6
    Join Date
    Oct 2007
    Location
    The Netherlands
    Posts
    45


    Did you find this post helpful? Yes | No

    Default Re: Interrupt on change for IR input - is it a good way to go

    In my experience the shielded ones (some sort of aluminum shield with a small window) are much less noisy
    The ones I use mostly come from old VHS decks or TV's

  7. #7
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    838


    Did you find this post helpful? Yes | No

    Default Re: Interrupt on change for IR input - is it a good way to go

    I tried using IOC and DT interupt14 ,bas , but no success yet on what i was hopping , but it does compile with no errors !!!


    1.setup DT_interupts as shown here at the start of code

    Code:
    INCLUDE "DT_INTS-14.bas"
        
    INCLUDE "ReEnterPBP.bas"
    ASM
    INT_LIST macro								; IntSource, Label, Type, ResetFlag?
    
    		INT_Handler GPC_INT,_GetIRcode, PBP, no
    	endm
    	INT_CREATE								; Creates the Interrupt Processor
    ENDASM
    2. setup gpo.0 as digital output

    3. call sendcode routine , which then sends out data on gpio.0

    4. i set up gpio.0 = 1 for an input and set IOC.0 =1 to turn on at end of sendcode routine
    5. i then use int enable after the send routine back in main loop using '@ INT_ENABLE GPC_INT'

    6. i ensure getircode routine has "@ INT_RETURN " at the end of the routine " see code"

    7 i remove gosub getircode call from main prog loop , as it should now only be called when an interupt or data is present on the port gpio.0

    8 main loop has nothing else in it for this test

    to test i send an ir code and see if it is written to eeprom - eg did it get the code when data was on the input and was the routine called from the interrupt


    but this is not working and the getircode sub does not get called

    What am i missing to make it work , or will it not work this way as i thought it might


    Code:
    GetIRcode:
         
         TRISIO.0  = 1                 ' setup input=1,output=0 GPIO.0 = 1 to input 
         IOC.0=1		               ' Set Change in Interrupt on GP0.0 for when it changes from high , when its a input in GetIR routine
         PULSIN IR,1,Leader            ' get leader high pulse time value in on GPIO.0   ( pulsin_max set to 4000 = 20ms )
        IF Leader < 800 tHEN return    ' look for 4500us high pulse  below 4000us  then its 2nd key area pulse  or data/ address bits  (800^ 5us= 4000us)
        IF Leader > 960 tHEN return    ' above 4800us  then it no sig  (460)
       
      FOR X = 0 TO 31                  ' grab 32 incoming pulses
           PULSIN GPIO.0,1,leader      ' now measuring high-going pulse widths
           BtnVal(x) = leader/2        ' leader divide by 2 so Btnval(x) is byte (<255) not word value  
      NEXT X
          
          z = 0                            ' Z points to start range of byte 
          S = 7                            ' S points to end range of byte 
          X = 0                            ' start X at 0 to line up with BtnVal array
      for Y = 1 to 4                       ' Get in Array and decode 4 bytes from 32 bit pulses 
            T = 7                          ' Set T to 7 so that it puts BtnVal(0) in to D7 location  
            FOR X = Z TO S                 ' sort 8 pulses of byte
        
              IF BtnVal[X]  > 120 THEN     ' > 120 x (5uS *2) = > 1.2mS pulse period = 1 (150)
                 DByteTmp = DByte[Y]       ' get into temp var
                 DByteTmp.0[T]=1           ' Set value to 0 or 1 , T reverses bit order of BtnVal(x) so byte has correct bin value to write byte 
                ELSE
                 DByteTmp = DByte[Y]      ' get into temp var
                 DByteTmp.0[T]=0          ' Set value to 0 or 1 , T reverses bit order of BtnVal(x) so byte has correct bin value to write byte 
               ENDIF
      
              DByte[Y] = DByteTmp          ' get it back into DByte(y)
              T = T - 1                    ' T points to next MSB on loop
            NEXT X
        
          Z = x                            ' Z = X (0,8,16,24) points to start of next byte
          S = 7 + X                        ' S  (7,15,23,31) points to End of next DByte BtnVal offset to X
      next Y                               ' loop for 4 bytes
     
      
       ' only save code if it differnat to stored IR code 
         x=1        ' ensure 1 
        for x = 1 to 4 
          if  DByte[x] <> STDByte[x] then 
              write x,DByte[x]     
          endif    
        next x  
       
    @ INT_RETURN    
       return
    regards

    Sheldon

  8. #8
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    838


    Did you find this post helpful? Yes | No

    Thumbs up Re: Interrupt on change for IR input - is it a good way to go

    finally had some time to debug this , and found the error , lov simulators , the problem was , if you have a look at the code / descriptions is that this routine WAS called from the main program loop .

    When it was changed for this test to be called by the event of change on interupt , the section directly after the pulsin command where the if signal length <800 then return etc , well that needed to be changed to the @ int _return

    I still need this routine to be both called when its - standing by - looking for input as a change on interrupt ,

    but i also need the routine be called from other parts of the program for input traps to be tested and triggered and so i have left in the normal " returns " in

    I think that "@ int_returns" are not acted upon , unless the " @ INT_ENABLE GPC_INT" is enabled , as such a normal call to this subroutine would skip the "@ int_returns" statement as i see it.

    Changed code is
    Code:
     GetIRcode:
         
         TRISIO.0  = 1                 ' setup input=1,output=0 GPIO.0 = 1 to input 
    
         PULSIN IR,1,Leader            ' get leader high pulse time value in on GPIO.0   ( pulsin_max set to 4000 = 20ms )
        IF Leader < 800 tHEN           ' look for 4500us high pulse  below 4000us  then its 2nd key area pulse  or data/ address bits  (800^ 5us= 4000us)
    @ INT_RETURN  
    return
    endif
    
        IF Leader > 960 tHEN    ' above 4800us  then it no sig 
    @ INT_RETURN
    return
    endif
    Warning - the includes of DT interupt14.bas is very heavy load on small pics where ram is very limited and having all those varables and then your program code varaibles makes it hard to use in anything but a small program , this project will be loaded into the 16F1825 , when i get them , so should not be such a big issue on ram as it is on the 12f683


    Comparing Overheads for the same code running on 16F1825 to the 12F683 , i found that the 16F1825 had an additional 320 words used to that in the 12F683, must be all those extra features in the chip when doing compile , even if you are not using them

    Now onto DT interupt14.bas interrupt testing routines using timer 0-2

    Cheers

    Sheldon

  9. #9
    Join Date
    Feb 2012
    Location
    PERTH AUSTRALIA
    Posts
    838


    Did you find this post helpful? Yes | No

    Question Re: Interrupt on change for IR input - is it a good way to go

    Question - should i disable interrupts when the pin is used as an output , and re-enable when its an input only or dont it not mater , as interrupts are only input detected ?????

Members who have read this thread : 0

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