RMT ISR Trigger?

ixs0792
Posts: 6
Joined: Wed Feb 26, 2020 10:05 pm

RMT ISR Trigger?

Postby ixs0792 » Wed Feb 26, 2020 10:22 pm

Can the RMT ISR be triggered after one data bit is complete?

I am working with a MTS Transducer (http://www.mtssensors.com/fileadmin/med ... DPulse.pdf) with a "Start/Stop" interface. This works by the host (a ESP32-WROOM-32 module) generates a start pulse, and then the transducer returns two pulse with a spacing based on the magnet linear distance (9.1us/in).

Start: _____|----|_______________________
Stop: ________|----|_____..._____|----|___

Once the Stop cycle is complete another Start pulse needs to be generated. I am trying to minimize this time between the stop pulse and the next start pulse.

This code "works" but the ISR waits for the idle_threshold to timeout before calling the rmt_isr_handler. Is it possible to have the ISR triggered as the rising edge of the stop bit occurs?

Code: Select all

#include "arduino.h"
#include "driver/rmt.h"


#define MTS_STARTP 14 
#define MTS_STOPP 32 

#define DEGBUG_PIN 15 

float gradient = 9.1049; //us/in

rmt_config_t rmt_tx;
rmt_config_t rmt_rx;
static const rmt_item32_t START_PULSE[] = {160, 1, 0, 0};
rmt_isr_handle_t xHandler = NULL; 


void IRAM_ATTR rmt_isr_handler(void* arg){
  digitalWrite(DEGBUG_PIN, HIGH); 
  //read RMT interrupt status.
  uint32_t intr_st = RMT.int_st.val;

  RMT.conf_ch[rmt_rx.channel].conf1.rx_en = 0;
  RMT.conf_ch[rmt_rx.channel].conf1.mem_owner = RMT_MEM_OWNER_TX;
  volatile rmt_item32_t* item = RMTMEM.chan[0].data32;
  
  if (item){          
    char buff[100]; 
    float distance = ((item)->duration1) * 0.0125 / gradient;
    snprintf (buff, sizeof(buff), "%.5f\"", distance); 
    Serial.println(buff); 
  }
  
  RMT.conf_ch[rmt_rx.channel].conf1.mem_wr_rst = 1;
  RMT.conf_ch[rmt_rx.channel].conf1.mem_owner = RMT_MEM_OWNER_RX;
  RMT.conf_ch[rmt_rx.channel].conf1.rx_en = 1;

  //clear RMT interrupt status.
  RMT.int_clr.val = intr_st;

  // start next interogation pulse
  rmt_tx_start(rmt_tx.channel, true);
  digitalWrite(DEGBUG_PIN, LOW);   
}

void setup(){
  Serial.begin(115200);   
  Serial.println();
  Serial.println("Start Program");  
  
  pinMode(DEGBUG_PIN, OUTPUT); 
  
  // Setup TX RMT Output
  rmt_tx.channel = RMT_CHANNEL_1;
  rmt_tx.gpio_num = (gpio_num_t) MTS_STARTP;
  rmt_tx.mem_block_num = 1;
  rmt_tx.clk_div = 1;
  rmt_tx.tx_config.loop_en = false;
  rmt_tx.tx_config.carrier_en = false;
  rmt_tx.tx_config.idle_level = (rmt_idle_level_t) 0;
  rmt_tx.tx_config.idle_output_en = true;
  rmt_tx.rmt_mode = RMT_MODE_TX;
  rmt_config(&rmt_tx);

  //load output buffer to interogation pulse
  rmt_fill_tx_items(rmt_tx.channel, START_PULSE, 1, 0);

  // Setup RX RMT Input
  rmt_rx.channel = RMT_CHANNEL_0;
  rmt_rx.gpio_num = (gpio_num_t) MTS_STOPP;
  rmt_rx.clk_div = 1;
  rmt_rx.mem_block_num = 2;
  rmt_rx.rmt_mode = RMT_MODE_RX;
  rmt_rx.rx_config.filter_en = false;
  rmt_rx.rx_config.idle_threshold = 0x7FFF; 
  rmt_config(&rmt_rx);
  
  //enable RX interupt
  rmt_set_rx_intr_en(rmt_rx.channel,true);
  rmt_isr_register(rmt_isr_handler, NULL, ESP_INTR_FLAG_LEVEL1, &xHandler);

  //start listening
  rmt_rx_start(rmt_rx.channel, false);

  //send the first interogation pulse
  rmt_tx_start(rmt_tx.channel, true);
}

void loop(){
}

ixs0792
Posts: 6
Joined: Wed Feb 26, 2020 10:05 pm

Re: RMT ISR Trigger?

Postby ixs0792 » Thu Feb 27, 2020 4:25 pm

I figured out a solution.

The MTS transducer was reconfigured to a PWM output:
Start = __|----|____________________|----|___...
PWM = ____|--------------...---------|_____|-------...

Then used a GPIO interrupt on the falling edge of the PWM signal to retrigger the RMT TX signal, and used the rising edge of the PWM to read the previous RMT RX duration.

This seems to be working for now...

Who is online

Users browsing this forum: Majestic-12 [Bot], Polarbear17123 and 103 guests