PDA

View Full Version : Can not decode properly IR remote code.



CuriousOne
- 20th December 2013, 11:10
Hello.

I want to use the IR remote in my project. I got the 38khz receiver from STB, and it's remote control. The code I'm using is as follows:



mand VAR word
vice VAR word
pice var word
cice var word

main:
SERIN irPin,N2400,vice,mand,pice,cice
LCDOUT $FE,$C0,#vice, " ", #mand," ",#pice, " ", #cice, " "
goto main


The problem is, that codes being read, are almost always different, but remain within same range according the distance of remote to receiver. Say, at 5cm, when pressing "1" button, I'll get reading in range of 240-250, but at 50cm, reading with same button will be 40-50. Even more fun is the fact, that when checked with scope, the signal on sensor output is the same. Here I attach the screenshot from scope.

What I'm doing wrong?

http://www.freeimagehosting.net/newuploads/yqv37.jpg

gadelhas
- 20th December 2013, 13:07
I don't understand why are you using serin????!?!?
IR protocol doesn't work with serin, you must create code to read it. By looking at the picture it seems to me that the protocol its NEC, so use code to decode NEC protocol. If you do a search in the forum you will find some code.

CuriousOne
- 20th December 2013, 13:40
Yes, I found that it is nec, and tried to take code from here:

http://www.picbasic.co.uk/forum/showthread.php?t=15368

and modified it to my needs:



Include "modedefs.bas" ' Include serial modes
'DEFINES FOR LCD PORTS
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 1500
DEFINE LCD_DATAUS 44

define osc 4

ADCON1=%00000110 'CONFIGURE PORT A AS DIGITAL
'TRISA=1 'CONFIGURE PORT A AS INPUT
low TRISB
LOW TRISC
LOW TRISA


Leader VAR WORD ' will be up to 900 for a 9mS leader pulse
BtnVal VAR BYTE[32] ' holds 32 pulse results
DByte1 VAR BYTE ' address byte
DByte2 VAR BYTE ' inverse of address byte
DByte3 VAR BYTE ' command byte
DByte4 VAR BYTE ' inverse of command byte
X VAR BYTE ' loop count

LCDOUT $FE, 1, "test "

Main:
PULSIN PORTC.4,0,Leader ' leader pulse is ~9mS low-going
IF Leader < 850 THEN Main

FOR X = 0 TO 31 ' grab 32 incoming pulses
PULSIN PORTC.4,1,BtnVal(X) ' now measuring high-going pulse widths
NEXT X

' now we'll decode 4 bytes from 32 pulses
FOR X = 0 TO 7 ' sort 1st 8 pulses
IF BtnVal[X] > 150 THEN ' > 150 x 10uS = > 1.5mS pulse period
DByte1.0[X]=1
ELSE
DByte1.0[X]=0
ENDIF
NEXT X

FOR X = 8 TO 15 ' sort 2nd 8 pulses, etc....
IF BtnVal[X] > 150 THEN
DByte2.0[X-8]=1
ELSE
DByte2.0[X-8]=0
ENDIF
NEXT X

FOR X = 16 TO 23
IF BtnVal[X] > 150 THEN
DByte3.0[X-16]=1
ELSE
DByte3.0[X-16]=0
ENDIF
NEXT X

FOR X = 24 TO 31
IF BtnVal[X] > 150 THEN
DByte4.0[X-24]=1
ELSE
DByte4.0[X-24]=0
ENDIF
NEXT X

LCDOUT $FE, 1, #dbyte1, " ", #dbyte2, " "
LCDOUT $FE, $C0,#dbyte3, " ", #dbyte4, " "

PAUSE 1000
GOTO Main


The problem is, it still does not works. It displays "0" when I press a key on remote. Sometimes, it will display something, like 4 or 170, but it never matches the key pressed and never repeats.

gadelhas
- 20th December 2013, 15:47
I didn't look at the code, because i'm at work, but you should post your schematic too!

CuriousOne
- 20th December 2013, 15:55
There's nothing much to post in schematic, the receiver is hooked as it should, GND goes to GND, VDD goes to VDD, and OUT is connected to PORTC.4

ivanrosales
- 20th December 2013, 17:04
I never tried NEC protocol before, but Sony SIRC has been worked flawlessly to me and it's very easy to decode with minimal resources, you should give a try:
http://www.picbasic.co.uk/forum/content.php?r=438-Add-IR-remote-control-capabilities-to-your-next-project!!

Regards.

longpole001
- 21st December 2013, 00:47
here is part of code i wrote to capture the IR codes for NEC protocol from a remote controlled LED RGB lamp project
code uses a 8mhz, PIC12F683, code use IOC with darrel 's int routines

hope it helps




DEFINE OSC 8 ' Timing referance for pause , pauseus commands
DEFINE PULSIN_MAX 21600 ' Maximum counts( clock ticks) allowed before pulsin times out( 21600 ^ 5ms = 108 ms)
' Norm IR pulse length is 108ms


' ========================= Get IR Code Routine =================
' * *
' * ******* IOC - Interupt Handler routine ******* *
' * *
'================================================= ===================

GetIRcode:

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
y = 0 ' Y is used for each byte

rctime IR,0,Leader ' get leader low pulse time value in on GPIO.0
IF Leader < 1700 or Leader > 1875 tHEN ' look for 9000us Low pulse of header for 1st or 2nd key area pulse
@ INT_RETURN ; reject if < 8500us or > 9375us (1700^ 5us= 8500us)
endif


RCtime IR,1,Leader ' check for 1st key seq high pulse for 4.5ms after the 9ms low pulse so no repeat headers or 2nd key
if Leader < 850 or Leader > 950 then ' if high for < 4250us then its the 2nkey /data at wrong or > 4750us ( invalid pulse) ( 850 * 5us = 4250us)
@ INT_RETURN
endif


FOR X = 0 TO 31 ' grab 32 incoming pulses
PULSIN IR,1,leader ' now measuring high-going pulse widths ( pulsin_max set to 21600 = 108ms )
BtnVal(x) = leader/2 ' leader divide by 2 so array Btnval(x) is byte (<255) not word value
NEXT X


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) c
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

CuriousOne
- 21st December 2013, 13:07
Thanks, but your code lacks some commands as I can see, like:

OSCCON = %01110111

to set OSC clock to 8mhz

CuriousOne
- 21st December 2013, 13:26
And it is quite interesting, if it's possible to decode air conditioner remote codes? they are very long and very weird :)

gadelhas
- 21st December 2013, 20:29
Thanks, but your code lacks some commands as I can see, like:

OSCCON = %01110111

to set OSC clock to 8mhz

You cannot assume that just by see "DEFINE OSC 8", because he can be using an external osc. You can only assume that, it he had post the config fuses.

One more thing, about this


There's nothing much to post in schematic, the receiver is hooked as it should, GND goes to GND, VDD goes to VDD, and OUT is connected to PORTC.4


What's the reference of your IR receiver? Because some need a pull up resistor, when your are not using it.

CuriousOne
- 22nd December 2013, 18:50
I've solved the problem, but code is quite weird :)

Code looks like this:



MAIN:
PULSIN FLASH,1,SOMEVAR
IF SOMEVAR<50 AND SOMEVAR >20 THEN GOTO KOUNT
GOTO MAIN
KOUNT:
INCREMENT=INCREMENT+1
IF FLASH=1 THEN POS=POS+1 ELSE NEG=NEG+1
IF INCREMENT>1000 THEN GOTO COMPLETE
GOTO KOUNT
COMPLETE:
IF POS>100 AND POS<300 AND NEG>1000 AND NEG<3000 THEN GOSUB JOB:
POS=0:NEG=0:INCREMENT=0
GOTO MAIN
JOB:
TOGGLE RELAY1
RETURN
END