PDA

View Full Version : Solved PASM-loop misses some IR-receiver pulses



StefanL38
10-14-2011, 08:31 PM
Hi,

my current project is "recording" IR-remote-signals in a special way.

I'm using an IR-receiver that is NOT decoding the carrier-frequency.
The Output of the TSOP98200 (http://www.google.de/url?sa=t&source=web&cd=2&ved=0CDgQFjAB&url=http%3A%2F%2Fwww.vishay.com%2Fdocs%2F84795%2Ft sop9820.pdf&ei=MZiYTvn1D4Gt8QO-yenoBQ&usg=AFQjCNGuGB391lMyVM2x65Hvlyl3nfFjAg) does still show all the single-pulses with carrier-frequency. (usually these receivers are used for lowest-level IR-repeaters re-emitting the carrier-signal)

Why am I using this one? Because I want to record all carrierfrequencies (30, 33, 36, 38, 40, 44, 50. 56 kHz) Because of this a standard demodulator with a fixed carrier-frequecy can't be used.

Now my current approach to to this is to measure the carrier-frequency of the first pulses.
Then setting up counterA to neg-edge-mode FRQA := 1 and then running a loop that looks for PHSA
beeing bigger than zero. This loop runs at a frequency of 8 times carrierfreuquency.
Whenever a carrier-pulse is detected a bit is added to a long But only at the carrier-frequency.
If 32 bits are put together this long will be stored into HUB-RAM.

This means each bit represents one carrier-pulse to reduce needed RAM.

Now the strange thing is that some pulses are not detected.
in the fixed-font part below you see a long row if "1"s but at two places 3 zeros inbetween.
(the bold red ones)
I re-checked with a digital storage oscilloscope (DSO) several times if these short "no carrier"-sequences are coming from the IR-receiver. The do not. The IR-receiver it self produces
a continious pulsetrain.

Know I'm puzzled why my PASM-loop is missing some pulses as the loop is running at 8 times higher speed as the pulses come in.
I'm using the counter which is independet of code-execution. The time between reading out PHSA and resetting PHSA to zero for the next cycle is pretty short.
Much shorter than a period. I even added another cog that strechtes the pulses from the IR-reiver from 1 microsecond up to half carrier-frequency (38kHz = 26 microseconds) Pulsewidth 13 microseconds.

How can it be that some pulses are detected as zero = no carrier-pulse? while there are carrier-pulses!


ser.start(30,31,0,115200) done
cognew(Toggle_Pin(0, 4),@ToggleStack)done
cognew(@entryMeasureFreq,0) done
ready for recording pulsetrain
wait for pulsetrain
wait for pulsetrain
11111111111111111111111111111111
11111111111111111111000111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11110001111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111100000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000001111
11111000111111111000000000000000
00000000000000000000000000000000
00000000000001111111111111111111
10000000000000000000000000000000
00000000000000000000000000000011
11111111111111111100000000000000
00000000000000000000000000000000
00000000000000111111111111111111
11000000000000000000000000000000
00000000000000000000000000000001
11111111111111111110000000000000
00000000000000000000000000000000
00000000000000011111111111111111
11100000000000000000000000111111
11111111111100000000000000000000
11111111111111111111000000000000
00000000000000000000000000000000
00000000000000001111111111111111
11110000000000000000000000000000
00000000000000000000000000000000
01111111111111111111100000000000
00000000011111111111111111111000
00000000000000000111111111110001
11111100000000000000000000111111
11111111111111000000000000000000
00111111111111111111110000000000
00000000001111111111111111111100
00000000000000000001111111111111
11111110000000000000000000011111
11111111111111100000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
recording of pulsetrain done
clockticks from pulse to pulse TestVar1 2090
_Period_8tel TestVar2 261
I attach my full testcode as a ZIP-archive.
and here is the interesting part of the PASM-code


edit:
arrrgh!! What is this forum-software doing with my well-fomatted fixed-font code????
Even when I copy it back from the forumsoftware-editor field and paste it into the propeller-tool
everything looks fine again. Only when showing it in the forum the columms jump back and forth like they want.

Forum-Administrator !! Get the forum-software-guy up and solving this problem!!!



DAT
ORG 0

entryMeasureFreq
{
' --------- Debugger Kernel add this at Entry (Addr 0) ---------
long $34FC1202,$6CE81201,$83C120B,$8BC0E0A,$E87C0E03,$8 BC0E0A
long $EC7C0E05,$A0BC1207,$5C7C0003,$5C7C0003,$7FFC,$7FF 8
' --------------------------------------------------------------
}

StartOfCode call #SetOutPuts
call #Read_SPIN_CmdM
call #SetupCounterMode
'initialise variables for recording IR-signalstates
mov _IR_Recv_Long, #0 'reset long containing bits of sampled pulsetrain

mov _HUB_Base_AdrM, par
add _HUB_Base_AdrM, #ptr2HUB_RAM_Buff
mov _HUB_Act_Idx, _HUB_Base_AdrM 'Reset BufferIndex to baseadress
mov _Buff_Count, _BuffSize 'setup variable for buffer-filling-loop
mov _32Bit_Count, #c_NoOfBitsPerLong 'setup variable for filling long with IR-statebits
mov _Period_8Cycl, #0

mov _CarrierOnFlag, #0
mov _CarrierONCnt, #0
mov _CarrierOffCnt, #0
mov _NrOfPulses, #0
mov _LastNoOfPulses,#0
mov _NewNoOfPulses, #0
mov _SumOfPulses, #0
mov _PeriodFrac, #1
shl _PeriodFrac, #c_Divisor '_PeriodFrac contains the fractional how often

call #MeasureCarrierFreq
'coming back from this subr means new carrier-period starts right now
'the counter is already prepared through a mov PHSA, #0 to catch the next high-to-low-transition
'and PHSA containing 1 (and not a highrer value)

mov _TestVar1M, #0'_Period
mov _TestVar2M, _Period_8tel
mov _SPIN_CmdM, #1 'set Status to 0 to indicate command finished
call #Write_SPIN_CmdM

xor OutA, _LED_RightM 'set bit "_LED_LeftM" in OutA-register to 1
mov PHSA, #0

Record_IR_Bits_Loop
waitcnt _MFlopMatch, _Period_8tel 'wait for 1/8 of a period
mov _NrOfPulses, PHSA 'PHSA holds actual sum of pulses update actual number of pulses

add _Period_8Cycl, #1 'increment number of Period 8th cycles
cmp _Period_8Cycl, _PeriodFrac wz 'check if a complete period is over
if_nz jmp #Record_IR_Bits_Loop 'only if period is over do the rest

mov PHSA, #0
mov _Period_8Cycl, #0 'reset loopcounter

cmp _NrOfPulses, #1 wc 'check if there were new pulses
if_c mov _IR_Recv_Bit, #0 'no pulse received => set IR_Recv_Bit to 0
if_nc mov _IR_Recv_Bit, #1 'a pulse received => set IR_Recv_Bit to 1

add _IR_Recv_Long, _IR_Recv_Bit 'add actual bit to long
sub _32Bit_Count, #1 wz 'check for last loop within actual long
if_nz shl _IR_Recv_Long, #1 'if not last bit shift bits 1 to the left

if_z call #WriteLongToBuffer

if_z sub _Buff_Count, #1 wz 'if byte was written to buffer decrement _Buff_Count by one
if_z jmp #Recording_finished 'if _Buff_Count reaches zero buffer is full

'mov _NrOfPulses, PHSA 'PHSA holds actual sum of pulses update actual number of pulses
'cmp _NrOfPulses, #1 wc 'check if there were new pulses
'if_nc or OutA, _VPTriggerPin 'if _NrOfPulses is >= 1 then the C-Flag is cleared
'if_nc add _TestVar1M, #1
jmp #Record_IR_Bits_Loop

Recording_finished

mov _TestVar1M, _Period
'mov _TestVar2M, _Snapshot2
'sub _TestVar2M, _Snapshot1

mov _SPIN_CmdM, #0 'set Status to 0 to indicate command finished
call #Write_SPIN_CmdM

infLoop nop
jmp #infLoop





'SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS SSSSSSSS
'# START Subroutines
'################################################# ########
SetOutPuts mov _BitMaskM, _LED_LeftM
or _BitMaskM, _LED_MiddleM
or _BitMaskM, _LED_RightM
'or _BitMaskM, _MonoFlopPin
or _BitMaskM, _VPTriggerPin
or _BitMaskM, _toggleBit
or DirA, _BitMaskM 'set bits of BitMakM in DirA-register to 1
andn OutA, _BitMaskM 'clear bits of BitMakM in OutA-register to 0

SetOutPuts_ret ret
'---------------------------------------------------------


'################################################# ########
SetupCounterMode 'setup counter-mode and initialise INcS-Register and TSUM-register
' 3 2 1
'10987654321098765432109876543210
'10987654321098765432109876543210
'%-CMODEPLL--------B__PIN---A__PIN
'%00111000000000000000000000000011

movi CTRA, #c_NegEdgeDetectorNoPLL 'setup counter for negative-edge-mode
movs CTRA, #%000000010 'sense IO-pin 2
mov FRQA, #1 'load summand-register with 1
mov PHSA, #0 'load summerise-register with 0
SetupCounterMode_ret ret
'---------------------------------------------------------


'################################################# ########
MeasureCarrierFreq
or OutA, _LED_LeftM 'set bit "_LED_LeftM" in OutA-register to 1

cmp _TestVar2M, #120 wz
if_z jmp #PresetPeriod

mov _InputStateM, #0 'load BitPattern ZERO
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO
'which means pulsetrain starts
mov _InputStateM, #8 'load bitpattern that should be matched
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until INA-registerbit specified in _IR_Recv_Pin2
'has the same state as in _InputStateM
mov _InputStateM, #0 'load BitPattern ZERO
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO

mov _InputStateM, #0 'load BitPattern ZERO
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO
'which means pulsetrain starts
mov _InputStateM, #8 'load bitpattern that should be matched
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until INA-registerbit specified in _IR_Recv_Pin2
'has the same state as in _InputStateM
mov _InputStateM, #0 'load BitPattern ZERO
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO

mov _InputStateM, #0 'load BitPattern ZERO
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO
'which means pulsetrain starts
mov _InputStateM, #8 'load bitpattern that should be matched
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until INA-registerbit specified in _IR_Recv_Pin2
'has the same state as in _InputStateM
mov _InputStateM, #0 'load BitPattern ZERO
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO

mov _InputStateM, #0 'load BitPattern ZERO
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO
'which means pulsetrain starts
mov _InputStateM, #8 'load bitpattern that should be matched
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until INA-registerbit specified in _IR_Recv_Pin2
'has the same state as in _InputStateM
mov _InputStateM, #0 'load BitPattern ZERO
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO


mov _InputStateM, #0 'load BitPattern ZERO
WaitIRPinLow waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO
'which means pulsetrain starts
mov _FirstPulse, cnt 'take snapshot of free running systemcounter

or OutA, _LED_MiddleM 'set bit "_LED_MiddleM" in OutA-register to 1


mov _InputStateM, #8 'load bitpattern that should be matched
WaitIRPinHigh waitpeq _InputStateM, _IR_Recv_Pin2 'wait until INA-registerbit specified in _IR_Recv_Pin2
'has the same state as in _InputStateM
mov _InputStateM, #0 'load BitPattern ZERO
WaitIRPinLow2 waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO
'which means pulsetrain starts
mov _SecondPulse, cnt 'take snapshot of free running systemcounter

andn OutA, _LED_LeftM 'clear bit "_LED_LeftM" in OutA-register to 0

mov _Period, _SecondPulse
sub _Period, _FirstPulse 'calculate clockticks of pulsedistance (=carrier-frequency)
mov _Period25, _Period
shr _Period25, #c_Divisor 'shr c_Divisor bits to the right means divide by 2^c_Divisor

jmp #here
PresetPeriod mov _Period, _2000

mov _Period_8tel, _Period
shr _Period_8tel, #c_Divisor 'shr 3 bits to the right means divide by 2^3 = 8 - 1/8 of a period
mov _MFlopMatch, _SecondPulse 'copy value of systemcounter-snapshot before
add _MFlopMatch, _Period 'add clockticks of 1 period
sub _MFlopMatch, _AheadTicks 'substract clockticks to be ahead of the next high-to-low-transition
mov PHSA, #0 'prepare counter to detect high-to-low-transition
or OutA, _LED_MiddleM 'set bit "_LED_LeftM" in OutA-register to 1
jmp #MeasureCarrierFreq_ret

here mov _Period_8tel, _Period
shr _Period_8tel, #c_Divisor 'shr 3 bits to the right means divide by 2^3 = 8 - 1/8 of a period

'wait until next pulse-period begins
mov _MFlopMatch, _SecondPulse 'copy value of systemcounter-snapshot before
add _MFlopMatch, _Period 'add clockticks of 1 period
sub _MFlopMatch, _AheadTicks 'substract clockticks to be ahead of the next high-to-low-transition

waitcnt _MFlopMatch, _Period

mov PHSA, #0 'prepare counter to detect high-to-low-transition
or OutA, _LED_MiddleM 'set bit "_LED_LeftM" in OutA-register to 1
MeasureCarrierFreq_ret ret
'---------------------------------------------------------


'################################################# ########
WriteLongToBuffer
wrlong _IR_Recv_Long, _HUB_Act_Idx 'write long to HUB-RAM
add _HUB_Act_Idx, #4 'set HUB-RAM-adress to next long

mov _IR_Recv_Long, #0 'reset long that contains sampled bits of pulsetrain
mov _32Bit_Count, #c_NoOfBitsPerLong 'setup variable for filling long with IR-statebits
WriteLongToBuffer_ret ret
'---------------------------------------------------------


'################################################# ########
ReSyncToCarrier
mov _InputStateM, #0 'load BitPattern ZERO
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO
mov _MFlopMatch, cnt 'new snapshot of systemcounter
add _MFlopMatch, _Period
sub _MFlopMatch, _AheadTicks

or OutA, _DebugPin
add _TestVar2M, #1

waitcnt _MFlopMatch, _Period
'mov _IR_Recv_Bit, #1 'resyncing means a pulse has occurred so set _IR_Recv_Bit to 1
ReSyncToCarrier_ret ret
'---------------------------------------------------------


'################################################# ########
Read_SPIN_CmdM
mov _HUB_Base_AdrM, par
add _HUB_Base_AdrM, #ptr2_S2A_Cmd
rdlong _SPIN_CmdM, _HUB_Base_AdrM

mov _HUB_Base_AdrM, par
add _HUB_Base_AdrM, #ptr2TestVar1
rdlong _TestVar1M, _HUB_Base_AdrM

mov _HUB_Base_AdrM, par
add _HUB_Base_AdrM, #ptr2TestVar2
rdlong _TestVar2M, _HUB_Base_AdrM

Read_SPIN_CmdM_ret ret
'---------------------------------------------------------


'################################################# ########
Write_SPIN_CmdM
mov _HUB_Base_AdrM, par
add _HUB_Base_AdrM, #ptr2TestVar1
wrlong _TestVar1M, _HUB_Base_AdrM

mov _HUB_Base_AdrM, par
add _HUB_Base_AdrM, #ptr2TestVar2
wrlong _TestVar2M, _HUB_Base_AdrM

mov _HUB_Base_AdrM, par
add _HUB_Base_AdrM, #ptr2_S2A_Cmd
wrlong _SPIN_CmdM, _HUB_Base_AdrM

Write_SPIN_CmdM_ret ret
'---------------------------------------------------------



_IR_Recv_Pin2 long |< 3
_MonoFlopPin long |< c_IR_Recv_Pin
_DebugPin long |< 5
_VPTriggerPin long |< 6

_10microSecs long c_10microSecs

_toggleBit long |< c_C3_LED

_LED_LeftM long |< c_LED_Left
_LED_MiddleM long |< c_LED_Middle
_LED_RightM long |< c_LED_Right

_BuffSize long c_Buffer_Size

_zero long 0

_AheadTicks long c_AheadTicks

_CarrierOnFlag long 1
_2000 long 2000


_SPIN_CmdM res 1
_TestVar1M res 1
_TestVar2M res 1

_HUB_Act_Idx res 1
_HUB_Base_AdrM res 1

_Buff_Count res 1

_32Bit_Count res 1

_FirstPulse res 1
_SecondPulse res 1

_Period res 1
_Period25 res 1
_Period50 res 1
_Period75 res 1

_MFlopMatch res 1
_EOSamplMatch res 1

_IR_Recv_Bit res 1
_IR_Recv_Long res 1

_InputStateM res 1

_BitMaskM res 1

_dummyLongM res 1

_NrOfPulses res 1
_LastNoOfPulses res 1
_NewNoOfPulses res 1
_SumOfPulses res 1
_MatchVal res 1
_Period_8tel res 1
_Period_8Cycl res 1
_CarrierOffCnt res 1
_CarrierONCnt res 1
_PeriodFrac res 1
_Snapshot1 res 1
_Snapshot2 res 1
I hope some PASM-gurus can explain to me why some pulses are missing and how I can
make 101% sure that not even a single pulse is missing.

keep the hints coming
best regards

Stefan

MagIO2
10-14-2011, 09:28 PM
Why don't you toggle a pin directly after the waitcnt? Then you can have a look at the scope at which times you sample. Maybe you simply have problems with the tolerances. The IR senders frequency is maybe not stable enough.

I really wonder why you want to keep all these bits?! The only thing I'd keep is the frequency you measured and translate the rest into a signal without carrier information. If you are interested I can post some code from my experiments (using a receiver) which translates the signal into a table of high and low times and a string which even is human-readable that describes the whole cycle.

With the timing-table and the length of a cycle you could even detect which remote control is sending.

As far as I remember playback of this signal has also been implemented and I successfully send recorded codes to the TV and a digital picture-frame.

StefanL38
10-14-2011, 11:42 PM
Hi MagIO,

thank you for answering. The alternative for storing the signal I see is to store the duration-times when the carrier is On/Off. Now this could be done as a multiple of the carrierfrequency or in 1/10 milliseconds.
Both result in 16 bit values (as the pauses between repeats can be 20-100 milliseconds.) Now with more signal-analysis these pauses could be found and somehow reduced to a 8bit value. So I would need
estimated half the memory for the price that some strange IR-remotes won't match with bordervalues to determine what is a repeat pause.

Reducing the information to databits has the same problems. How short/long is a "1" and a "0" and I would have to implement bi-phase-coding, pulse-distance-coding, pulse-length-coding.

If you have code doing all this reliable I would like to see it.
As I plan to use a 4MBit flash-ROM I don't worry too much about memory with my approach. In my method the duration of carrier On/Off is represented by the number of bits beeing "1" or "0".
So playing back will be very easy. Whenever a bit is "1" send a single carrier-pulse = IR-LED on for some microseconds. Whenever a bit is "0" the IR-LED stays off.
Moving from bit to bit is done with the carrier-frequency.

I changed my code to use POS-mode instead of edge-mode. This means the PHSA-register counts up not only if a transition is detected but wenever and as long as HIGH-level is detected.
This means I have to detect is PHSA = 0 or is it greater than 0 (regardless of how much greater than 0) greater than 0 means a carrier-signal has been detected.

With this change I get sequences of "1"s without one, two or three zeros inbetween. So for the IR-remote I did this primary testing it now seems to work reliable.
Next testphase will be other IR-remotes with new and quite weak batteries to see if it then works reliable too And playing back.

keep the suggestions coming
best regards

Stefan

kuroneko
10-15-2011, 03:51 AM
How can it be that some pulses are detected as zero = no carrier-pulse? while there are carrier-pulses!
Self-inflicted damage. What it boils down to is that you get your carrier frequency measurement wrong by 10 cycles which has a cumulative affect later when you sample the pulses. I applied a 1us/25us fake pulse train (2080 cycles) and also removed the monoflop, 1us is more than enough for a counter to spot. Now look at your first timestamp sample:

mov _InputStateM, #8 'load bitpattern that should be matched
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until INA-registerbit specified in _IR_Recv_Pin2
'has the same state as in _InputStateM
mov _InputStateM, #0 'load BitPattern ZERO
waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO

mov _InputStateM, #0 'load BitPattern ZERO
WaitIRPinLow waitpeq _InputStateM, _IR_Recv_Pin2 'wait until specified bit "_IR_Recv_Pin" is ZERO
'which means pulsetrain starts
mov _FirstPulse, cnt 'take snapshot of free running systemcounter

Or cleaned up a bit:

waitpeq _IR_Recv_Pin2, _IR_Recv_Pin2 ' wait for high
waitpne _IR_Recv_Pin2, _IR_Recv_Pin2 ' wait for low
WaitIRPinLow waitpne _IR_Recv_Pin2, _IR_Recv_Pin2 ' wait for low

mov _FirstPulse, cnt

You measure between two consecutive high-low edges but the red bits of code delay the first measurement by 10 and 6 cycles respectively (2070 and 2074 cycles/period). To me this simply looks like a copy/paste error. Just make sure that you really use alternating blocks, i.e. inserting another wait for high removes the reported glitch.

For the record, if you look at your scan result you'll find two more gaps (4 total).

StefanL38
10-15-2011, 09:33 AM
Hi Kuroneko,

thank you very much for analysing my code and showing how it can be coded shorter.
I corrected my code but there is still a gap. I guess the carrier-frequency is not that stable. (Yesterday I opened another IR-remote-control that was already defect. No chrystal just a capacitor or maybe a resonator)
I guess that having measured the carrier-frequency with some deviation it might be that right inbetween the last

mov _NrOfPulses, PHSA

and resetting PHSA to zero

mov _NrOfPulses, #0

some pulses are not catched. Anyway until now I'm satisfied with the solution to use the counter in POS-mode. Meaning PHSA counts up whenever the IR-Pin is high.
As I only have to detect zero pulses or more than zero pulses it doesn't matter what the exact number in PHSA is.
With this mode I had no more gaps.

In the backround of my head I have a vaque idea of using two cogs:
one cog for resyncing on each single pulse and signaling each pulse towards the second cog. And the second cog collecting the bits together and writing the bitstream to HUB-RAM.
But I have to think more about this before I can start coding it.

best regards

Stefan

MagIO2
10-15-2011, 04:51 PM
Ok, I'll search for my code this evening and post it!

What I do is:
Find the high-times and low-times allowing a deviation and build up a timing table which is sorted (the longest low-time is dismissed because it is the pause between 2 repeats). Together with the typical number of bits send per periode and of course with the carrier frequency this gives a "fingerprint" of a remote control without knowing the real codes so far.

What I plan to do is to create a hash-value out of this, so that finding the right codes is easier.

Let's say I have 4 different high-times and 2 different low-times, then I say high 1 = A, high 2 = B, high 3 = C and high 4 = D.
Low 1 = a and low 2 = b. This way I can translate each cycle into a sequence of letters and easily compare this sequence with codes that have been learned before.

With all the timing-information and the letter-sequence you can also recreate the signal. This is as far as I remember already working.

I think if you manage your 000-problem your code would be perfect to feed my code ;o)

StefanL38
10-15-2011, 05:17 PM
Hi MagIO2,

I have solved the 000-gap problem. the solution is to use the counter in POS-mode. Or when using it without the monoflop with NEG-mode. This means PHSA counts up whenever the IR-Pin is high.
As I only have to detect zero pulses or more than zero pulses it doesn't matter what the exact number in PHSA is.
With this mode I have no more gaps just a slight deviation in the numbers of "1" and "0".

best regards

Stefan

MagIO2
10-15-2011, 06:53 PM
Ok, here is the latest code I found.
You inspired me to continue with this stuff again, so I'll setup my gadgetganster board again! I wanted to continue with code for learning IR codes and write them to different files.

By the way ... can you tell us a bit more about your project (if you want to)?

MagIO2
10-15-2011, 08:06 PM
Hmm .. the latest does not seem to be the best for you to see what's going on ;o)

Here is the code in version 2 which at least shows you the string I talked about.

And for all who don't want to run the code, here is an example of a sample:


analysing...
Total # of samples per sequence: 1181
Summary 0s:
12, 171, 0, 0, 0, 0, 0, 0, 0, 0,
Summary 1s:
9, 30, 82, 451, 0, 0, 0, 0, 0, 0,
bCaBaBaAaAaAaBaAaBaBaAaAaAaAaBaAaAaD36
bCaBaBaAaAaAaBaAaBaBaAaAaAaAaBaAaAaD


As far as I remember, the code samples twice because some IR codes contain a switching bit, some send a code only once and then just a repeat code. Forgot what the 36 means at the end of code 1, but I'll find it out ;o) ....

StefanL38
10-15-2011, 08:55 PM
HI MagIO2,

thank you for sharing your code. As you haven't commented your code I'm too lazy (at the moment) to analyse your code.

best regards

Stefan

MagIO2
10-15-2011, 09:07 PM
Hmmm ... I'm sorry for that! I'm going to improve it and add plenty of comments as soon as I understand what I did ;o)

But I found out that IRbase2 is pretty nice. You can scan a whole remote control and save the codes on SD card.
First you're asked for a filename, then you enter the key-name. After confirming with return you push the according key on the control and the code is displayed and stored on SD card. When entering space the file is closed and the last key is played back on an IR diode attached to two pins. One pin is replaying the signal, the other pin toggles with carrier frequency.

StefanL38
10-15-2011, 09:28 PM
I don't have a GadgetGangster PPB. I have a parallax PPDB, a C3 and a self assembled board.

The C3 needs a different SD-card-driver as the SPI-bus is multiplexed. I haven't dived into that yet. To tell about the project. I want to record all common carrier-frequencies and store 50-60 IR-commands for playing back.
I don't want to use an SD-card. I want to use a SPI-flash-ROM.

Next step is to play back the IR-code from my stored bitstream representing carrier On/Off.
What do you think how much memory does your time-classifying-approach save about my carrier-On/Off-approach?

best regards

Stefan

MagIO2
10-15-2011, 10:14 PM
I think we have the focus on different things. You want to record and playback and I want to have a general purpose driver. So it can record, replay and understand. The understand-part is the reason for translating the IR signal into timing-table and signal string. Because then you can simply do a string-compare to find out which key has been pressed.

With the bitstream you can't do that, as small deviations will cause a failure of the compare.

If I read your initial post right you need ~2000 bits => 250byte per key
What I measured is the code of a JVC IR remote control which has a pretty long message and it could be packed to 18 bytes per key. Additionally 32 bytes are needed for storing the time-table per different remote control.

Playback is easy. You attach one side of the diode to one pin and the other side to another pin. On one pin you constantly output the carrier frequency, on the other pin you output the signal you recorded.

regards,
Andreas

StefanL38
10-15-2011, 10:23 PM
Hi Andreas,

Your functionality with the timing table is great. Especially for recognizing codes.

As you wrote my code would feed perfect into your code. Does your code use a carrier-demodulating IR-receiver? And therefore is fixed to a certain carrier-frequency?

So my code would expand on different carrierfrequencies? The timing analysing would be made from the numbers of "1"'s and "0"'s my code delivers?

best regards

Stefan

MagIO2
10-15-2011, 11:07 PM
Yes, I currently use a TSOP which is doing the demodulation. As long as you are close enough these devices also recognize signals modulated with other carrier-frequencies.
Yes, my hardware setup is theoretically fixed to a carrier frequency. And the code maybe needs some little adjustments. Function analyze works without a change. addList tries to find the timing entry in the list and adds it if no value close enough is found. The deviation allowed is currently set to +/- 2 bits. translate should work and printTrans also needs to take care of the deviation. So, depending on how big the difference the length of the 1s in a row and the 0s in a row is, the deviation maybe has to be changed.

And yes, that's what I'd expect. You simply read the signal into the sigBuf which currently has a size of 257 longs and let my code do the analysis.

For detection of the type of IR control I think some "normalization" or maybe averaging of the timing values needs to be done to make them comparable. My idea is to normalize somehow depending on the carrier frequency. So it would be nice to know the timings you measured.