Page 1 of 1

RMT Implmentation - HELP!!!

Posted: Mon Dec 02, 2019 5:20 pm
by fabltd
Hello

I am trying to work out the RMT example here:

https://github.com/espressif/arduino-es ... eadXJT.ino

The comments say:

// ; 0 bit = 6us low/10us high
// ; 1 bit = 14us low/10us high

I assume this line checks for a valid transmission:

#define XJT_VALID(i) (i->level0 && !i->level1 && i->duration0 >= 8 && i->duration0 <= 11)

What does the 8 and 11 refer to ?

What is level 0 and level 1.

Its very hard to implement this with no documentation.

The SDK docs don't match the Arduino implementation.

Please help.....

I have spent a day and I am getting nowhere.

Thanks

JT

Re: RMT Implmentation - HELP!!!

Posted: Wed Dec 04, 2019 10:34 pm
by tommeyers
I went looking for examples of rmt and arduino (google esp32 arduino rmt example)

There seems to be a lot written about that.

Can you narrow down what you need that is not addressed in the above or in https://docs.espressif.com/projects/esp ... s/rmt.html

Tom Meyers

Re: RMT Implmentation - HELP!!!

Posted: Thu Dec 05, 2019 12:23 am
by CollinK
fabltd wrote:
Mon Dec 02, 2019 5:20 pm
I assume this line checks for a valid transmission:

#define XJT_VALID(i) (i->level0 && !i->level1 && i->duration0 >= 8 && i->duration0 <= 11)

What does the 8 and 11 refer to ?

What is level 0 and level 1.
Yeah, the documentation can be a bit sparse at times. Did you look at the ESP32 Technical Manual? It does cover the way the underlying hardware works. That's helpful info to understand. But, I can pretty completely explain the whole way that reception works. You seem to be interested in reception given that you were asking about those lines so here it goes:

You set up the RMT hardware on a specific pin (rmtInit) with a specific amount of storage space. Whatever you ask for you get twice as many samples because two are stored per 32 bit integer. The first one is called 0, the second 1. So, level0 refers to the first sample in the 32 bit integer, level1 is the second sample. After setting up the pin you need to tell it the granularity for signal capture. That's rmtSetTick. You specify how many nano seconds each sample period should take. Let's say that you give it a value of 100 for the timing. That means that what the RMT reception hardware is doing is checking the state of the pin every 100 nanoseconds. As long as the pin state stays the same as it was before we just keep adding to a counter. When the signal state changes the previous state is saved along with the count of how many periods it was in that state for. Remember I said there are two samples per 32 bit integer. So, if you ask for a 64 position RMT buffer you have 128 samples. Each sample is a one bit value specifying whether that sample was HIGH or LOW (logic 1 or 0). Then there are 15 bits that specify how long the signal held that level for. This sets an upper limit for how long of a duration you can capture.

Follow so far? Whatever state the pin was in when you started is considered "idle". So, you can idle either high or low. Let's say you idle low. Let's also say you set the interval to 100ns and you are inputting a square wave with 500ns on/off time. So, the initial state is idle and nothing happens until you input the square wave. Now, the pin goes high for the first wave. The hardware detects this and starts counting. There is no telling whether your Squarewave generator is sync'd to the RMT hardware but let's assume they are in perfect lock step. So, the RMT hardware detects 5 periods where the signal is high. Then, at the 6th sampling point it sees that the signal is now low so it saves a sample that says "HIGH, 5 periods" and starts counting the low time. That goes on for 5 periods and then the signal goes high. So it saves "LOW, 5 periods". This now fills the first 32 bit buffer entry so level0 is 1 because the first captured signal state was high. And, duration0 is 5 because that state happened for 5 periods of the clock we set up. level1 is 0 because the second signal state we captured was low. And, duration1 is 5 because it also happened for 5 periods. You won't get any of that, though, until the signal state goes back to idle for the set time. I think it defaults to something like 100 or 200 sample times. You can set the timeout with rmtSetRxThreshold. This means you can capture longer pulses of the "active" state than you probably can as the "idle" state since going over the threshold in the idle state doesn't record a duration but rather terminates capture and causes a hardware interrupt so you can process the data.

So, let's say you capture 4 periods of the squarewave then stop and it was not synchronized perfectly to the RMT hardware. It might look like this:
Level 0 Duration0 Level1 Duration1
1 4 0 5
1 5 0 5
1 4 0 4
1 5 0 5

Note that because the idle state was low the first captured level will always be 1 because it takes a high pulse to wake it up. And, you will pretty much always alternate between 1 and 0 as the signal state because you're counting up each state and only going to a new state when the pin changes state. And, note that the timing was fluctuating between 4 and 5. That's because you are very rarely going to be perfectly sync'd to the other side so it's very common for the # of pulses captured to jitter a bit. So, generally the data processing you are doing has to have some leeway in the numbers. If you expect a pulse to be 5 in duration then accept it if it is 4, 5, or 6 long.

Hopefully that helps to clarify what is going on and helps you to understand how to use it for your own application.