PDA

View Full Version : Interrupt on change for IR input - is it a good way to go



longpole001
- 25th July 2012, 12:18
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

Megahertz
- 25th July 2012, 13:19
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.

ardhuru
- 25th July 2012, 18:00
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.

longpole001
- 26th July 2012, 01:12
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

dhouston
- 26th July 2012, 11:26
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.

eggman
- 26th July 2012, 15:42
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

longpole001
- 27th July 2012, 08:12
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




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




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

longpole001
- 30th July 2012, 02:58
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



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

longpole001
- 30th July 2012, 10:05
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 ?????