PDA

View Full Version : NEC IR Protocol remote decoder, help me before I kill myself!



Bonxy
- 23rd August 2011, 20:53
Hi Guys & Gals

I'm going nuts

I am trying to decode the NEC remote protocol and I've been at it for days, I cant even measure the 9ms start pulse!

I have tried to use the pulsin command and I have also used a timer to measure the start pulse but no mater what method I use I get a different pulse width every time I press a remote button, even with the same button, even with different remotes, I just cant figure this out.

IF YOU HAVE SOME NEC CODE PLEASE SHARE :o


'-----------------------------------------------------------------------------
'Defines for EasyPic3
DEFINE LCD_DREG PORTB ' Define LCD registers and bits
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 2
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3

DEFINE OSC 20

include "lcddefs.bas" 'easy LCD
INCLUDE "AllDigital.pbp" 'Set ALL ports to Digital i/o
pause 400

startpulse var byte
main:

startpulse = 0

pulsin portc.0,0,startpulse
if startpulse > 0 then

lcdout cmd,clss, cmd,movtoB12, dec startpulse
pause 1000
endif

GoTo main
'--------------------------------------------------------------------------------------

What am I doing wrong ?

dhouston
- 23rd August 2011, 21:43
Search the Code Example forum - I posted examples (using RF) to send/receive it a few years back. X-10 uses it for their RF remotes.

You can also find RF code here (http://davehouston.org/PIC-RX-TX.TXT)...

The RF code uses slightly different timing (shorter start sequence) but you should be able to handle that. And IR is usually active low while RF is active high.

bogdan
- 24th August 2011, 01:02
i did this a while ago... samsung tv_volume_up=(latching) relay close.... tv_volume_down=(latching) relay open

hope it helps


;Configuration Bits in the MICROCHIP / MPASM SUITE / P16F1933.INC file
;
;----- CONFIG1 Options --------------------------------------------------
;_FOSC_LP EQU H'FFF8' ; LP Oscillator, Low-power crystal connected between OSC1 and OSC2 pins
;_FOSC_XT EQU H'FFF9' ; XT Oscillator, Crystal/resonator connected between OSC1 and OSC2 pins
;_FOSC_HS EQU H'FFFA' ; HS Oscillator, High-speed crystal/resonator connected between OSC1 and OSC2 pins
;_FOSC_EXTRC EQU H'FFFB' ; EXTRC oscillator: External RC circuit connected to CLKIN pin
;_FOSC_INTOSC EQU H'FFFC' ; INTOSC oscillator: I/O function on CLKIN pin
;_FOSC_ECL EQU H'FFFD' ; ECL, External Clock, Low Power Mode (0-0.5 MHz): device clock supplied to CLKIN pin
;_FOSC_ECM EQU H'FFFE' ; ECM, External Clock, Medium Power Mode (0.5-4 MHz): device clock supplied to CLKIN pin
;_FOSC_ECH EQU H'FFFF' ; ECH, External Clock, High Power Mode (4-32 MHz): device clock supplied to CLKIN pin
;
;_WDTE_OFF EQU H'FFE7' ; WDT disabled
;_WDTE_SWDTEN EQU H'FFEF' ; WDT controlled by the SWDTEN bit in the WDTCON register
;_WDTE_NSLEEP EQU H'FFF7' ; WDT enabled while running and disabled in Sleep
;_WDTE_ON EQU H'FFFF' ; WDT enabled
;
;_PWRTE_ON EQU H'FFDF' ; PWRT enabled
;_PWRTE_OFF EQU H'FFFF' ; PWRT disabled
;
;_MCLRE_OFF EQU H'FFBF' ; MCLR/VPP pin function is digital input
;_MCLRE_ON EQU H'FFFF' ; MCLR/VPP pin function is MCLR
;
;_CP_ON EQU H'FF7F' ; Program memory code protection is enabled
;_CP_OFF EQU H'FFFF' ; Program memory code protection is disabled
;
;_CPD_ON EQU H'FEFF' ; Data memory code protection is enabled
;_CPD_OFF EQU H'FFFF' ; Data memory code protection is disabled
;
;_BOREN_OFF EQU H'F9FF' ; Brown-out Reset disabled
;_BOREN_SBODEN EQU H'FBFF' ; Brown-out Reset controlled by the SBOREN bit in the BORCON register
;_BOREN_NSLEEP EQU H'FDFF' ; Brown-out Reset enabled while running and disabled in Sleep
;_BOREN_ON EQU H'FFFF' ; Brown-out Reset enabled
;
;_CLKOUTEN_ON EQU H'F7FF' ; CLKOUT function is enabled on the CLKOUT pin
;_CLKOUTEN_OFF EQU H'FFFF' ; CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
;
;_IESO_OFF EQU H'EFFF' ; Internal/External Switchover mode is disabled
;_IESO_ON EQU H'FFFF' ; Internal/External Switchover mode is enabled
;
;_FCMEN_OFF EQU H'DFFF' ; Fail-Safe Clock Monitor is disabled
;_FCMEN_ON EQU H'FFFF' ; Fail-Safe Clock Monitor is enabled
;
;;----- CONFIG2 Options --------------------------------------------------
;_WRT_ALL EQU H'FFFC' ; 000h to 7FFh write protected, no addresses may be modified by EECON control
;_WRT_HALF EQU H'FFFD' ; 000h to 3FFh write protected, 400h to 7FFh may be modified by EECON control
;_WRT_BOOT EQU H'FFFE' ; 000h to 1FFh write protected, 200h to 7FFh may be modified by EECON control
;_WRT_OFF EQU H'FFFF' ; Write protection off
;
;_PLLEN_OFF EQU H'FEFF' ; 4x PLL disabled
;_PLLEN_ON EQU H'FFFF' ; 4x PLL enabled
;
;_STVREN_OFF EQU H'FDFF' ; Stack Overflow or Underflow will not cause a Reset
;_STVREN_ON EQU H'FFFF' ; Stack Overflow or Underflow will cause a Reset
;
;_BORV_25 EQU H'FBFF' ; Brown-out Reset Voltage (VBOR) set to 2.5 V
;_BORV_19 EQU H'FFFF' ; Brown-out Reset Voltage (VBOR) set to 1.9 V
;
;_LVP_OFF EQU H'DFFF' ; High-voltage on MCLR/VPP must be used for programming
;_LVP_ON EQU H'FFFF' ; Low-voltage programming enabled
;
;
;
;

@ __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF ;commented the line in the picbasic folder file="12F1822.inc"
;-------------------------------------------------------------------------------
CLEAR ;Set all RAM registers to zero
;================================================= ==============================
;PORTS CONFIGURATION
;RA0 IR
;RA2, RA4 connection to relay
;RA5 LED
OSCCON.1=0
OSCCON.0=0 ;When the SCS bits of the OSCCON register = 00,
;the system clock source is determined by
;configuration of the FOSC<2:0> bits in the
;Configuration Word Register 1 (CONFIG1)
OSCCON.6=1 ;int osc freq 4MHz (IRCF bits)
OSCCON.5=1 ;int osc freq 4MHz (IRCF bits)
OSCCON.4=0 ;int osc freq 4MHz (IRCF bits)
OSCCON.3=1 ;int osc freq 4MHz (IRCF bits)
ANSELA=0 ;turn off the Analog to Digital converter,
;needs to be disabled prior to use I/O on portA.0 to 5
CM1CON0.7=0 ;Comparators Off (CxON bit)
FVRCON.7=0 ;Fixed Voltage Reference is disabled (FVREN bit)
DEFINE OSC 4 ;=4MHz
DEFINE PULSIN_MAX 490
OPTION_REG.7=1
Header VAR WORD
index VAR BYTE
IR_pulse VAR BYTE[31]
IR_data VAR BYTE[31]
PORTA=0
TRISA=%000001 ;PORTA.0 input for the IR

IRIN:
PULSIN PORTA.0,0,Header
IF (Header<400) OR (Header>490) THEN GOTO IRIN
FOR index=0 TO 31
PULSIN PORTA.0,1,IR_pulse[index]
NEXT
FOR index=0 TO 31
WRITE index,IR_pulse[index]
IF IR_pulse[index]<100 THEN
IR_pulse[index]=0
ELSE
IR_pulse[index]=1
ENDIF
NEXT

'Volume UP
FOR index=0 TO 31
LOOKUP Index,[1,1,1,0, 0,0,0,0, 1,1,1,0, 0,0,0,0, 1,1,1,0, 0,0,0,0, 0,0,0,1, 1,1,1,1],IR_data
IF IR_pulse[index]<>IR_data then Volume_DOWN
NEXT index
PORTA.5=1 ;turn ON the LED and operate (set) the relay
PORTA.4=0
PORTA.2=1
PAUSE 2 ;Relay Data sheet: 3 ms max. (mean value: approx. 2.0 ms)
PORTA.2=0
pause 1000 ;protect the relay for overusage when they keep the vol up pressed

'Volume DOWN
Volume_DOWN:
FOR index=0 TO 31
LOOKUP Index,[1,1,1,0, 0,0,0,0, 1,1,1,0, 0,0,0,0, 1,1,0,1, 0,0,0,0, 0,0,1,0, 1,1,1,1],IR_data
IF IR_pulse[index]<>IR_data then IRIN
NEXT index

PORTA.5=0 ;turn OFF the LED and release (reset) the relay
PORTA.2=0
PORTA.4=1
PAUSE 1 ;Relay Data sheet: 2 ms max. (mean value: approx. 1.0 ms)
PORTA.4=0
pause 1000 ;protect the relay for overusage when they keep the vol down pressed
GOTO IRIN

Bonxy
- 24th August 2011, 18:52
Hi Guys, thanks for sharing your code with me, dhouston i did see your code before when I was trawling the net and the forum for a solution, and bogdan I like your lookup table for the Ir data, but I am beginning to think there is something wrong with my Ir receiver IC...
As far as I understand it the 9ms start pulse should be totaly constant and the same every time any key is pressed, but the start pulse width is different every time I pres a key so I cant move on to making any decoding code until I figure out why the start pulse is different every time.
I'm going to change the ir reciver for another one and will report back, thanks for helping me with this :-)

dhouston
- 24th August 2011, 20:26
I would allow for ±20% deviation in the start pulse. The NEC code has built-in error checking so grabbing the wrong code is not much of a problem.

Where are you doing your testing? Fluorescent lights can output a lot of noise in the 38kHz band that NEC used. Direct sunlight can also be a complication. Otherwise, IR tends to be mostly noise free so catching the start code is usually straightforward.

I would not use PulsIn. Here's some hastily modified and untested code that should work. Blame the forum software for the screwed up spacing/tabs, etc.

'=======================| GENERIC IR/RF RECEIVER |=========================
'GEN-RF-683.BAS
'PIC12F683 @4MHz uses MPASM

'================================================= =========================

@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _FCMEN_OFF

DEFINE OSC 4
DEFINE DEBUG_REG GPIO
DEFINE DEBUG_BIT 2
DEFINE DEBUGIN_REG GPIO
DEFINE DEBUG_IN 3
DEFINE DEBUG_MODE 1
DEFINE DEBUG_BAUD 9600

@Timer1=TMR1L
Timer1 VAR WORD EXT
TMR1ON VAR T1CON.0 'Timer1 ON/OFF control bit
IR VAR byte[4]
leadin var byte[2]
period VAR byte
i VAR byte
bits VAR byte

OSCCON =%01100001 '4MHz _INTRC_OSC_NOCLKOUT
CMCON0 =%00000111 'disable comparators
ANSEL =%00000001 'AN0=analog
ADCON0.7 =1 'right justify ADC
TRISIO =%00101011 'input=1,output=0
GPIO =%00101000 'high=1,low=0
INTCON =%00000000 'disable interrupts
T1CON =%00110000 'TMR1 prescaler=8,tick=8µS

init: RF[0]=0:RF[1]=0:RF[2]=0:RF[3]=0:
While GPIO.1=1 'wait falling edge
Wend 'falling edge
TMR0=0:OPTION_REG=%10000101 'TMR0 prescaler=64
While GPIO.1=0 'wait rising edge
Wend 'rising edge
leadin[0]=TMR0:TMR0=0
If (leadin[0]<154) Then init '8500µS (154)
If (leadin[0]>190) Then init '10500µS (190)
While GPIO.1=1 'wait falling edge
Wend 'falling edge
leadin[1]=TMR0:TMR0=0 'clear TMR0
OPTION_REG=%10000011 'TMR0 prescaler=16
i=0
Repeat
While GPIO.1=0 'wait rising edge
If TMR0>186 Then break '3000µS
Wend 'rising edge
While GPIO.1=1 'wait falling edge
If TMR0>186 Then break '3000µS
Wend 'edge
period=TMR0:TMR0=0 'reset TMR0
If (period<49) Then init
If (period>93) Then '1500µS
IR.0(i)=1
EndIf
i=i+1
Until (i>31)
break: If (i<32) Then init
Debug hex2 i
For i = 0 to 3
Debug hex2 IR[i] REV 8
Next
TMR1ON=0:Timer1=0:TMR1ON=1
Debug 13,10
GoTo init

End

Bonxy
- 28th August 2011, 16:29
Hi Guys

Ok, I am totaly stumpped with this, I have tried to use a timer as suggested by dhouston & I have been trying the pulsin method as suggested by bogdan but I get the same problem, the start pulse is all over the place, it ranges from 0 to 255 etc, it seems random.
I have changed the ir reciver to eliminate a fault there and I checked the output on my scope and it seems to show a correct pattern.

God knows what I am doing wrong, I just wonder if it is down to the pic's i use 18f4550 & 18f14k50 ?, I have even changed the oscillator down to 4mhz to try and copy bogdan's pulsin code (shown below), also I dont know why the example uses a word var for the pulsin, am I missing something there ?.
Maths is not my strong point so maybe I'm just reading things worong I dunno but I've been at this a week now and cant get the same start pulse 2 times in a row.

Could someone check the code below and tell me why I dont get values in the range of 400 - 490 ?.


'Defines for EasyPic3
DEFINE LCD_DREG PORTB ' Define LCD registers and bits
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 2
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
INCLUDE "AllDigital.pbp" 'Set ALL ports to Digital i/o
DEFINE OSC 4 ;=4MHz
DEFINE PULSIN_MAX 490

Header VAR WORD '<-- why is this a 'word' instead of a byte ?
index VAR BYTE
IR_pulse VAR BYTE[31]
IR_data VAR BYTE[31]
PORTC=0
TRISC=%000001 ;PORTC.0 input for the IR



'Note, device is a 18f4550

IRIN:
PULSIN PORTC.0,0,Header

IF (Header < 400) OR (Header > 490) THEN GOTO IRIN '<-- problem, values I get are not between 400 to 490


goto irin

Jumper
- 28th August 2011, 16:41
Hi,

Please post your HW schematic with component numbers and values. It will be much easier for all of us if we can see what and how you connect to the PIC. Do you have the pic on 5V and the reciver also on 5V.. or are you running a 5V receiver on 3V ?

Step one must be to rule out HW and also make it possible for others to duplicate your setup for testing purposes.

/me

Ioannis
- 28th August 2011, 16:42
Your Header variable is a word because the values you expect are beyond 0-255 range that a byte can accept.

Keep in mind that Pulsin is clock dependant. The real clock your PIC is using, NOT the one you declare with DEFINE OSC line. At 4MHz it increment by a 10usec step. At 20MHz by a 2usec step.

How do you know that values are not within the range?

Do you have some kind of output check?

Ioannis

Bonxy
- 28th August 2011, 17:02
Thanks for your replies

Jumper, I dont have a schematic to post but Im using an easypic3 board with a 18f4550 at 5v with the tsop 2438 reciver on the same 5v with the output pin connected to portc.0 (pdf datasheet attached).

Ioannis, I realised as soon as I posted why it was a word var lol, I assume the valuse are not in the range as I am using the same xtal and code as bogdan's working code ?, as I said I am usless at math so I am taking bogdan's word that the value I should get at 4mhz is between 400 to 490.

bogdan
- 28th August 2011, 17:03
the code was for a samsung tv .... close, but not the same like the nec protocol

SAMSUNG IR protocol:
http://www.samsung.com/global/business/semiconductor/products/microcontrollers/downloads/S3F80KB_RemoteController_AN_REV000_090108.pdf (check "Figure 1. IR Signal")



NEC IR protocol:
http://www.mcselec.com/index.php?option=com_content&task=view&id=223&Itemid=57

... the leader/header for nec should be 9msec

change the
DEFINE PULSIN_MAX 990 (try with 10% deviation... 900*1.1)
- - - - - - - - - - - - - - - - - - - - -
IF (Header < 810) OR (Header > 990) THEN GOTO IRIN (again the -/+10% deviation)

Bonxy
- 28th August 2011, 17:16
I've looked at the nec ir protocol but i'm non the wiser :-(

Just if anyone is interested I have attached the actual code that came with my remote and reciver IC kit, it was written for the arduino and commented in japanese, I have translated the comments to english but I cant translate the code, if anyone wants to look at it it might reveal to someone more experienced what I need to do to get it to work maybe ?.

Jumper
- 28th August 2011, 17:38
Plan B:

Use an other pic and set up the HPWM manually for 38 kHz. Then you connect an IR diode to the HPWM pin using a resistor to get aprox 20 mA in the led.

Then in the code you make a simple main loop. Turn on the HWPM, delay 9 ms, and then turn off the HPWM, wait a while (i.e 5 ms) and then goto main again. Point this led towards the ir-receiver from a close distance and now you have a signal that you really know how it looks like. Then you put a shoebox upside down over both the receiver and the transmitter led so they get a nice dark space to be in.

Have you ever thought about catching the IR signal using the CCP module or by using interupts and a timer?

This way you can even build a text signal for the NEC protocol ... [startpulse] delay [bit0] delay etc..

Which way to decode the signal is the best? Well it all depends what other things your pic will do. If it will only decode the IR signal you can just read the pin in a fast loop and increment a counter when it is LOW.

Keep in mind that the receiver you are using is ACTIVE LOW.. so the pin will be high when there is no modulated IR light present.

dhouston
- 28th August 2011, 19:19
NEC IR protocol:
http://www.mcselec.com/index.php?option=com_content&task=view&id=223&Itemid=57

Here's a more authoritative source for the NEC protocol...


http://davehouston.org/Nec6121.pdf

Bonxy
- 28th August 2011, 19:39
Thanks dhouston, but looking at more protocol descriptions is just giving me headache lol, I've been at it all week, I think I've actually looked at the description before when I was first googling the nec protocol.

What I need is a simple working code example that I can then develop...

If you or anyone can give me a code example for a 18f4550 at 4 or 20 mhz i would be extreemly gratefull..

Thanks guys

cncmachineguy
- 29th August 2011, 03:25
the code was for a samsung tv .... close, but not the same like the nec protocol

SAMSUNG IR protocol:
http://www.samsung.com/global/business/semiconductor/products/microcontrollers/downloads/S3F80KB_RemoteController_AN_REV000_090108.pdf (check "Figure 1. IR Signal")



NEC IR protocol:
http://www.mcselec.com/index.php?option=com_content&task=view&id=223&Itemid=57

... the leader/header for nec should be 9msec

change the
DEFINE PULSIN_MAX 990 (try with 10% deviation... 900*1.1)
- - - - - - - - - - - - - - - - - - - - -
IF (Header < 810) OR (Header > 990) THEN GOTO IRIN (again the -/+10% deviation)

Did you try this?

Bonxy
- 29th August 2011, 08:52
cncmachineguy

Yes I did, i still did not get valuses to match, I got values in the range of 552 to 614 and everything in between.

bogdan
- 29th August 2011, 11:47
please let us now the model # of the remote

(i will try to upload the codes into a universal remote and i will check the protocol later today)

Bruce
- 29th August 2011, 15:45
There are much better/faster ways to do this, but this should get you started with something that's fairly easy to understand.

Assuming you have an NEC transmitter that outputs something like the top portion of the graphic below;


5927



This should return similar results to what's shown in the serial terminal window just above.


#CONFIG
__config _XT_OSC & _WDT_ON & _MCLRE_OFF & _LVP_OFF & _CP_OFF
#ENDCONFIG

DEFINE OSC 4

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

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

FOR X = 0 TO 31 ' grab 32 incoming pulses
PULSIN PORTB.0,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

HSEROUT [BIN8 DByte1,13,10,BIN8 DByte2," Address",13,10,13,10]
HSEROUT [BIN8 DByte3,13,10,BIN8 DByte4," Command",13,10,13,10]
PAUSE 1000
GOTO Main

Bonxy
- 29th August 2011, 20:28
Bruce, thanks for uploading that code, I am going to try the code on my next day off work and will report back, I've had a look and its well commented and I can understand it, so I have fingers crossed that it's going to work :-), I think where I am falling down is my poor understanding of math, eg the osc speed and its relation to ms's & pulsin, I just dont get that, anyway I'm going to give your code a good go, thanks again.

Bogdan, I have attached my remote pictures & instruction PDF that came with it, thanks also for your help with this :-)

Ioannis
- 29th August 2011, 20:40
I think where I am falling down is my poor understanding of math, eg the osc speed and its relation to ms's & pulsin

Look at post #8. Also the manual at the Pulsin command explains why is that.

Ioannis

Bonxy
- 31st August 2011, 19:44
Bruce, thank you :-)

Your code worked perfectly at 4 mhz first go :-)

So, I've hacked away at it all day and through trial & error and determination I have got it to work at 20mhz, It was a total pain I could not work out the math for the life of me, so I searched the forum and net, but everyone seems to have a different idea on how to work it out, in the end I resorted to trial & error but I got it to work at 20mhz.

The repeatsub does not work correctly all the time, again I assum a timing error

I show the results below for all to see, I've also tried to add the repeat (button held down) function with limited success, if you or anyone would care to comment on or improve the end result that would be awesom..

'#CONFIG
'__config _XT_OSC & _WDT_ON & _MCLRE_OFF & _LVP_OFF & _CP_OFF
'#ENDCONFIG
'Defines for EasyPic3
DEFINE LCD_DREG PORTB ' Define LCD registers and bits
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 2
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
INCLUDE "AllDigital.pbp" 'Set ALL ports to Digital i/o
include "LCDDEFS.bas" 'easy lcd

DEFINE OSC 20 'set osc to 20mhz

Leader VAR WORD ' will be up to 900 for a 9mS leader pulse
BtnVal VAR word[32] ' holds 32 pulse results 'NEEDS TO BE WORD VAR FOR 20Mhz
DByte1 VAR BYTE ' address byte
DByte2 VAR BYTE ' inverse of address byte
DByte3 VAR BYTE ' command byte
DByte4 VAR BYTE ' inverse of command byte
i VAR BYTE ' loop count

Main:

PULSIN PORTC.0,0,Leader ' leader pulse is ~9mS low-going

IF Leader < 4400 THEN goto Main 'use 850 for 4mhz, use 4400 for 20mhz

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

if btnval(i) > 950 then goto repeatsub 'capture repeat pulse ?

NEXT i



' now we'll decode 4 bytes from 32 pulses (address)
FOR i = 0 TO 7
IF BtnVal[i] > 350 THEN ' > use 150 for 4mhz, use 350 for 20mhz
DByte1.0[i]=1
ELSE
DByte1.0[i]=0
ENDIF
NEXT i


'now we'll decode 4 bytes from 32 pulses (command)
FOR i = 16 TO 23
IF BtnVal[i] > 350 THEN ' > use 150 for 4mhz, use 350 for 20mhz
DByte3.0[i-16]=1
ELSE
DByte3.0[i-16]=0
ENDIF
NEXT i

'show results on LCD, address on top line & command on bottom line
Lcdout cmd,clss,cmd,movtoA2, "Address " , hex DByte1 'debug to LCD display
lcdout cmd,movtoB2, "Command " , hex DByte3 'debug to LCD display

'HSEROUT [BIN8 DByte1,13,10,BIN8 DByte2," Address",13,10,13,10]
'HSEROUT [BIN8 DByte3,13,10,BIN8 DByte4," Command",13,10,13,10]
PAUSE 200 'dont know why this is needed for it to work ?
GOTO Main




'we get to heare if button on remote is held down
repeatsub:
toggle porta.0 ' led to tell us that a button is held down (repeat)

PAUSE 400 'only god knows why this is needed for it to work ?
goto main
return


Thanks..
Bruce
Ioannas
dhouston
bogdan
cncmachineguy
jumper

pull88
- 23rd January 2013, 20:30
Bruce, thank you :-)

Your code worked perfectly at 4 mhz first go :-)

So, I've hacked away at it all day and through trial & error and determination I have got it to work at 20mhz, It was a total pain I could not work out the math for the life of me, so I searched the forum and net, but everyone seems to have a different idea on how to work it out, in the end I resorted to trial & error but I got it to work at 20mhz.

The repeatsub does not work correctly all the time, again I assum a timing error

I show the results below for all to see, I've also tried to add the repeat (button held down) function with limited success, if you or anyone would care to comment on or improve the end result that would be awesom..

'#CONFIG
'__config _XT_OSC & _WDT_ON & _MCLRE_OFF & _LVP_OFF & _CP_OFF
'#ENDCONFIG
'Defines for EasyPic3
DEFINE LCD_DREG PORTB ' Define LCD registers and bits
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 2
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
INCLUDE "AllDigital.pbp" 'Set ALL ports to Digital i/o
include "LCDDEFS.bas" 'easy lcd

DEFINE OSC 20 'set osc to 20mhz

Leader VAR WORD ' will be up to 900 for a 9mS leader pulse
BtnVal VAR word[32] ' holds 32 pulse results 'NEEDS TO BE WORD VAR FOR 20Mhz
DByte1 VAR BYTE ' address byte
DByte2 VAR BYTE ' inverse of address byte
DByte3 VAR BYTE ' command byte
DByte4 VAR BYTE ' inverse of command byte
i VAR BYTE ' loop count

Main:

PULSIN PORTC.0,0,Leader ' leader pulse is ~9mS low-going

IF Leader < 4400 THEN goto Main 'use 850 for 4mhz, use 4400 for 20mhz

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

if btnval(i) > 950 then goto repeatsub 'capture repeat pulse ?

NEXT i



' now we'll decode 4 bytes from 32 pulses (address)
FOR i = 0 TO 7
IF BtnVal[i] > 350 THEN ' > use 150 for 4mhz, use 350 for 20mhz
DByte1.0[i]=1
ELSE
DByte1.0[i]=0
ENDIF
NEXT i


'now we'll decode 4 bytes from 32 pulses (command)
FOR i = 16 TO 23
IF BtnVal[i] > 350 THEN ' > use 150 for 4mhz, use 350 for 20mhz
DByte3.0[i-16]=1
ELSE
DByte3.0[i-16]=0
ENDIF
NEXT i

'show results on LCD, address on top line & command on bottom line
Lcdout cmd,clss,cmd,movtoA2, "Address " , hex DByte1 'debug to LCD display
lcdout cmd,movtoB2, "Command " , hex DByte3 'debug to LCD display

'HSEROUT [BIN8 DByte1,13,10,BIN8 DByte2," Address",13,10,13,10]
'HSEROUT [BIN8 DByte3,13,10,BIN8 DByte4," Command",13,10,13,10]
PAUSE 200 'dont know why this is needed for it to work ?
GOTO Main




'we get to heare if button on remote is held down
repeatsub:
toggle porta.0 ' led to tell us that a button is held down (repeat)

PAUSE 400 'only god knows why this is needed for it to work ?
goto main
return


Thanks..
Bruce
Ioannas
dhouston
bogdan
cncmachineguy
jumper

Hello friend my name es Paul, one question: what happen if I want to turn on the light with a specific key to the remote control? example, I want to turn on the light with the source button, from my samsug led tv, the codec is: E0E0807F hex, please help me.

RONY11
- 30th May 2016, 07:29
pls any one help me.....i want to take data from TSOP with nec protocol......and change duty cycle of pwm at ccp1 pin and increse and decrese brightness of led....i using 16f887........pls give me code.....

RFEFX
- 19th January 2018, 19:33
Bonxy,

Thank you for figuring out 20Mhz values. i would have never thought they would be different between different oscillators.

Pro Tip: there are new LED lights at SAM's club that have an infrared remote. the remotes operate on the NEC protocol not to mention they are color coded buttons !!!

Regards,
Gary D.

RFEFX
- 19th January 2018, 19:45
Hello friend my name es Paul, one question: what happen if I want to turn on the light with a specific key to the remote control? example, I want to turn on the light with the source button, from my samsug led tv, the codec is: E0E0807F hex, please help me.

I know this reply is 5 years too late.. lol. but just in case anyone else would like to control their lights. http://www.picbasic.co.uk/forum/showthread.php?t=15712

Ioannis
- 19th January 2018, 19:53
By the way, your signature link is not valid anymore. Are you aware of that?

Ioannis