PDA

View Full Version : NEC IR decoding issues (and another thread is closed)



CuriousOne
- 10th December 2023, 09:18
Hello.
I found this thread https://www.picbasic.co.uk/forum/showthread.php/15368-NEC-IR-Protocol-remote-decoder-help-me-before-I-kill-myself!
But it is closed, so I can't answer there.

I've used code from it, which looks like this:



'************************************************* ***************
'* Name : I2C EEPROM *
'* Author : Daniel T. Barber *
'* Notice : Copyright (c) 2018 *
'************************************************* ***************


@ ERRORLEVEL -306 ' turn off crossing page boundary message

'************ Config Settings for 16F877A *************
#CONFIG
cfg1 = _INTRC_OSC_NOCLKOUT ; INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
cfg1&= _WDT_ON ; WDT enabled
cfg1&= _PWRTE_OFF ; PWRT disabled
cfg1&= _MCLRE_OFF ; RE3/MCLR pin function is digital input, MCLR internally tied to VDD
cfg1&= _CP_OFF ; Program memory code protection is disabled
cfg1&= _CPD_OFF ; Data memory code protection is disabled
cfg1&= _BOR_OFF ; BOR disabled
cfg1&= _IESO_ON ; Internal/External Switchover mode is enabled
cfg1&= _FCMEN_ON ; Fail-Safe Clock Monitor is enabled
cfg1&= _LVP_OFF ; RB3 pin has digital I/O, HV on MCLR must be used for programming
cfg1&= _DEBUG_OFF ; In-Circuit Debugger disabled, RB6/ICSPCLK and RB7/ICSPDAT are general purpose I/O pins
__CONFIG _CONFIG1, cfg1


cfg2 = _BOR40V ; Brown-out Reset set to 4.0V
cfg2&= _WRT_OFF ; Write protection off
__CONFIG _CONFIG2, cfg2


#ENDCONFIG

TRISA=%01000000 'SET A TO OUTPUT 1=input
TRISC=%10000000 'set half C for in/out
TRISB=%00000000 'set PortB to output
ANSELH=%00000000 ' ADC OFF B
ANSEL=%000000000 'configure PortA as digital except first 2
ADCON1=%10000000 'adc justify
OSCCON=%01110101 'SET FREQUENCY TO 8MHZ
WPUB=%00000000 'turn off Pullups
CM1CON0=0 'DISABLE COMPARATORS
CM2CON0=0 'SAME HERE


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
portval var word '

Define OSC 8 'Adjust consistent with oscillator speed being used


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

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

SEROUT2 portc.5,90,[BIN8 DByte1,13,10,BIN8 DByte2," Address",13,10,13,10]
SEROUT2 portc.5,90, [BIN8 DByte3,13,10,BIN8 DByte4," Command",13,10,13,10]
PAUSE 1000
GOTO Main




It kinda works - the output occurs only when I press some button on the remote, but the issue is that it always returns

00000000
00000000 Address


00000000
00000000 Command

This happens on every button press on every remote.
However, if I keep some button pressed, then the repeat statement gets caught and all 0 -s are replaced by 1. But no other response. I tried different remotes - same. I also tried to just output PULSIN data directly into serial port and it is something in between 300-800, when I press any key on remote, and around 19155 when I hold some key, so repeat statement is sent.

What I'nm doing wrong?

CuriousOne
- 10th December 2023, 10:12
Fixed. Just dumped raw value of what is written BtnVal and it is either around 80 or 110, so I modified the code and now it works!
But why so low values? due to slower PIC ?

HenrikOlsson
- 10th December 2023, 11:34
The value returned by PULSIN for a specific pulse width is dependent of the speed at which the PIC runs.
At 4MHz the resoulution is 10us, at 20MHz it's 2us (all according to the manual).

This means that the PULSIN values corresponding to a logic "1" and "0" will be different depending on oscillator frequency.

I reccon the code you copied comes from Bruce's post #18 in the thread? Is that correct?

CuriousOne
- 10th December 2023, 14:21
Yes, correct.

I tried to make this code respond faster, by changing the pause value from 1000 to 100 (works fine), but when I change it from 100 to 10, now it improperly detects half of the statements.

I want to use this code to remote control a clock, and as I understand, PULSIN can't run in background, so it will be slowing down the clock routines, right? The clock code has to read from RTC, update display, check for alarms, adjust backlight leds and so on....

As I understand, there will be a need to use timer somehow, for lead pulse detection, and based on it, interrupt will be generated and IR decoding code will be run?

Ioannis
- 10th December 2023, 17:46
A fast ISR is the best way to go.

But you may get away with other routes too.

For example, if you read the RTC interrupt every second to update the time and test the other things you want. Finally read the IR code.

Since IR transmission is not repeated quickly, you have plenty of time to do the above tasks. The worse that can happen is to loose one transmission but will grab the second.

I believe your RTC does have an Interrupt output, so that MCU can be triggered, either poll or by interrupt regularly.

Ioannis