ppm decoder

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

ppm decoder

2,602 Views
PW_CTL
Contributor III

Hi, 

I am working on a ppm decoder with a RS08KA4, but I'm not sure about how to make it. In the past I've done a NEC decoder with this MCU, measuring the time between low pulses. 
Has anybody did something with ppm signals to receive some bytes?
Thanks and best regards. 
Labels (1)
0 Kudos
15 Replies

1,604 Views
bigmac
Specialist III

Hello,

 

How does your current requirement differ from the NEC decode?

 

Within this rather lengthy thread, and starting on page 3, there was assembly code presented for NEC decode processing, that made use of some generalised firmware timing loops.  While this code was intended for HCS08 devices, it could probably be adapted for RS08 applications, with allowance made for differing instruction cycles.

 

Regards,

Mac

 

0 Kudos

1,604 Views
PW_CTL
Contributor III

Hi bigmac,

 

The NEC protocol is easy to decode, there are long pulses and short pulses. Measuring the width of the pulses, you can differ a 0 from a 1, even with a low precision in the measurement. I use TPMCNT for that and it is a good decoder, it never fails.

 

For ppm, the value of the bit comes from the position of the pulse. The protocol encodes every two bits in 4 bits, in the next way:

 

00 -> 1000

01 -> 0100

10 -> 0010

11 -> 0001

 

So, I could measure the distance between pulses, but it can vary a lot (between 0 and 7 positions) so I need a very high precision to detect the distance between pulses propertly. For example, next two sequences: 1000 0001 and 1000 0010, it's very easy to have a mistake, this is not a strong algorithm.

 

You can find attached a sample of the bitstream I am trying to decode.

 

Do you have any suggestion about how to face the problem?

 

Thanks and best regards.

 

0 Kudos

1,604 Views
bigmac
Specialist III

Hello,

 

There must be more to this encoding scheme than is immediately apparent.  What equipment uses this arrangement?

 

The first problem appears to be lack of synchronisation at the start of each codeword.  The first two pulses of the sample appear to be wider than the others.  However, it is unclear whether these might be specially for synchronisation, or perhaps they are the four bit sequence 1100 repeated twice.  The wide pulses occur nowhere else in the sample, which may mean that the 1100 sequence does not occur elsewhere in lhe codeword.  It may also help if we knew what binary value the sample represented.

 

You will need to specify the bit timings and the tolerance on the timing periods.  The use of the TPM module does not easily allow for any bit timing tolerance, and on this basis I would tend to use the software loop timing method where upper and lower limits for pulse timing can be allowed for.

 

Regards,

Mac

 

0 Kudos

1,604 Views
PW_CTL
Contributor III

Hi bigmac, 

 

Thanks for your fast reply.

 

The 1100 sequence is not allowed, the valid sequences are only:

 

1000 (=00)

0100 (=01)

0010 (=10)

0001 (=11)

 

So I think the first sequence is for syncronization. I know the protocol and I can decode it in a paper, but the problem is how to measure the steps with enough accuracy to decide if every two 1s, there are four, five or six 0s.

 

I will try setting a fixed period, but the RS08KA4 do not allow this kind of interrupts, and I don't think it is a robust algorithm. I will post the results later.

 

Thanks and best regards.

 

 

0 Kudos

1,604 Views
bigmac
Specialist III

Hello,

 

My understanding of your previous post was that the data bit sequence 1100 would generate tha pulse timing sequence 0001 1000 which has two adjacent pulses that would form a wide pulse.  I was previously referring to the data sequence, rather than the pulse timing sequence.

 

It may help if you can identify the protocol by a name other than PPM.

 

Regards,

Mac

 

0 Kudos

1,604 Views
PW_CTL
Contributor III

Hello, 

 

Yes, sorry, you are right. Anyway I found more documentation about that and I can confirm you that the initial sequence is for syncronization.

 

The problem still being how to measure the time exactly. With MTIM module, I can set a period of 64us, and the time of the "ones" is 340us. The error is near a 20%, so after 5 zeros we lost the syncronization. 

 

The TPM module also have low accuracy for this task. 

 

do you have any suggestion about how to measure the time between two events more exactly?

 

Thanks and best regards.

0 Kudos

1,604 Views
bigmac
Specialist III

Hello,

 

The MTIM module is not suitable for this purpose.

 

You will need to use a TPM channel with input capture mode.  This will give sufficient resolution for your purpose - you must actually make sure that the TPM prescale setting is such that the time period you are measuring is less than the overflow period.  All processing of the current time event must be completed prior to the next event occurring.

 

As I said in an earlier post, another method is to utilize software loop timing methods.  For the code that I posted in the other thread, there are two generalised sub-routines.  The WAIT_HIGH routine will exit when either the input goes to a high state, or a variable timeout period expires.  The WAIT_LOW routine is similar, but waits for the input to go low.

 

Whatever method you use, you will probably need to make allowance for overall timing variations of maybe +/-20 percent.

 

Regards,

Mac

 

0 Kudos

1,604 Views
PW_CTL
Contributor III

Hi, 

 

Ok, I will use the TPM with the capture mode, I have one prototype prepared to work in this way. Is there any application note or any kind of tutorial about how to use the capture mode of the TPM module?

 

Thanks and best regards.

0 Kudos

1,604 Views
bigmac
Specialist III

Hello,

 

I don't know of any application note - the reference manual should contain enough information to implement input capture.  Input capture operation is really quite simple.  The data returned in the TPM channel register is the TPM counter value at the point of the last input transition, and is not subject to any latency associated with polling.  The TPM count difference, and therefore the period between two transitions, is easily calculated and can then be compared with the timing limits of the IR protocol.

 

On closer examination of the sample waveform, I don't think that your description of the protocol is quite correct.  I think that it is more likely that each pulse is time referenced from the previous pulse, with a number of different length gaps between pulses.  I could identify a possible five different periods within the data, but maybe there are only four, as might be expected.  This is why you need to identify what the nominal timing should be.

 

Accepting that the first two wider pulses flag the start condition, and that each subsequent gap represents two bits, this would make a total of 30 bits per codeword.  Is this correct?

 

The method used by Peter H may not be suited to RS08 devices, since there is no interrupt capability, in the accepted sense.  All applicable flags will need to be polled.

 

Regards,

Mac

0 Kudos

1,604 Views
PeterHouse
Contributor I

Mac,

 

I have only read about the RS08 a little and did not even know it existed until I saw your post. 

 

The global flags register sounds like the RS08 programming model is similar to PIC processors where there is only one interrupt and you have to check flags to determine the interrupt source.  This seems pretty workable if the timer channels can be set to generate an interrupt and have the correct flags available for source determination.

 

I am curious and too lazy to dig out the manuals and read them !  :smileyhappy:

 

Thanks,

 

Peter House

0 Kudos

1,604 Views
PW_CTL
Contributor III

Thanks for the support and the code. Even if it is not directly aplicable, the code seems to be useful.

 

I got it working yesterday in the afternoon. The problem was that the signal was too low (the uC is powered at 3.3V and the signal is about 2V), so it never detects transitions, it consider always low state. I place a pull-up resistor, and everything is working now, I can measure the time between high and low edges with good resolution, using TPM input capture. Now, I only have to apply the decoding algorithm.

 

To set up the TPM input capture, I found next document which explains the use of the registers:

http://cache.freescale.com/files/microcontrollers/doc/ref_manual/TIM08RM.pdf?fsrch=1&sr=1

 

 

Thanks for your help and best regards. 

0 Kudos

1,604 Views
bigmac
Specialist III

Hello,

 

While the reference manual cited may provide general timing information, it actually refers to a TIM module associated with earlier HC908 devices, rather than the TPM module.  There are significant differences between the two module types, but maybe to a lesser extent with input capture operation.  The setup of the registers will be different for each timer type.

 

Peter,

The "interrupt" of the RS08 can wakeup from wait mode, but that is all.  The global flags register may simplify polling, but nothing will happen automatically, and the program flow is always within the main loop.  This is because there is no stack within the device.  The nesting of sub-routines also requires special coding.

 

It reminds me of the limitiations of the very first PICs about twenty years ago.

 

Regards,

Mac

0 Kudos

1,604 Views
PW_CTL
Contributor III

Hi, 

 

Finally I finish the decoder, measuring the time with the input capture ot the TPM module. The accuracy is good in this way.

 

Thank you very much for your help.

0 Kudos

1,604 Views
PeterHouse
Contributor I

Please share how you accomplished your task.

 

Peter

0 Kudos

1,604 Views
PeterHouse
Contributor I

Here is some example IR code I use.  It is intended for decoding Zenith IR remote codes.  I have used this same structure for decoding different IR and radio remote control codes including some PPM type codes. 

 

The routine IR_Check must be called repeatedly from your main loop.  The main processing takes place at the interrupt level in the routine IR_Int and IR_TOF.  IR_Init must be called first to initialize the Timer module.  It is reasonably well commented.

 

Good Luck,

 

Peter House

0 Kudos