In the meantime I created a small user interface with a rotating push button encoder and OLED display "Feather OLED 128x32" to config 4 channels with 4 pulses. But this needs still some debugging, the code is not so tidy.
The delay is still there but I did improve the jitter by using the correct core.
Code: Select all
// Reaction time with ESP32 THING PLUS is about 2.5us for a PIN Interrupt
// With RMT we can have 8 channels with as example pulse resolution of 100ns longest pulse is
// The RMT channels have a delay / jitter of about 100ns
// Reference https://esp-idf.readthedocs.io/en/v1.0/api/rmt.html
//
// ESP32 Thing Plus WROOM
//
// PINOUT LEFT Side
// 23 SDA for OLED as I2C
// 22 SCL for OLED as I2C
// 14 OLED Button C
// 32 OLED Button B
// 15 OLED Button A
// 33 RMT_CHD
// 27 RMT_CHC
// 12 RMT_CHB
// 13 RMT_CHA
// VUSB
// EN
// VBAT
//
// JST LiPO
//
// Qwiic Con.
// ***********************************
// PINOUT RIGHT Side
// 21 Interrupt Toggel pin 4
// 17 ENCODER A
// 16 ENCODER B
// 19 PWM Generator Output (connect to 21 Interrupt Toggle pin)
// 18
// 5
// A5
// A4
// A3
// A2
// A1
// A0
// GND
// NC
// 3V3
// RESET
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <driver/rmt.h>
#include <ESP32Encoder.h>
ESP32Encoder encoder;
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);
TaskHandle_t Task1;
TaskHandle_t Task2;
// Display variable
int32_t jog_val = 0;
int32_t Set_Val = 0;
int32_t Set_Val_old = 0;
float Act_val;
float Act_val_old;
// Channel parameter is at the beginning so position cursor at 16
int Set_X_pos = 16;
int Set_X_pos_old = 16;
int Param_line_y = 3;
int Param_line_y_old = 3;
int Channel = 0;
int Channel_old = 0;
const int Menu_lenght = 14;
char line[Menu_lenght][22] ={"PULSE GEN V1 by R.L. ",
"CHAN : 0 ",
" ",
"CHAN : 0.0 ",
"Delay: 0.0 us ",
"PulH1: 0.0 us ",
"PulL1: 0.0 us ",
"PulH2: 0.0 us ",
"PulL2: 0.0 us ",
"PulH3: 0.0 us ",
"PulL3: 0.0 us ",
"PulH4: 0.0 us ",
"PulL4: 0.0 us ",
"PGen : 10.0 Hz "};
struct Pulse_Pattern {
int del;
int pulse_del_L;
int pulseH1;
int pulseH1_L;
int pulseL1;
int pulseL1_L;
int pulseH2;
int pulseH2_L;
int pulseL2;
int pulseL2_L;
int pulseH3;
int pulseH3_L;
int pulseL3;
int pulseL3_L;
int pulseH4;
int pulseH4_L;
int pulseL4;
int pulseL4_L;
};
// Timing in x of 100ns
Pulse_Pattern PULS[4] = {{50,1,23,0,32,1,40,0,50,1,00,0,00,1,00,0,00},
{60,1,35,0,32,1,40,0,50,1,00,0,00,1,00,0,00},
{70,1,30,0,32,1,40,0,50,1,00,0,00,1,00,0,00},
{80,1,40,0,32,1,40,0,50,1,00,0,00,1,00,0,00}};
//
static portMUX_TYPE my_mutex;
//gpio_num_t pin21 = (gpio_num_t)(21 & 0x1F);
//gpio_num_t pin4 = (gpio_num_t)(4 & 0x1F);
int state=0;
uint32_t numberPinHigh;
// use first channel of 16 channels (started from zero)
#define LEDC_CHANNEL_0 0
// use 13 bit precission for LEDC timer
#define LEDC_TIMER_13_BIT 13
// use 5000 Hz as a LEDC base frequency
int LEDC_BASE_FREQ = 10;
int LEDC_BASE_FREQ_old = 10;
int brightness = 1; // how bright the LED is
struct Button {
const uint8_t PIN;
uint32_t numberKeyPresses;
bool pressed;
};
Button Trig1 = {18, 0, false}; // GPIO 12 is Input Trigger pin.
//int OUT_PIN = 4;
// fade LED PIN (replace with LED_BUILTIN constant for built-in LED)
#define Master_Gen_PIN 19
#define BUTTON_A 15
#define BUTTON_B 32
#define BUTTON_C 14
#define RMT_CHA GPIO_NUM_13
#define RMT_CHB GPIO_NUM_12
#define RMT_CHC GPIO_NUM_27
#define RMT_CHD GPIO_NUM_33
rmt_config_t configA;
rmt_item32_t itemsA[5];
rmt_config_t configB;
rmt_item32_t itemsB[5];
rmt_config_t configC;
rmt_item32_t itemsC[5];
rmt_config_t configD;
rmt_item32_t itemsD[5];
// Arduino like analogWrite
// value has to be between 0 and valueMax
void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) {
// calculate duty, 8191 from 2 ^ 13 - 1
uint32_t duty = (8191 / valueMax) * min(value, valueMax);
// write duty to LEDC
ledcWrite(channel, duty);
}
// Interrupt routine when RMT to start
void IRAM_ATTR isr() {
portENTER_CRITICAL(&my_mutex);
//timing sensitive stuff
REG_SET_BIT(RMT_CH0CONF1_REG, RMT_TX_START_CH0);
REG_SET_BIT(RMT_CH1CONF1_REG, RMT_TX_START_CH1);
REG_SET_BIT(RMT_CH2CONF1_REG, RMT_TX_START_CH2);
REG_SET_BIT(RMT_CH3CONF1_REG, RMT_TX_START_CH3);
portEXIT_CRITICAL(&my_mutex);
Trig1.numberKeyPresses += 1;
Trig1.pressed = true;
}
// Interrupt routine for fast GPIO changes
void IRAM_ATTR isr1() {
GPIO.out_w1ts = 0b10000; // Toggle PIN 4
GPIO.out_w1tc = 0b10000;
}
void setup() {
Serial.begin(115200);
// Enable the weak pull up resistors
ESP32Encoder::useInternalWeakPullResistors=UP;
// use pin 17 and 16 for the second encoder
encoder.attachSingleEdge(17, 16);
encoder.setFilter(1023);
Serial.println("Encoder Start = " + String((int32_t)encoder.getCount()));
// set starting count value after attaching
encoder.setCount(Set_X_pos);
// clear the encoder's raw count and set the tracked count to zero
// encoder.clearCount();
Serial.println("OLED FeatherWing test");
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32
Serial.println("OLED begun");
UI_clear();
Serial.println("IO test");
pinMode(BUTTON_A, INPUT_PULLUP); //15
pinMode(BUTTON_B, INPUT); //32
pinMode(BUTTON_C, INPUT_PULLUP); //14
pinMode(Trig1.PIN, INPUT_PULLUP); // When no signal is applied, it will be at a voltage level of VCC instead of floating, avoiding the detection of non existing external interrupts.
pinMode(RMT_CHA, INPUT_PULLUP); // RMT Channel0 A
pinMode(RMT_CHB, INPUT_PULLUP); // RMT Channel1 B
pinMode(RMT_CHC, INPUT_PULLUP); // RMT Channel2 C
pinMode(RMT_CHD, INPUT_PULLUP); // RMT Channel3 D
pinMode(GPIO_NUM_21, INPUT); // Connected to 18
pinMode(GPIO_NUM_2, OUTPUT);
//pinMode(GPIO_NUM_4, OUTPUT);
//disableCore0WDT();
disableCore1WDT();
vPortCPUInitializeMutex(&my_mutex);
attachInterrupt(Trig1.PIN, isr, RISING); // FALLING RISING LOW HIGH CHANGE
//attachInterrupt(21, isr1, RISING);
//create a task that will be executed in the Task1code() function, with priority 1 and executed on core 1
xTaskCreatePinnedToCore(
Task_core0, /* Task function. */
"Task_core0", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task1, /* Task handle to keep track of created task */
1); /* pin task to core 0 */
delay(500);
// Setup timer and attach timer to a led pin
ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT);
ledcAttachPin(Master_Gen_PIN, LEDC_CHANNEL_0);
RMT_Init();
Fill_pulse_pattern();
// set the brightness on LEDC channel 0
ledcAnalogWrite(LEDC_CHANNEL_0, brightness); // PWM with duty of 1 from 255
UI_Init();
}
void PWM_init()
{
// Setup timer and attach timer to a led pin
ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT);
//ledcAttachPin(Master_Gen_PIN, LEDC_CHANNEL_0);
}
//Task1code: blinks an LED every 1000 ms
void Task_core0( void * pvParameters ){
for(;;){
//Serial.print("Task_Core0 runs on Core ");
//Serial.println(xPortGetCoreID());
vTaskDelay(100 / portTICK_PERIOD_MS);
int time3 = millis();
UI_update();
//Serial.println(millis()-time3);
yield();
}
}
void loop() {
// This loop Taks runs on core 1
//GPIO.out_w1ts = 0b10000; // Toggle PIN 4
//GPIO.out_w1tc = 0b10000;
}
The code for the user interface File UI_Interface
Code: Select all
// Display 128 x 64
// Line 1 0,0
// Line 2 16,0
int edit_from = 6;
int edit_to = 16;
int32_t jog_from = 6;
int32_t jog_to = 16;
int Char_num = 48;
boolean forceUpdate = false;
boolean Edit = false;
boolean Edit_old = false;
void UI_Init()
{
// text display tests
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,0);
display.println(line[0]);
display.println(line[1]);
display.println(line[2]);
//updateParameter(false);
for (Channel = 3 ;Channel>=0;Channel--)
{
for (Param_line_y = 3 ;Param_line_y<11;Param_line_y++)
{
//Serial.println(Param_line_y);
updateParameter(true);
}
}
Param_line_y = 3;
updateParameter(true);
Serial.println("Loaded");
display.println(line[Param_line_y]);
delay(2000);
display.display(); // actually display all of the above
}
void UI_clear()
{
display.clearDisplay();
display.display(); // actually display all of the above
}
void setParam(float val1)
{
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf(val1, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
}
void setParamI(int val1)
{
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf((float)val1, 9, 0, line[Param_line_y]+8); // Leave room for too large numbers!
}
void loadALLParameter()
{
}
void updateParameter(boolean load)
{
switch (Param_line_y) {
case 3: //Channel
if (load==true)
{
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf((float)Channel, 9, 0, line[Param_line_y]+8); // Leave room for too large numbers!
Serial.print("Channel: ");
Serial.println(Channel);
}
else
{
Act_val = constrain(atoi(line[Param_line_y]+6),0,3);
Channel = Act_val;
//setParamI(Channel);
//strncpy(line[Param_line_y]+6, " ", 6);
//dtostrf((float)val1, 9, 0, line[Param_line_y]+8); // Leave room for too large numbers!
strncpy(line[Param_line_y]+6, " ", 12);
dtostrf((float)Act_val, 9, 0, line[Param_line_y]+8); // Leave room for too large numbers!
strncpy(line[1], "CHAN : ", 20);
dtostrf(Act_val, 1, 0, line[1]+8); // Leave room for too large numbers!
}
break;
case 4: // Delay
if (load==true)
{
strncpy(line[Param_line_y]+6, " ", 6);
Act_val = constrain(PULS[Channel].del,0,32767);
dtostrf(Act_val*0.1, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
Serial.print("PULS[x].del: ");
Serial.println(PULS[Channel].del);
}
else
{
Act_val = atof(line[Param_line_y]+6);
PULS[Channel].del = constrain((Act_val *10),0,32767);
setParam(0.1*(float)PULS[Channel].del);
Act_val = atof(line[Param_line_y]+6);
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf(Act_val, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
}
if(Act_val>0)
{
PULS[Channel].pulse_del_L = 0 ;
}
else
{
PULS[Channel].pulse_del_L = 0 ;
}
break;
case 5: // H1
if (load==true)
{
strncpy(line[Param_line_y]+6, " ", 6);
Act_val = constrain(PULS[Channel].pulseH1,0,32767);
dtostrf(Act_val*0.1, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
Serial.print("PULS[x].pulseH1: ");
Serial.println(PULS[Channel].pulseH1);
}
else
{
Act_val = atof(line[Param_line_y]+6);
PULS[Channel].pulseH1 = constrain((Act_val *10),0,32767);
setParam(0.1*(float)PULS[Channel].pulseH1);
Act_val = atof(line[Param_line_y]+6);
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf(Act_val, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
if(Act_val>0)
{
PULS[Channel].pulseH1_L = 1 ;
}
else
{
PULS[Channel].pulseH1_L = 0 ;
}
}
break;
case 6: // L1
if (load==true)
{
strncpy(line[Param_line_y]+6, " ", 6);
Act_val = constrain(PULS[Channel].pulseL1,0,32767);
dtostrf(Act_val*0.1, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
Serial.print("PULS[x].pulseL1: ");
Serial.println(PULS[Channel].pulseL1);
}
else
{
Act_val = atof(line[Param_line_y]+6);
PULS[Channel].pulseL1 = constrain((Act_val *10),0,32767);
setParam(0.1*(float)PULS[Channel].pulseL1);
Act_val = atof(line[Param_line_y]+6);
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf(Act_val, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
}
if(Act_val>0)
{
PULS[Channel].pulseL1_L = 0 ;
}
else
{
PULS[Channel].pulseL1_L = 0 ;
}
break;
case 7: // H2
if (load==true)
{
strncpy(line[Param_line_y]+6, " ", 6);
Act_val = constrain(PULS[Channel].pulseH2,0,32767);
dtostrf(Act_val *0.1, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
Serial.print("PULS[x].pulseH2: ");
Serial.println(PULS[Channel].pulseH2);
}
else
{
Act_val = atof(line[Param_line_y]+6);
PULS[Channel].pulseH2 = constrain((Act_val *10),0,32767);
setParam(0.1*(float)PULS[Channel].pulseH2);
Act_val = atof(line[Param_line_y]+6);
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf(Act_val, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
}
if(Act_val>0)
{
PULS[Channel].pulseH2_L = 1 ;
}
else
{
PULS[Channel].pulseH2_L = 0 ;
}
break;
case 8: // L2
if (load==true)
{
strncpy(line[Param_line_y]+6, " ", 6);
Act_val = constrain(PULS[Channel].pulseL2,0,32767);
dtostrf(Act_val *0.1, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
Serial.print("PULS[x].pulseL2: ");
Serial.println(PULS[Channel].pulseL2);
}
else
{
Act_val = atof(line[Param_line_y]+6);
PULS[Channel].pulseL2 = constrain((Act_val *10),0,32767);
setParam(0.1*(float)PULS[Channel].pulseL2);
Act_val = atof(line[Param_line_y]+6);
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf(Act_val, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
}
if(Act_val>0)
{
PULS[Channel].pulseL2_L = 0 ;
}
else
{
PULS[Channel].pulseL2_L = 0 ;
}
break;
case 9: // H3
if (load==true)
{
strncpy(line[Param_line_y]+6, " ", 6);
Act_val = constrain(PULS[Channel].pulseH3,0,32767);
dtostrf(Act_val*0.1, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
Serial.print("PULS[x].pulseH3: ");
Serial.println(PULS[Channel].pulseH3);
}
else
{
Act_val = atof(line[Param_line_y]+6);
PULS[Channel].pulseH3 = constrain((Act_val *10),0,32767);
setParam(0.1*(float)PULS[Channel].pulseH3);
Act_val = atof(line[Param_line_y]+6);
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf(Act_val, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
}
if(Act_val>0)
{
PULS[Channel].pulseH3_L = 1 ;
}
else
{
PULS[Channel].pulseH3_L = 0 ;
}
break;
case 10: // L3
if (load==true)
{
strncpy(line[Param_line_y]+6, " ", 6);
Act_val = constrain(PULS[Channel].pulseL3,0,32767);
dtostrf(Act_val*0.1, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
Serial.print("PULS[x].pulseL3: ");
Serial.println(PULS[Channel].pulseL3);
}
else
{
Act_val = atof(line[Param_line_y]+6);
PULS[Channel].pulseL3 = constrain((Act_val *10),0,32767);
setParam(0.1*(float)PULS[Channel].pulseL3);
Act_val = atof(line[Param_line_y]+6);
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf(Act_val, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
}
if(Act_val>0)
{
PULS[Channel].pulseL3_L = 0 ;
}
else
{
PULS[Channel].pulseL3_L = 0 ;
}
break;
case 13:
if (load==true)
{
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf(LEDC_BASE_FREQ, 9, 1, line[Param_line_y]+8); // Leave room for too large numbers!
Serial.print("LEDC_BASE_FREQ: ");
Serial.println(LEDC_BASE_FREQ);
}
else
{
Act_val = atoi(line[Param_line_y]+6);
LEDC_BASE_FREQ = Act_val;
setParamI(LEDC_BASE_FREQ);
Act_val = atof(line[Param_line_y]+6);
strncpy(line[Param_line_y]+6, " ", 6);
dtostrf(Act_val, 9, 0, line[Param_line_y]+8); // Leave room for too large numbers!
Serial.print("LEDC_BASE_FREQ");
Serial.println(LEDC_BASE_FREQ);
}
break;
default:
break;
}
//Serial.println(Param_line_y);
}
void Incr()
{
float rat;
Act_val = atof(line[Param_line_y]+8);
if (Set_X_pos== 16)
{
rat = pow(10,16-Set_X_pos);
}
else
{
rat = pow(10,15-Set_X_pos);
}
Act_val = constrain(Act_val + (float)rat,0,32767);
//Serial.println(rat);
setParam(Act_val);
}
void Decr()
{
float rat;
Act_val = atof(line[Param_line_y]+8);
if (Set_X_pos== 16)
{
rat = pow(10,16-Set_X_pos);
}
else
{
rat = pow(10,15-Set_X_pos);
}
Act_val = constrain(Act_val - (float)rat,0,32767);
//Serial.println(rat);
setParam(Act_val);
}
void UI_update()
{
jog_val = constrain(encoder.getCount(),jog_from-1,jog_to+1);
Set_Val = constrain(jog_val,jog_from,jog_to);
encoder.setCount(Set_Val);
if (Edit==true)
{
if (Set_Val==47)
{
line[Param_line_y][Set_X_pos] = (char)46;
}
else
{
line[Param_line_y][Set_X_pos] = (char)Set_Val;
forceUpdate==true;
}
if (jog_val > Set_Val)
{
Incr();
forceUpdate = true;
line[Param_line_y][Set_X_pos] = (char)48;
Set_Val = 48;
encoder.setCount(Set_Val);
}
if (jog_val < Set_Val and not Act_val <=0)
{
Decr();
forceUpdate = true;
line[Param_line_y][Set_X_pos] = (char)57;
Set_Val = 57;
encoder.setCount(Set_Val);
}
//Serial.println("Encoder count = " + String(Set_Val));
}
else
{
Set_X_pos = constrain(Set_Val ,edit_from,edit_to);
}
updateParameter(false);
// Check Buttons
if(!digitalRead(BUTTON_A))
{
if (Edit==true)
{
UI_edit(); // Leave Edit mode
Edit_old=true;
}
Param_line_y = constrain(Param_line_y-1,3,Menu_lenght-1);
if (Param_line_y==3)
{
Set_X_pos = 16;
Set_X_pos_old = 16;
encoder.setCount(16);
//Serial.println("Test 16");
}
else
{
Set_X_pos = 14;
Set_X_pos_old = 14;
encoder.setCount(14);
//Serial.println("Test 14");
}
updateParameter(true);
delay(200);
if (Edit_old==true) UI_edit(); // Go back to old Edit mode
}
if(!digitalRead(BUTTON_B) )
{
UI_edit();
delay(200);
}
if(!digitalRead(BUTTON_C))
{
if (Edit==true)
{
UI_edit(); // Leave Edit mode
Edit_old=true;
}
Param_line_y = constrain(Param_line_y+1,3,Menu_lenght-1);
if (Param_line_y==3)
{
Set_X_pos = 16;
Set_X_pos_old = 16;
encoder.setCount(16);
//Serial.println("Test 16");
}
else
{
Set_X_pos = 14;
Set_X_pos_old = 14;
encoder.setCount(14);
//Serial.println("Test 14");
}
updateParameter(true);
delay(200);
if (Edit_old==true) UI_edit(); // Go back to old Edit mode
}
if (Set_Val_old != Set_Val or Param_line_y != Param_line_y_old or Channel != Channel_old or forceUpdate==true)
{
UI_Main_update();
Fill_pulse_pattern();
//forceUpdate = false;
}
if (LEDC_BASE_FREQ_old != LEDC_BASE_FREQ)
{
PWM_init();
}
// Store actual params
Param_line_y_old = Param_line_y;
Channel_old = Channel;
Set_Val_old = Set_Val;
Set_X_pos_old = Set_X_pos;
Edit_old = Edit;
}
void UI_edit()
{
//display.setTextSize(1);
//display.setTextColor(SSD1306_WHITE,SSD1306_BLACK);
int Char_num = line[Param_line_y][Set_X_pos];
//Serial.println(Char_num);
if (Edit == false and Set_Val != 15 and Char_num!=32)
{
strncpy(line[2],"EDIT ", 22);
Edit = true;
encoder.setCount(Char_num);
jog_from = 48;
jog_to = 57;
}
else
{
strncpy(line[2]," ", 22);
Edit = false;
encoder.setCount(Set_X_pos);
jog_from = 6;
jog_to = 16;
}
//Serial.println(Set_X_pos);
//display.display(); // actually display all of the above
}
void UI_Main_update()
{
//Serial.println(Param_line_y);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE,SSD1306_BLACK);
display.setCursor(0,0*8);
display.println(line[0]);
display.println(line[1]);
display.println(line[2]);
display.println(line[Param_line_y]);
display.display(); // actually display all of the above
showCursor();
}
void showCursor()
{
display.setCursor(Set_X_pos_old*6,3*8);
display.print(line[Param_line_y_old][Set_X_pos_old]);
display.setTextColor(SSD1306_BLACK,SSD1306_WHITE);
display.setCursor(Set_X_pos*6,3*8);
display.print(line[Param_line_y][Set_X_pos]);
display.display(); // actually display all of the above
}
and of course the code for the RMT File name RMT_Gen
Code: Select all
void RMT_Init()
{
// Channel A put your setup code here, to run once:
configA.rmt_mode = RMT_MODE_TX;
configA.channel = RMT_CHANNEL_0;
configA.gpio_num = GPIO_NUM_13; // RMT_CHA;
configA.mem_block_num = 1;
configA.tx_config.loop_en = 0;
configA.tx_config.carrier_en = 0;
configA.tx_config.idle_output_en = 1;
configA.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
configA.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH;
configA.clk_div = 8; // 80MHx / 80 = 1MHz 0r 1uS per count
rmt_config(&configA);
rmt_driver_install(RMT_CHANNEL_0, 0, 0); // rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int rmt_intr_num)
// Channel B put your setup code here, to run once:
configB.rmt_mode = RMT_MODE_TX;
configB.channel = RMT_CHANNEL_1;
configB.gpio_num = RMT_CHB;
configB.mem_block_num = 1;
configB.tx_config.loop_en = 0;
configB.tx_config.carrier_en = 0;
configB.tx_config.idle_output_en = 1;
configB.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
configB.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH;
configB.clk_div = 8; // 80MHx / 80 = 1MHz 0r 1uS per count
rmt_config(&configB);
rmt_driver_install(RMT_CHANNEL_1, 0, 0); // rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int rmt_intr_num)
// Channel C put your setup code here, to run once:
configC.rmt_mode = RMT_MODE_TX;
configC.channel = RMT_CHANNEL_2;
configC.gpio_num = RMT_CHC; // GPIO_NUM_15
configC.mem_block_num = 1;
configC.tx_config.loop_en = 0;
configC.tx_config.carrier_en = 0;
configC.tx_config.idle_output_en = 1;
configC.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
configC.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH;
configC.clk_div = 8; // 80MHx / 80 = 1MHz 0r 1uS per count
rmt_config(&configC);
rmt_driver_install(RMT_CHANNEL_2, 0, 0); // rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int rmt_intr_num)
// CHannel D put your setup code here, to run once:
configD.rmt_mode = RMT_MODE_TX;
configD.channel = RMT_CHANNEL_3;
configD.gpio_num = RMT_CHD;
configD.mem_block_num = 1;
configD.tx_config.loop_en = 0;
configD.tx_config.carrier_en = 0;
configD.tx_config.idle_output_en = 1;
configD.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
configD.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH;
configD.clk_div = 8; // 80MHx / 80 = 1MHz 0r 1uS per count
rmt_config(&configD);
rmt_driver_install(RMT_CHANNEL_3, 0, 0); // rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int rmt_intr_num)
}
void Fill_pulse_pattern()
{
//Serial.println("RMT Reinit");
//PIN 27
//Serial.println(PULS[1].pulseH1);
itemsA[0].duration0 = PULS[0].del;
itemsA[0].level0 = PULS[0].pulse_del_L;;
itemsA[0].duration1 = PULS[0].pulseH1; //PULS[1].pulseL;
itemsA[0].level1 = PULS[0].pulseH1_L;
itemsA[1].duration0 = PULS[0].pulseL1;
itemsA[1].level0 = PULS[0].pulseL1_L;;
itemsA[1].duration1 = PULS[0].pulseH2;
itemsA[1].level1 = PULS[0].pulseH2_L;;
itemsA[2].duration0 = PULS[0].pulseL2;
itemsA[2].level0 = PULS[0].pulseL2_L;;
itemsA[2].duration1 = PULS[0].pulseH3; // End of pattern with 0 time to stop pulse train
itemsA[2].level1 = PULS[0].pulseH3_L;;
itemsA[3].duration0 = PULS[0].pulseL3; // End of pattern with 0 time to stop pulse train
itemsA[3].level0 = PULS[0].pulseL3_L;;
itemsA[3].duration1 = 0; // End of pattern with 0 time to stop pulse train
itemsA[3].level1 = 0;
//PIN 33
itemsB[0].duration0 = PULS[1].del;
itemsB[0].level0 = PULS[1].pulse_del_L;;
itemsB[0].duration1 = PULS[1].pulseH1; //PULS[1].pulseL;
itemsB[0].level1 = PULS[1].pulseH1_L;
itemsB[1].duration0 = PULS[1].pulseL1;
itemsB[1].level0 = PULS[1].pulseL1_L;;
itemsB[1].duration1 = PULS[1].pulseH2;
itemsB[1].level1 = PULS[1].pulseH2_L;;
itemsB[2].duration0 = PULS[1].pulseL2;
itemsB[2].level0 = PULS[1].pulseL2_L;;
itemsB[2].duration1 = PULS[1].pulseH3; // End of pattern with 0 time to stop pulse train
itemsB[2].level1 = PULS[1].pulseH3_L;;
itemsB[3].duration0 = PULS[1].pulseL3; // End of pattern with 0 time to stop pulse train
itemsB[3].level0 = PULS[1].pulseL3_L;;
itemsB[3].duration1 = 0; // End of pattern with 0 time to stop pulse train
itemsB[3].level1 = 0;
//PIN 15
itemsC[0].duration0 = PULS[2].del;
itemsC[0].level0 = PULS[2].pulse_del_L;;
itemsC[0].duration1 = PULS[2].pulseH1; //PULS[1].pulseL;
itemsC[0].level1 = PULS[2].pulseH1_L;
itemsC[1].duration0 = PULS[2].pulseL1;
itemsC[1].level0 = PULS[2].pulseL1_L;;
itemsC[1].duration1 = PULS[2].pulseH2;
itemsC[1].level1 = PULS[2].pulseH2_L;;
itemsC[2].duration0 = PULS[2].pulseL2;
itemsC[2].level0 = PULS[2].pulseL2_L;;
itemsC[2].duration1 = PULS[2].pulseH3; // End of pattern with 0 time to stop pulse train
itemsC[2].level1 = PULS[2].pulseH3_L;;
itemsC[3].duration0 = PULS[2].pulseL3; // End of pattern with 0 time to stop pulse train
itemsC[3].level0 = PULS[2].pulseL3_L;;
itemsC[3].duration1 = 0; // End of pattern with 0 time to stop pulse train
itemsC[3].level1 = 0;
//PIN 32
itemsD[0].duration0 = PULS[3].del;
itemsD[0].level0 = PULS[3].pulse_del_L;;
itemsD[0].duration1 = PULS[3].pulseH1; //PULS[1].pulseL;
itemsD[0].level1 = PULS[3].pulseH1_L;
itemsD[1].duration0 = PULS[3].pulseL1;
itemsD[1].level0 = PULS[3].pulseL1_L;;
itemsD[1].duration1 = PULS[3].pulseH2;
itemsD[1].level1 = PULS[3].pulseH2_L;;
itemsD[2].duration0 = PULS[3].pulseL2;
itemsD[2].level0 = PULS[3].pulseL2_L;;
itemsD[2].duration1 = PULS[3].pulseH3; // End of pattern with 0 time to stop pulse train
itemsD[2].level1 = PULS[3].pulseH3_L;;
itemsD[3].duration0 = PULS[3].pulseL3; // End of pattern with 0 time to stop pulse train
itemsD[3].level0 = PULS[3].pulseL3_L;;
itemsD[3].duration1 = 0; // End of pattern with 0 time to stop pulse train
itemsD[3].level1 = 0;
rmt_fill_tx_items(RMT_CHANNEL_0,itemsA,4,0);
rmt_fill_tx_items(RMT_CHANNEL_1,itemsB,4,0);
rmt_fill_tx_items(RMT_CHANNEL_2,itemsC,4,0);
rmt_fill_tx_items(RMT_CHANNEL_3,itemsD,4,0);
}