static uint16_t PWM_Resolution_Val = 511;
static uint16_t Max_Deviser_Counter_Value = 63;
static uint8_t Max_Delay_Timer = 15;
static uint16_t CURRENT_DIM = 0;
static uint16_t TARGET_DIM = 511;
static uint16_t CURRENT_CCT = 511;
static uint16_t TARGET_CCT = 511;
static uint8_t currentDelay = 1;
static unsigned long PWM_LAST_Update = 0;
inline uint16_t CONVERT_VALUE(uint16_t input, uint16_t max_output, uint16_t max_input) {
return (uint32_t)input * max_output / max_input;
}
// Function for absolute value
inline uint16_t AbsDiff(uint16_t a, uint16_t b) {
return (a > b) ? (a - b) : (b - a);
}
// Utility function to map values safely
long Scale_Value(long x, long in_min, long in_max, long out_min, long out_max) {
long run = in_max - in_min;
if (run == 0) return out_min;
long rise = out_max - out_min;
long delta = x - in_min;
return (delta * rise) / run + out_min;
}
void setup() {
Serial.begin(9600);
}
void loop() {
// --- Step 1: Read and scale input ---
uint16_t DIM_POT = analogRead(A1);
uint16_t CCT_POT = analogRead(A2);
// Scale 0–1023 → 0–255
uint16_t DIM_VAL = Scale_Value(DIM_POT, 0, 1023, 0, 255);
uint16_t CCT_VAL = Scale_Value(CCT_POT, 0, 1023, 0, 255);
TARGET_DIM = CONVERT_VALUE(DIM_VAL,PWM_Resolution_Val,255);
TARGET_CCT = CONVERT_VALUE(CCT_VAL,PWM_Resolution_Val,255);
// ✅ Correct call (not declaration)
UPDATE_PWM();
}
void UPDATE_PWM ()
{
// Early return if no update needed or delay not elapsed
if (((TARGET_DIM == CURRENT_DIM) && (TARGET_CCT == CURRENT_CCT)) || ((millis() - PWM_LAST_Update) < currentDelay))
{
return;
}
uint16_t ABS_DIM = AbsDiff(CURRENT_DIM, TARGET_DIM);
uint16_t ABS_CCT = AbsDiff(CURRENT_CCT, TARGET_CCT);
// Step sizes (minimum 1)
uint16_t STEP_SIZE_DIM = CONVERT_VALUE(ABS_DIM, Max_Deviser_Counter_Value, PWM_Resolution_Val) + 1;
uint16_t STEP_SIZE_CCT = CONVERT_VALUE(ABS_CCT, Max_Deviser_Counter_Value, PWM_Resolution_Val) + 1;
// Clamp to avoid overshoot
if (STEP_SIZE_DIM > ABS_DIM) STEP_SIZE_DIM = ABS_DIM;
if (STEP_SIZE_CCT > ABS_CCT) STEP_SIZE_CCT = ABS_CCT;
// Reverse delay logic: Bigger step = Smaller delay
uint16_t MAX_DIFF = (STEP_SIZE_DIM > STEP_SIZE_CCT) ? STEP_SIZE_DIM : STEP_SIZE_CCT;
currentDelay = Scale_Value(MAX_DIFF, 0, Max_Deviser_Counter_Value, Max_Delay_Timer, 1);
// Smooth transitions
if (CURRENT_DIM != TARGET_DIM) CURRENT_DIM += (TARGET_DIM > CURRENT_DIM) ? STEP_SIZE_DIM : -STEP_SIZE_DIM;
if (CURRENT_CCT != TARGET_CCT) CURRENT_CCT += (TARGET_CCT > CURRENT_CCT) ? STEP_SIZE_CCT : -STEP_SIZE_CCT;
// --- PWM outputs ---
if (CURRENT_DIM == 0) {
Serial.println("LED OFF");
} else {
uint16_t WHITE_Brightness = CONVERT_VALUE(CURRENT_CCT, CURRENT_DIM, PWM_Resolution_Val);
uint16_t WORM_Brightness = CURRENT_DIM - WHITE_Brightness;
Serial.print("WORM_Brightness = ");
Serial.print(WORM_Brightness);
Serial.print(" | WHITE_Brightness = ");
Serial.print(WHITE_Brightness);
Serial.print(" | Delay = ");
Serial.println(currentDelay);
}
PWM_LAST_Update = millis();
}
/*
#define PWM_RESOLUTION 4095
#define SMOOTH_STEP_MIN 1
#define SMOOTH_STEP_MAX 64
#define DELAY_MIN 1
#define DELAY_MAX 15
// ADC input values
unsigned int Master_Dim = 0;
unsigned int Master_CCT = 0;
// Target PWM duty values
unsigned int target_warm = 0;
unsigned int target_cool = 0;
// Actual (current) PWM duty values
unsigned int current_warm = 0;
unsigned int current_cool = 0;
// Utility function to map values
long Scale_Value(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
// Absolute value between two
unsigned int AbsDiff(unsigned int a, unsigned int b) {
return (a > b) ? (a - b) : (b - a);
}
void setup() {
Serial.begin(115200);
analogReadResolution(8); // 0–255 input
}
void loop() {
// --- Step 1: Read and scale input ---
Master_Dim = analogRead(32);
Master_CCT = analogRead(35);
// Scale 0–255 to 0–4095
Master_Dim = Scale_Value(Master_Dim, 0, 255, 0, PWM_RESOLUTION);
Master_CCT = Scale_Value(Master_CCT, 0, 255, 0, PWM_RESOLUTION);
// --- Step 2: Calculate new target warm/cool duty ---
target_warm = Scale_Value(PWM_RESOLUTION - Master_CCT, 0, PWM_RESOLUTION, 0, Master_Dim);
target_cool = Scale_Value(Master_CCT, 0, PWM_RESOLUTION, 0, Master_Dim);
// --- Step 3: Smooth transition for WARM ---
if (current_warm != target_warm) {
unsigned int diff = AbsDiff(current_warm, target_warm);
unsigned int step = Scale_Value(diff, 0, PWM_RESOLUTION, SMOOTH_STEP_MIN, SMOOTH_STEP_MAX);
if (current_warm < target_warm) current_warm += step;
else current_warm -= step;
}
// --- Step 4: Smooth transition for COOL ---
if (current_cool != target_cool) {
unsigned int diff = AbsDiff(current_cool, target_cool);
unsigned int step = Scale_Value(diff, 0, PWM_RESOLUTION, SMOOTH_STEP_MIN, SMOOTH_STEP_MAX);
if (current_cool < target_cool) current_cool += step;
else current_cool -= step;
}
// --- Step 5: Adaptive delay based on max diff (Inverse Mapping) ---
unsigned int max_diff = max(AbsDiff(current_warm, target_warm), AbsDiff(current_cool, target_cool));
unsigned int delay_time = Scale_Value(max_diff, 0, PWM_RESOLUTION, DELAY_MAX, DELAY_MIN);
delay(delay_time);
// --- Step 6: Output ---
PWM_Set_Duty(current_warm, current_cool);
}
void PWM_Set_Duty(unsigned int WARM_DUTY, unsigned int COOL_DUTY) {
Serial.print("WARM_DUTY: "); Serial.print(WARM_DUTY);
Serial.print(" | COOL_DUTY: "); Serial.println(COOL_DUTY);
}
*/
/*
#define PWM_RESOLUTION 4095
#define SMOOTH_STEP_MIN 1
#define SMOOTH_STEP_MAX 64
#define DELAY_MIN 1
#define DELAY_MAX 15
// ADC input values
unsigned int Master_Dim = 0;
unsigned int Master_CCT = 0;
// Target PWM duty values
unsigned int target_warm = 0;
unsigned int target_cool = 0;
// Actual (current) PWM duty values
unsigned int current_warm = 0;
unsigned int current_cool = 0;
// Utility function to map values
long Scale_Value(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
// Absolute value between two
unsigned int AbsDiff(unsigned int a, unsigned int b) {
return (a > b) ? (a - b) : (b - a);
}
void setup() {
Serial.begin(115200);
analogReadResolution(8); // 0–255 input
}
void loop() {
// --- Step 1: Read and scale input ---
Master_Dim = analogRead(32);
Master_CCT = analogRead(35);
// Scale 0–255 to 0–4095
Master_Dim = Scale_Value(Master_Dim, 0, 255, 0, PWM_RESOLUTION);
Master_CCT = Scale_Value(Master_CCT, 0, 255, 0, PWM_RESOLUTION);
// --- Step 2: Calculate new target warm/cool duty ---
target_warm = Scale_Value(PWM_RESOLUTION - Master_CCT, 0, PWM_RESOLUTION, 0, Master_Dim);
target_cool = Scale_Value(Master_CCT, 0, PWM_RESOLUTION, 0, Master_Dim);
// --- Step 3: Smooth transition for WARM ---
if (current_warm != target_warm) {
unsigned int diff = AbsDiff(current_warm, target_warm);
unsigned int step = Scale_Value(diff, 0, PWM_RESOLUTION, SMOOTH_STEP_MIN, SMOOTH_STEP_MAX);
if (current_warm < target_warm) current_warm += step;
else current_warm -= step;
}
// --- Step 4: Smooth transition for COOL ---
if (current_cool != target_cool) {
unsigned int diff = AbsDiff(current_cool, target_cool);
unsigned int step = Scale_Value(diff, 0, PWM_RESOLUTION, SMOOTH_STEP_MIN, SMOOTH_STEP_MAX);
if (current_cool < target_cool) current_cool += step;
else current_cool -= step;
}
// --- Step 5: Adaptive delay based on max diff (Inverse Mapping) ---
unsigned int max_diff = max(AbsDiff(current_warm, target_warm), AbsDiff(current_cool, target_cool));
unsigned int delay_time = Scale_Value(max_diff, 0, PWM_RESOLUTION, DELAY_MAX, DELAY_MIN);
delay(delay_time);
// --- Step 6: Output ---
PWM_Set_Duty(current_warm, current_cool);
}
void PWM_Set_Duty(unsigned int WARM_DUTY, unsigned int COOL_DUTY) {
Serial.print("WARM_DUTY: "); Serial.print(WARM_DUTY);
Serial.print(" | COOL_DUTY: "); Serial.println(COOL_DUTY);
}
*/
/*
#define PWM_RESOLUTION 4095
#define Max_Deviser_Counter_Value 511
#define Max_Delay_Timer 15
// Variables to store the analog values
unsigned int Master_Dim = 0;
unsigned int Master_CCT = 0;
unsigned int PWM_DUTY = 0;
unsigned int PWM_DUTY_Track;
unsigned int ID_Counter = 1; // Counter for adjusting brightness rapidly
unsigned int Delay = 1; // Delay time for adjusting values
unsigned int ABS_DIFF;
void setup() {
// Initialize serial communication at 115200 baud
Serial.begin(115200);
// Configure the ADC resolution (optional)
analogReadResolution(8); // Set to 12-bit resolution (0-4095)
// Note: ESP32 pins don't need to be set as INPUT for analogRead
}
void loop() {
// Read the analog values
Master_Dim = analogRead(32);
Master_CCT = analogRead(35);
// scaling step per signal as per PWM RESOLUTION
Master_Dim = Scale_Value(Master_Dim, 0, 255, 0, PWM_RESOLUTION);
Master_CCT = Scale_Value(Master_CCT, 0, 255, 0, PWM_RESOLUTION);
PWM_DUTY = Scale_Value(Master_CCT, 0, PWM_RESOLUTION, 0, Master_Dim);
if (PWM_DUTY != PWM_DUTY_Track) {
PWM_Set_Duty(PWM_DUTY, (Master_Dim - PWM_DUTY));
ABS_DIFF = ABS_Value(PWM_DUTY, PWM_DUTY_Track);
ID_Counter = Scale_Value(ABS_DIFF, 0, PWM_RESOLUTION, 0, Max_Deviser_Counter_Value);
if (ID_Counter <= 0) ID_Counter = 1;
Delay = Scale_Value(ID_Counter, 0, Max_Deviser_Counter_Value, Max_Delay_Timer, 0);
if (Delay <= 0) Delay = 1;
if (PWM_DUTY > PWM_DUTY_Track) PWM_DUTY_Track += ID_Counter;
else if (PWM_DUTY < PWM_DUTY_Track) PWM_DUTY_Track -= ID_Counter;
PWM_Set_Duty(PWM_DUTY_Track, (Master_Dim - PWM_DUTY));
delay(Delay);
}
}
long Scale_Value(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
int ABS_Value(int a, int b) {
if (a > b) {
return a - b;
} else {
return b - a;
}
}
void PWM_Set_Duty(unsigned int WARM_DUTY, unsigned int COOL_DUTY) {
Serial.print(" | WARM_DUTY: "); Serial.print(WARM_DUTY);
Serial.print(" | COOL_DUTY: "); Serial.println(COOL_DUTY);
}
*/