Fading example code
unknown
c_cpp
10 months ago
6.5 kB
5
Indexable
#include "driver/gpio.h"
#include "driver/ledc.h"
#include "esp_timer.h"
#include "driver/gptimer.h"
uint16_t ti = 20000;
uint8_t ch = 1;
#define NUM_CHANNELS 5
static uint16_t start_values_LED1[NUM_CHANNELS];
static uint16_t target_values_LED1[NUM_CHANNELS];
static int16_t step_values_LED1[NUM_CHANNELS];
static int16_t steps_taken_LED1[NUM_CHANNELS];
static bool fade_active_LED1 = false;
static uint16_t steps_remaining_LED1 = 0;
uint32_t Rtrig = ti;
uint32_t Gtrig = ti*2;
uint32_t Btrig = ti*3;
hw_timer_t *LEDtimer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR onLEDTimer(){
if(ch == 1){
if (steps_remaining_LED1 > 0) {
for (int i = 0; i < NUM_CHANNELS; i++) {
if(steps_taken_LED1[i] == 0){
if(start_values_LED1[i] != target_values_LED1[i]){
start_values_LED1[i] = start_values_LED1[i] + step_values_LED1[i];
ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)i, (start_values_LED1[i]));
ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)i);
} else {step_values_LED1[i] = 0;}
} else if (steps_taken_LED1[i] == 1 || steps_taken_LED1[i] == -1){
if((start_values_LED1[i] != 0 && steps_taken_LED1[i] < 0) || (start_values_LED1[i] != 65535 && steps_taken_LED1[i] > 0)){
start_values_LED1[i] = start_values_LED1[i] + steps_taken_LED1[i];
}
steps_taken_LED1[i] = step_values_LED1[i];
ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)i, (start_values_LED1[i]));
ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)i);
} else if (steps_taken_LED1[i] > 1){
steps_taken_LED1[i] = steps_taken_LED1[i] - 1;
} else if (steps_taken_LED1[i] < -1){
steps_taken_LED1[i] = steps_taken_LED1[i] + 1;
}
}
steps_remaining_LED1--;
if (steps_remaining_LED1 == 0){
for (int i = 0; i < NUM_CHANNELS; i++) {
start_values_LED1[i] = target_values_LED1[i];
ledc_set_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)i, (target_values_LED1[i]));
ledc_update_duty(LEDC_LOW_SPEED_MODE, (ledc_channel_t)i);
}
}
} else {
timerStop(LEDtimer);
}
}
else if(ch ==4){
ch = 1;
} else {
ch++;
}
}
void setup(){
//initializePins();
Serial.begin(115200);
initializeLEDs();
LEDtimer = timerBegin(10000); // Timer 10kHz
timerAttachInterrupt(LEDtimer, &onLEDTimer);
timerAlarm(LEDtimer, 10, true, 0);
timerStop(LEDtimer);
}
void loop(){
uint16_t x = 3000;
if(millis() > Rtrig){
Rtrig = millis() + ti*3;
uint16_t current_values[NUM_CHANNELS] = {0, 0, x, 0, 0};
uint16_t target_values[NUM_CHANNELS] = {x, 0, 0, 0, 0};
fade(current_values, target_values, ti); // 1000ms transition
}
if(millis() > Gtrig){
Gtrig = millis() + ti*3;
uint16_t current_values1[NUM_CHANNELS] = {x, 0, 0, 0, 0};
uint16_t target_values1[NUM_CHANNELS] = {0, x, 0, 0, 0};
fade(current_values1, target_values1, ti); // 1000ms transition
}
if(millis() > Btrig){
Btrig = millis() + ti*3;
uint16_t current_values2[NUM_CHANNELS] = {0, x, 0, 0, 0};
uint16_t target_values2[NUM_CHANNELS] = {0, 0, x, 0, 0};
fade(current_values2, target_values2, ti); // 1000ms transition
}
Serial.print(start_values_LED1[0]);
Serial.print(",");
Serial.print(start_values_LED1[1]);
Serial.print(",");
Serial.print(x);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.println(start_values_LED1[2]);
}
void fade(uint16_t *current_values, uint16_t *new_values, uint16_t transition_ms) {
if (fade_active_LED1){
timerStop(LEDtimer); // Stop the timer interrupt
}
transition_ms = transition_ms/4; //1ms interrupt divided between 4 channels
steps_remaining_LED1 = transition_ms; //Duration divided by 4 is the amount of steps
for (int i = 0; i < NUM_CHANNELS; i++) { //For every color channel
start_values_LED1[i] = current_values[i]; //Write to global variable
target_values_LED1[i] = new_values[i]; //Write to global variable
if ((target_values_LED1[i] - start_values_LED1[i]) == 0){ //If there's no change in this color channel
step_values_LED1[i] = 0; //The step size is 0
}
else {
step_values_LED1[i] = (target_values_LED1[i] - start_values_LED1[i]) / (int16_t)transition_ms; //Calculate the step size
if(step_values_LED1[i] == 0){ //If the step value is 0, The difference between current and asked LED brightness is smaller than the transition time. We thus have to skip steps
step_values_LED1[i] = (float)transition_ms/((float)target_values_LED1[i] - (float)start_values_LED1[i]); //The amount of interrupt runs to skip in order to achieve the required change within the requested timeframe
steps_taken_LED1[i] = step_values_LED1[i]; //We'll decrement the steps taken in the interrupt
} else {
steps_taken_LED1[i] = 0; //If no steps should be skipped, steps taken should be 0 to indicate the same to the interrupt function
}
}
}
fade_active_LED1 = true; //Enable the fade flag
timerStart(LEDtimer); // Start the timer interrupt
}
void initializeLEDs(){
ledc_timer_config_t ledc_timer = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_16_BIT,
.timer_num = LEDC_TIMER_0,
.freq_hz = 120,
.clk_cfg = LEDC_USE_RC_FAST_CLK
};
ledc_timer_config(&ledc_timer);
ledc_channel_config_t ledc_channel = {
.gpio_num = 19,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LEDC_CHANNEL_0,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = LEDC_TIMER_0,
.duty = 0,
.hpoint = 0
};
ledc_channel_config(&ledc_channel);
ledc_channel.gpio_num = 15;
ledc_channel.channel = LEDC_CHANNEL_1;
ledc_channel_config(&ledc_channel);
ledc_channel.gpio_num = 16;
ledc_channel.channel = LEDC_CHANNEL_2;
ledc_channel_config(&ledc_channel);
ledc_channel.gpio_num = 17;
ledc_channel.channel = LEDC_CHANNEL_3;
ledc_channel_config(&ledc_channel);
ledc_channel.gpio_num = 18;
ledc_channel.channel = LEDC_CHANNEL_4;
ledc_channel_config(&ledc_channel);
}Editor is loading...
Leave a Comment