#include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "driver/uart.h" #include "driver/rmt_tx.h" #include "led_strip_encoder.h" #define RMT_LED_STRIP_RESOLUTION_HZ 10000000 #define LED_GPIO_NUM 6 #define LED_NUMBERS 30 static const char *TAG = "led-laser"; static uint8_t led_pixels[LED_NUMBERS * 3]; static rmt_channel_handle_t led_chan = NULL; static rmt_encoder_handle_t led_encoder = NULL; typedef struct { const char *name; int freq_hz; int duration_min; uint32_t hue; } preset_t; static const preset_t presets[] = { {"Regeneration", 40, 60, 0}, {"Durchblutung", 60, 60, 15}, {"Tiefenwirkung",80,45, 5}, {"Gepulst Rot", 50, 60, 0}, {"Oberflächenlicht",30,45,20}, {"Muskeln/Gelenke",65,60,10}, {"Ganzkörper", 45, 90, 0} }; #define PRESET_COUNT (sizeof(presets)/sizeof(presets[0])) static int current_preset = -1; static bool led_on = false; static uint64_t last_toggle_ms = 0; static void hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r, uint32_t *g, uint32_t *b) { h %= 360; uint32_t rgb_max = v * 255 / 100; uint32_t rgb_min = rgb_max * (100 - s) / 100; uint32_t i = h / 60; uint32_t diff = h % 60; uint32_t adj = (rgb_max - rgb_min) * diff / 60; switch(i){ case 0: *r=rgb_max; *g=rgb_min+adj; *b=rgb_min; break; case 1: *r=rgb_max-adj; *g=rgb_max; *b=rgb_min; break; case 2: *r=rgb_min; *g=rgb_max; *b=rgb_min+adj; break; case 3: *r=rgb_min; *g=rgb_max-adj; *b=rgb_max; break; case 4: *r=rgb_min+adj; *g=rgb_min; *b=rgb_max; break; default:*r=rgb_max; *g=rgb_min; *b=rgb_max-adj; break; } } static void set_all_pixels(uint32_t r, uint32_t g, uint32_t b) { for(int i=0;i=PRESET_COUNT) return; current_preset = idx; const preset_t *p = &presets[idx]; uint32_t r,g,b; hsv2rgb(p->hue, 100, 100, &r,&g,&b); set_all_pixels(r,g,b); led_on = true; last_toggle_ms = esp_timer_get_time()/1000; ESP_LOGI(TAG, "Preset %d %s %dHz", idx, p->name, p->freq_hz); } static void stop_leds(void){ current_preset = -1; memset(led_pixels,0,sizeof(led_pixels)); flush_leds(); ESP_LOGI(TAG,"LEDs stopped"); } static void list_presets(void){ printf("\n--- Presets ---\n"); for(int i=0;iname, p->freq_hz, p->duration_min); } printf("Commands: 0-6 select, next, stop, list\n"); } static void process_line(char *line){ if(strcmp(line,"stop")==0){ stop_leds(); return; } if(strcmp(line,"next")==0){ int nxt = (current_preset+1)%PRESET_COUNT; apply_preset(nxt); return; } if(strcmp(line,"list")==0){ list_presets(); return; } if(strlen(line)==1 && line[0]>='0' && line[0]<='6'){ int idx = line[0]-'0'; if(idx 0){ uint8_t c; int len = uart_read_bytes(UART_NUM_0,&c,1,0); if(len>0){ if(c=='\r' || c=='\n'){ line_buf[line_pos]='\0'; if(line_pos>0){ process_line(line_buf); } line_pos=0; }else{ if(line_pos < (int)sizeof(line_buf)-1){ line_buf[line_pos++]=c; } } } } if(current_preset>=0){ const preset_t *p=&presets[current_preset]; uint64_t now = esp_timer_get_time()/1000; uint64_t period_ms = 1000 / p->freq_hz; uint64_t half = period_ms/2; if(half<1) half=1; if(now - last_toggle_ms >= half){ led_on = !led_on; last_toggle_ms = now; if(led_on){ uint32_t r,g,b; hsv2rgb(p->hue,100,100,&r,&g,&b); set_all_pixels(r,g,b); }else{ memset(led_pixels,0,sizeof(led_pixels)); } flush_leds(); } } vTaskDelay(pdMS_TO_TICKS(5)); } }