uint8_t msg[1024];
int len;
} pwm_data_t;
+
+typedef struct rgb_data_s {
+ uint16_t red;
+ uint16_t green;
+ uint16_t blue;
+} rgb_data_t;
+
#endif
return duty_res;
}
+static rgb_data_t rgb_to_int(float red, float green, float blue, float target, int duty_res){
+ rgb_data_t return_rgb;
+
+ float total = red + green + blue;
+
+ // gamma correct and scale if needed (i.e. if any color is active)
+ if (total > 0){
+ red = gamma_correct(red*(pwm_target/total));
+ green = gamma_correct(green*(pwm_target/total));
+ blue = gamma_correct(blue*(pwm_target/total));
+ }
+
+ // scale the float to the appropriate duty resolution we're using locally
+ return_rgb.red = (int)(red*(pow(2,duty_res)));
+ return_rgb.green = (int)(green*(pow(2,duty_res)));
+ return_rgb.blue = (int)(blue*(pow(2,duty_res)));
+
+ return return_rgb;
+}
+
static void pwm_task(void* discard){
// 32 MHz ref tick used for timer
cJSON* red_json;
cJSON* green_json;
cJSON* blue_json;
+ cJSON* red2_json;
+ cJSON* green2_json;
+ cJSON* blue2_json;
cJSON* target_json;
cJSON* freq_json;
double red_duty_float;
- int red_duty_int;
double green_duty_float;
- int green_duty_int;
double blue_duty_float;
- int blue_duty_int;
- double total;
+ double red2_duty_float;
+ double green2_duty_float;
+ double blue2_duty_float;
for(;;) {
// just a JSON string hot off of mqtt, we need to parse the values from it
if(xQueueReceive(pwm_queue, &recv, portMAX_DELAY)) {
// data over and over. this might get messy if getting multiple values in a short period or something, but so far no issues
// with concurrency.
if (cJSON_IsObject(current_pwm)){
- // used to adjust scaling with pwm_target
- total = 0.0;
// initialize everything off
red_duty_float = 0;
green_duty_float = 0;
blue_duty_float = 0;
+ red2_duty_float = 0;
+ green2_duty_float = 0;
+ blue2_duty_float = 0;
// not changed in normal operation, used for debugging PWM brightness
target_json = cJSON_GetObjectItemCaseSensitive(current_pwm, "target");
if (cJSON_IsNumber(target_json)){
duty_res = change_pwm_freq(freq_json->valueint);
}
-
+ bool second_values_set = false;
+
// red duty cycle as a float
red_json = cJSON_GetObjectItemCaseSensitive(current_pwm, "red");
if (cJSON_IsNumber(red_json)){
ESP_LOGI(TAG, "parsed red float %f", red_json->valuedouble);
red_duty_float = red_json->valuedouble;
- total += red_duty_float;
}
// green duty cycle as a float
if (cJSON_IsNumber(green_json)){
ESP_LOGI(TAG, "parsed green float %f", green_json->valuedouble);
green_duty_float = green_json->valuedouble;
- total += green_duty_float;
}
// blue duty cycle as a float
if (cJSON_IsNumber(blue_json)){
ESP_LOGI(TAG, "parsed blue float %f", blue_json->valuedouble);
blue_duty_float = blue_json->valuedouble;
- total += blue_duty_float;
}
-
- // gamma correct and scale if needed (i.e. if any color is active)
- if (total > 0){
- red_duty_float = gamma_correct(red_duty_float*(pwm_target/total));
- green_duty_float = gamma_correct(green_duty_float*(pwm_target/total));
- blue_duty_float = gamma_correct(blue_duty_float*(pwm_target/total));
+ // red2 duty cycle as a float
+ red2_json = cJSON_GetObjectItemCaseSensitive(current_pwm, "red2");
+ if (cJSON_IsNumber(red2_json)){
+ ESP_LOGI(TAG, "parsed red2 float %f", red2_json->valuedouble);
+ red2_duty_float = red2_json->valuedouble;
+ second_values_set = true;
}
- // scale the float to the appropriate duty resolution we're using locally
- red_duty_int = (int)(red_duty_float*(pow(2,duty_res)));
- green_duty_int = (int)(green_duty_float*(pow(2,duty_res)));
- blue_duty_int = (int)(blue_duty_float*(pow(2,duty_res)));
+ // green2 duty cycle as a float
+ green2_json = cJSON_GetObjectItemCaseSensitive(current_pwm, "green2");
+ if (cJSON_IsNumber(green2_json)){
+ ESP_LOGI(TAG, "parsed green2 float %f", green2_json->valuedouble);
+ green2_duty_float = green2_json->valuedouble;
+ second_values_set = true;
+ }
+ // blue2 duty cycle as a float
+ blue2_json = cJSON_GetObjectItemCaseSensitive(current_pwm, "blue2");
+ if (cJSON_IsNumber(blue2_json)){
+ ESP_LOGI(TAG, "parsed blue2 float %f", blue2_json->valuedouble);
+ blue2_duty_float = blue2_json->valuedouble;
+ second_values_set = true;
+ }
+
+ rgb_data_t rgb1 = rgb_to_int(red_duty_float, green_duty_float, blue_duty_float, pwm_target, duty_res);
+ rgb_data_t rgb2;
+ if (second_values_set){
+ rgb2 = rgb_to_int(red2_duty_float, green2_duty_float, blue2_duty_float, pwm_target, duty_res);
+ } else {
+ // fallback to using first string values
+ rgb2 = rgb1;
+ }
// set all active PWM channels appropriately
- ESP_LOGI(TAG, "red duty float calculated as %02f, int %d", red_duty_float, red_duty_int);
-
+ // set the first string pwm values
if (CONFIG_PWM_R1_GPIO != -1){
- ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, R1_CHANNEL, red_duty_int));
+ ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, R1_CHANNEL, rgb1.red));
// Update duty to apply the new value
ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, R1_CHANNEL));
}
-
- if (CONFIG_PWM_R2_GPIO != -1){
- ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, R2_CHANNEL, red_duty_int));
+ if (CONFIG_PWM_G1_GPIO != -1){
+ ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, G1_CHANNEL, rgb1.green));
// Update duty to apply the new value
- ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, R2_CHANNEL));
+ ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, G1_CHANNEL));
}
-
-
- ESP_LOGI(TAG, "green duty float calculated as %02f, int %d", green_duty_float, green_duty_int);
-
- if (CONFIG_PWM_G1_GPIO != -1){
- ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, G1_CHANNEL, green_duty_int));
+ if (CONFIG_PWM_B1_GPIO != -1){
+ ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, B1_CHANNEL, rgb1.blue));
// Update duty to apply the new value
- ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, G1_CHANNEL));
+ ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, B1_CHANNEL));
}
-
- if (CONFIG_PWM_G2_GPIO != -1){
- ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, G2_CHANNEL, green_duty_int));
+
+ // set the second string pwm values
+ if (CONFIG_PWM_R2_GPIO != -1){
+ ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, R2_CHANNEL, rgb2.red));
// Update duty to apply the new value
- ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, G2_CHANNEL));
+ ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, R2_CHANNEL));
}
-
-
- ESP_LOGI(TAG, "blue duty float calculated as %02f, int %d", blue_duty_float, blue_duty_int);
- if (CONFIG_PWM_B1_GPIO != -1){
- ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, B1_CHANNEL, blue_duty_int));
+ if (CONFIG_PWM_G2_GPIO != -1){
+ ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, G2_CHANNEL, rgb2.green));
// Update duty to apply the new value
- ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, B1_CHANNEL));
+ ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, G2_CHANNEL));
}
if (CONFIG_PWM_B2_GPIO != -1){
- ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, B2_CHANNEL, blue_duty_int));
+ ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, B2_CHANNEL, rgb2.blue));
// Update duty to apply the new value
ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, B2_CHANNEL));
}