PDA

View Full Version : Multiple IR Receivers



jhorsburgh
- 6th September 2008, 06:12
Hello All,
I am trying to get a PIC to receive a binary code from either one of two 38Khz IR receivers, at the moment it works for one receiver but i don't know how to make it monitor two pins? I think Interrupts are the way to go, but don't know where to start. Does anyone know how i could do this?

<code>
INCLUDE "modedefs.bas"
CMCON = 7
trisio = %00001111
GPIO = 0
DEFINE OSCCAL_1K 1 ' Set OSCCAL for 1K device
Define OSC 4
@ DEVICE PIC12f629, XT_OSC
@ DEVICE PIC12f629, WDT_ON
@ DEVICE PIC12f629, PWRT_ON
@ DEVICE PIC12f629, MCLR_OFF
@ DEVICE PIC12f629, BOD_ON
@ DEVICE PIC12f629, CPD_OFF
CODELENGTH VAR BYTE 'BYTE VARIABLE OK - LESS THAN 8 PULSES MEASURED
UID VAR BYTE
PIN VAR BYTE
RXPIN1 Var GPIO.3

Pause 100 'SETTLE DOWN BOTH PIC & IR RECEIVER

STARTPULSE:
PulsIn GPIO.3,0,CODELENGTH 'MEASURE LOW PULSE (IR LED ON TIME)
IF (CODELENGTH > 200) and (CODELENGTH < 400) Then SENSOR1
goto STARTPULSE

SENSOR1:
RXPIN1 = GPIO.3
pin = 1
GOTO CODEPULSES

SENSOR2:
RXPIN1 = GPIO.2
pin = 2
GOTO CODEPULSES

CODEPULSES:
PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit0 = 1 '2MS PULSE IS 1
IF CODELENGTH < 150 Then LET UID.bit0 = 0 '1MS PULSE IS 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit1 = 1
IF CODELENGTH < 150 Then LET UID.bit1 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit2 = 1
IF CODELENGTH < 150 Then LET UID.bit2 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit3 = 1
IF CODELENGTH < 150 Then LET UID.bit3 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit4 = 1
IF CODELENGTH < 150 Then LET UID.bit4 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit5 = 1
IF CODELENGTH < 150 Then LET UID.bit5 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit6 = 1
IF CODELENGTH < 150 Then LET UID.bit6 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit7 = 1
IF CODELENGTH < 150 Then LET UID.bit7 = 0

IF UID = 247 Then LEDON
codelength = 0
UID = 0
GoTo STARTPULSE

LEDON:
High GPIO.0 'LED ON
serout 1, N2400,[#PIN," ",#UID,10,13]
Pause 500
Low GPIO.0
codelength = 0
UID = 0
GoTo STARTPULSE

End
</code>

Thank in advance,
Jeremy

Archangel
- 6th September 2008, 07:27
It may be reading one, then executing the GOTO and then continues
to execute below the if thens and repeats at the GoTo STARTPULSE.
<br>
I would make the GOTOs into gosubs with returns, so the code will return
to the next line which is the next sensor.


INCLUDE "modedefs.bas"
CMCON = 7
trisio = %00001111
GPIO = 0
DEFINE OSCCAL_1K 1 ' Set OSCCAL for 1K device
Define OSC 4
@ DEVICE PIC12f629, XT_OSC
@ DEVICE PIC12f629, WDT_ON
@ DEVICE PIC12f629, PWRT_ON
@ DEVICE PIC12f629, MCLR_OFF
@ DEVICE PIC12f629, BOD_ON
@ DEVICE PIC12f629, CPD_OFF
CODELENGTH VAR BYTE 'BYTE VARIABLE OK - LESS THAN 8 PULSES MEASURED
UID VAR BYTE
PIN VAR BYTE
RXPIN1 Var GPIO.3

Pause 100 'SETTLE DOWN BOTH PIC & IR RECEIVER

STARTPULSE:
PulsIn GPIO.3,0,CODELENGTH 'MEASURE LOW PULSE (IR LED ON TIME)
IF (CODELENGTH > 200) and (CODELENGTH < 400) Then SENSOR1
goto STARTPULSE

SENSOR1:
RXPIN1 = GPIO.3
pin = 1
GOSUB CODEPULSES

SENSOR2:
RXPIN1 = GPIO.2
pin = 2
GOSUB CODEPULSES

CODEPULSES:
PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit0 = 1 '2MS PULSE IS 1
IF CODELENGTH < 150 Then LET UID.bit0 = 0 '1MS PULSE IS 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit1 = 1
IF CODELENGTH < 150 Then LET UID.bit1 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit2 = 1
IF CODELENGTH < 150 Then LET UID.bit2 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit3 = 1
IF CODELENGTH < 150 Then LET UID.bit3 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit4 = 1
IF CODELENGTH < 150 Then LET UID.bit4 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit5 = 1
IF CODELENGTH < 150 Then LET UID.bit5 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit6 = 1
IF CODELENGTH < 150 Then LET UID.bit6 = 0

PulsIn RXPIN1,0,CODELENGTH
IF CODELENGTH > 150 Then LET UID.bit7 = 1
IF CODELENGTH < 150 Then LET UID.bit7 = 0

IF UID = 247 Then
GOSUB LEDON
ENDIF
codelength = 0
UID = 0
RETURN

GoTo STARTPULSE

LEDON:
High GPIO.0 'LED ON
serout 1, N2400,[#PIN," ",#UID,10,13]
Pause 500
Low GPIO.0
codelength = 0
UID = 0
GoTo STARTPULSE

End

ardhuru
- 6th September 2008, 08:00
These modules have a weak internal pullup, so simply connecting the outputs of both modules to a single pic pin should work.

Regards,

Anand

jhorsburgh
- 8th September 2008, 00:35
Hi Guys,
What i am trying to do is have the signals come in on different pins and then send the received data along with the input pin number out through RS232. I have tried using GOTO and GOSUBS commands but it only works 50% of the time on one pin and not at all on the other.

Thanks Guys

skimask
- 8th September 2008, 03:19
Hi Guys,
What i am trying to do is have the signals come in on different pins and then send the received data along with the input pin number out through RS232. I have tried using GOTO and GOSUBS commands but it only works 50% of the time on one pin and not at all on the other.

Thanks Guys

Are you saying that because one pin is tied up looking for a pulse that it ends up missing pulses on the other pin?
Not sure if it'll help any (probably won't since a PIC is single threaded and can only act on one input at any one time unless you record any pulses you get and post-process them to see if anything useful was present during the time you recorded any pulses), but if you check your manual, you might find something that'll help you limit the MAXIMUM time the PULSIN statement waits for a PULSE (quite a few hints in that statement right there).

dhouston
- 8th September 2008, 13:31
Why are you using two receivers? If both are 38kHz, both will see both signals. Whichever pin is triggered first will seize control.

jhorsburgh
- 9th September 2008, 00:37
Hey Guys,
I had made the following changes to the code, and added the "DEFINE PULSIN_MAX 300" line to the top of the code. It now works for GPIO.3 most of the time but it does not work at all on GPIO.2. The modules are 38Khz dave but i am not sure what you mean by "both will see both signals. Whichever pin is triggered first will seize control. "

<code>
STARTPULSE:
PulsIn GPIO.3,0,CODELENGTH 'MEASURE LOW PULSE (IR LED ON TIME)
IF (CODELENGTH > 200) and (CODELENGTH < 400) Then SENSOR1
PulsIn GPIO.2,0,CODELENGTH 'MEASURE LOW PULSE (IR LED ON TIME)
IF (CODELENGTH > 200) and (CODELENGTH < 400) Then SENSOR2
goto STARTPULSE

SENSOR1:
RXPIN1 = GPIO.3
pin = 1
GOTO CODEPULSES

SENSOR2:
RXPIN1 = GPIO.2
pin = 2
GOTO CODEPULSES
</code>

Thanks Again,
Jeremy

Bruce
- 9th September 2008, 00:50
Place PulsIn GPIO.2,0,CODELENGTH before PulsIn GPIO.3,0,CODELENGTH.

Does it work with the sensor on GPIO.2 now?

dhouston
- 9th September 2008, 11:31
Unless the two receivers are optically isolated so that neither can see the signal intended for the other, both will see all signals.

The first one in your code will process the signal, blocking all of the code statements for the other one.

If you follow Bruce's suggestion, the one that wasn't working will start working but the other will stop working.