/* ESP32 reading PWM RC signals 8 CH.
Based on the code for ATmega 328: https://github.com/TheDIYGuy999/Rc_Engine_Sound
modified for boat by croky_b for boat
* ***** ESP32 CPU frequency must be set to 240MHz! *****
*/
#include "driver/rmt.h"
//
// =======================================================================================================
// PIN ASSIGNMENTS & GLOBAL VARIABLES (Do not play around here)
// =======================================================================================================
//
// Pin assignment and wiring instructions
// ------------------------------------------------------------------------------------
// Use a 330Ohm resistor in series with all I/O pins! allows to drive LED directly and
// provides short circuit protection.
// ------------------------------------------------------------------------------------
#define RMT_TICK_PER_US 1
// determines how many clock cycles one "tick" is
// [1..255], source is generally 80MHz APB clk
#define RMT_RX_CLK_DIV (80000000/RMT_TICK_PER_US/1000000)
// time before receiver goes idle
#define RMT_RX_MAX_US 3500
#define RECEIVER_CHANNELS_NUM 8
const uint8_t RECEIVER_CHANNELS[RECEIVER_CHANNELS_NUM] = {0, 1, 2, 3, 4, 5, 6, 7 };
const uint8_t RECEIVER_PINS[RECEIVER_CHANNELS_NUM] = {13, 12, 14, 27, 33, 35, 39, 34 };
uint32_t pulseWidth[7]; // Current RC signal pulse width
//
// =======================================================================================================
// RMT
// =======================================================================================================
//
// Reference https://esp-idf.readthedocs.io/en/v1.0/api/rmt.html
static void IRAM_ATTR rmt_isr_handler(void* arg) {
uint32_t intr_st = RMT.int_st.val;
uint8_t i;
for (i = 0; i < RECEIVER_CHANNELS_NUM; i++) {
uint8_t channel = RECEIVER_CHANNELS[i];
uint32_t channel_mask = BIT(channel * 3 + 1);
if (!(intr_st & channel_mask)) continue;
RMT.conf_ch[channel].conf1.rx_en = 0;
RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_TX;
volatile rmt_item32_t* item = RMTMEM.chan[channel].data32;
if (item) {
pulseWidth[i] = item->duration0;
}
RMT.conf_ch[channel].conf1.mem_wr_rst = 1;
RMT.conf_ch[channel].conf1.mem_owner = RMT_MEM_OWNER_RX;
RMT.conf_ch[channel].conf1.rx_en = 1;
//clear RMT interrupt status.
RMT.int_clr.val = channel_mask;
}
}
//
// =======================================================================================================
// MAIN ARDUINO SETUP (1x during startup)
// =======================================================================================================
//
void setup()
{
//{13,12,14,27,33,35,34,39 };
pinMode(13, INPUT_PULLDOWN);
pinMode(12, INPUT_PULLDOWN);
pinMode(14, INPUT_PULLDOWN);
pinMode(27, INPUT_PULLDOWN);
pinMode(33, INPUT_PULLDOWN);
pinMode(35, INPUT_PULLDOWN);
pinMode(34, INPUT_PULLDOWN);
pinMode(39, INPUT_PULLDOWN);
// Communication setup --------------------------------------------
Serial.begin(115200); // USB serial (for DEBUG)
// PWM ----
// New: PWM read setup, using rmt
uint8_t i;
rmt_config_t rmt_channels[RECEIVER_CHANNELS_NUM] = {};
for (i = 0; i < RECEIVER_CHANNELS_NUM; i++) {
rmt_channels[i].channel = (rmt_channel_t) RECEIVER_CHANNELS[i];
rmt_channels[i].gpio_num = (gpio_num_t) RECEIVER_PINS[i];
rmt_channels[i].clk_div = RMT_RX_CLK_DIV;
rmt_channels[i].mem_block_num = 1;
rmt_channels[i].rmt_mode = RMT_MODE_RX;
rmt_channels[i].rx_config.filter_en = true;
rmt_channels[i].rx_config.filter_ticks_thresh = 100; // Pulses shorter than this will be filtered out
rmt_channels[i].rx_config.idle_threshold = RMT_RX_MAX_US * RMT_TICK_PER_US;
rmt_config(&rmt_channels[i]);
rmt_set_rx_intr_en(rmt_channels[i].channel, true);
rmt_rx_start(rmt_channels[i].channel, 1);
}
rmt_isr_register(rmt_isr_handler, NULL, 0, NULL); // This is our interrupt
// wait for RC receiver to initialize
while (millis() <= 3000) ;
}
// =======================================================================================================
// READ PWM RC SIGNALS
// =======================================================================================================
// CH1=[0] CH2= [1] CH3=[2] CH4=[3] CH5=[4] CH6=[5] CH7=[6] CH8=[7]
void readRcSignals()
{
delay(500);
Serial.print("CH1 :");
Serial.println(pulseWidth[0]);
Serial.println("");
Serial.print("\CH2 :");
Serial.println(pulseWidth[1]);
Serial.println("");
Serial.print("CH3 :");
Serial.println(pulseWidth[2]);
Serial.println("");
Serial.print("CH4 :");
Serial.println(pulseWidth[3]);
Serial.println("");
Serial.print("CH5 :");
Serial.println(pulseWidth[4]);
Serial.println("");
Serial.print("CH6 :");
Serial.println(pulseWidth[5]);
Serial.println("");
Serial.print("CH7 :");
Serial.println(pulseWidth[6]);
Serial.println("");
Serial.print("CH8 :");
Serial.println(pulseWidth[7]);
}
//
// =======================================================================================================
// MAIN LOOP
// =======================================================================================================
//
void loop()
{
readRcSignals();
}
|