#include "pico/stdlib.h" #include "hardware/pio.h" #include "ws2812.h" #include "ws2812.pio.h" #include #define WS2812_PIN 15 #define IS_RGBW false #define NB_WS2812 5 uint32_t couleur[13]; uint32_t buffer_couleur[12]; struct ws2812_type_gestion_t { enum led_type_gestion_t led_type_gestion; uint32_t couleur; } ws2812_type_gestion[NB_WS2812]; void ws2812_set_buffer(uint32_t couleur, uint8_t index_led); static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b); void ws2812_init(){ couleur[0]=0x000200; couleur[1]=0x010200; couleur[2]=0x020200; couleur[3]=0x020100; couleur[4]=0x020000; couleur[5]=0x020001; couleur[6]=0x020002; couleur[7]=0x010002; couleur[8]=0x000002; couleur[9]=0x000102; couleur[10]=0x000202; couleur[11]=0x000201; couleur[12]=0x000200; /*couleur[0]=0x002000; couleur[1]=0x102000; couleur[2]=0x202000; couleur[3]=0x201000; couleur[4]=0x200000; couleur[5]=0x200010; couleur[6]=0x200020; couleur[7]=0x100020; couleur[8]=0x000020; couleur[9]=0x001020; couleur[10]=0x002020; couleur[11]=0x002010; couleur[12]=0x002000;*/ /*couleur[0]=0x00FF00; couleur[1]=0x80FF00; couleur[2]=0xFFFF00; couleur[3]=0xFF8000; couleur[4]=0xFF0000; couleur[5]=0xFF0080; couleur[6]=0xFF00FF; couleur[7]=0x8000FF; couleur[8]=0x0000FF; couleur[9]=0x0080FF; couleur[10]=0x00FFFF; couleur[11]=0x00FF80; couleur[12]=0x00FF00;*/ // initialisation du PIO PIO pio = pio0; int sm = 0; uint offset = pio_add_program(pio, &ws2812_program); ws2812_program_init(pio, sm, offset, WS2812_PIN, 800000, IS_RGBW); // Tout rouge ! for(uint32_t i = 0; i<12; i++){ ws2812_set_buffer_rgb(ORANGE_24BITS, i); ws2812_type_gestion[NB_WS2812].couleur = urgb_u32(ORANGE_24BITS); ws2812_type_gestion[NB_WS2812].led_type_gestion = PAS_DE_GESTION; } ws2812_affiche_buffer(); } void ws2812_arc_en_ciel(){ while(1){ uint32_t i; sleep_ms(50); // Affichage for(i = 0; i<12; i++){ ws2812_set_buffer(couleur[i], i); } ws2812_affiche_buffer(); // Décalage des couleurs for(i = 0; i<12; i++){ couleur[i] = couleur[i+1]; } couleur[12]=couleur[0]; } } static inline void put_pixel(uint32_t pixel_grb) { pio_sm_put_blocking(pio0, 0, pixel_grb << 8u); } static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) { return ((uint32_t) (r) << 8) | ((uint32_t) (g) << 16) | (uint32_t) (b); } void ws2812_affiche_buffer(){ for(uint32_t i = 0; i<12; i++){ put_pixel(buffer_couleur[i]); } } void ws2812_set_buffer_rgb(uint8_t rouge, uint8_t vert, uint8_t bleu, uint8_t index_led){ ws2812_set_buffer(urgb_u32(rouge, vert,bleu), index_led); } void ws2812_set_rgb(uint8_t rouge, uint8_t vert, uint8_t bleu, uint8_t index_led){ ws2812_set_buffer(urgb_u32(rouge, vert,bleu), index_led); ws2812_affiche_buffer(); sleep_us(500); } //Bit 7 6 5 4 3 2 1 0 //Data R R R G G G B B void ws2812_set_buffer_8bits(uint8_t couleur, uint8_t index_led){ ws2812_set_buffer(urgb_u32(couleur >> 5, (couleur >> 2) & 0x07, couleur & 0x03), index_led); } /// @brief Rempli le buffer à envoyer au LED, necessite d'appeler la fonction ws2812_affiche_buffer() ensuite /// @param couleur : couleur en RVB /// @param index_led : index entre 0 et 11 void ws2812_set_buffer(uint32_t couleur, uint8_t index_led){ if(index_led <12){ buffer_couleur[index_led] = couleur; } } void ws2812_set_led(uint8_t led, uint32_t couleur){ ws2812_set_buffer(couleur, led); ws2812_affiche_buffer(); } uint32_t ws2812_mix_color(uint32_t couleur1, uint32_t couleur2, float facteur){ uint8_t r, g, b; b = (couleur1 & 0xFF) * (1 - facteur) + (couleur2 & 0xFF) * facteur; r = ((couleur1 & 0xFF00)>> 8) * (1 - facteur) + ((couleur2 & 0xFF00)>> 8) * facteur; g = ((couleur1 & 0xFF0000)>> 16) * (1 - facteur) + ((couleur2 & 0xFF0000)>> 16) * facteur; return urgb_u32(r, g, b); } void ws2812_set_mode(uint8_t led_id, enum led_type_gestion_t led_type_gestion, uint32_t couleur){ if(led_id < NB_WS2812){ ws2812_type_gestion[led_id].couleur = couleur; ws2812_type_gestion[led_id].led_type_gestion = led_type_gestion; } } void ws2812_gestion(void){ uint32_t temps_ref; uint8_t nb_cli; uint8_t phase_led; float f; for(int led_id = 0; led_id < NB_WS2812; led_id++){ switch (ws2812_type_gestion[led_id].led_type_gestion) { case PAS_DE_GESTION: break; case LED_STABLE: ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id); break; case LED_CLI_RAPIDE: if((get_absolute_time() / 50000) % 2){ ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id); }else{ ws2812_set_buffer(0x000000, led_id); } break; case LED_CLI_NORMAL: if((get_absolute_time() / 200000) % 2){ ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id); }else{ ws2812_set_buffer(0x000000, led_id); } break; case LED_CLI_LENT: if((get_absolute_time() / 1000000) % 2){ ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id); }else{ ws2812_set_buffer(0x000000, led_id); } break; case LED_CLI_PANIQUE_1: temps_ref =100000; nb_cli = 1; phase_led =(get_absolute_time() / temps_ref) % (nb_cli*2 + 4) ; printf(">l:%d\n", phase_led); if(phase_led >= nb_cli*2){ ws2812_set_buffer(0x000000, led_id); }else{ printf(">l1:%d\n",phase_led ); if(phase_led % 2){ ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id); }else{ ws2812_set_buffer(0x000000, led_id); } } break; case LED_CLI_PANIQUE_2: temps_ref =100000; nb_cli = 2; phase_led =(get_absolute_time() / temps_ref) % (nb_cli*2 + 4) ; if(phase_led >= nb_cli*2){ ws2812_set_buffer(0x000000, led_id); }else{ if(phase_led % 2){ ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id); }else{ ws2812_set_buffer(0x000000, led_id); } } break; case LED_CLI_PANIQUE_3: temps_ref =100000; nb_cli = 3; phase_led =(get_absolute_time() / temps_ref) % (nb_cli*2 + 4) ; if(phase_led >= nb_cli*2){ ws2812_set_buffer(0x000000, led_id); }else{ if(phase_led % 2){ ws2812_set_buffer(ws2812_type_gestion[led_id].couleur, led_id); }else{ ws2812_set_buffer(0x000000, led_id); } } break; case LED_PULSE_LENT: temps_ref = 3000000; if((get_absolute_time() / temps_ref) % 2){ f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref; ws2812_set_buffer(ws2812_mix_color(0, ws2812_type_gestion[led_id].couleur, f), led_id); }else{ f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref; ws2812_set_buffer(ws2812_mix_color(ws2812_type_gestion[led_id].couleur, 0, f), led_id); } break; case LED_PULSE_NORMAL: temps_ref = 1000000; if((get_absolute_time() / temps_ref) % 2){ f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref; ws2812_set_buffer(ws2812_mix_color(0, ws2812_type_gestion[led_id].couleur, f), led_id); }else{ f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref; ws2812_set_buffer(ws2812_mix_color(ws2812_type_gestion[led_id].couleur, 0, f), led_id); } break; case LED_PULSE_RAPIDE: temps_ref = 200000; if((get_absolute_time() / temps_ref) % 2){ f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref; ws2812_set_buffer(ws2812_mix_color(0, ws2812_type_gestion[led_id].couleur, f), led_id); }else{ f = (float)(get_absolute_time() % temps_ref) / (float)temps_ref; ws2812_set_buffer(ws2812_mix_color(ws2812_type_gestion[led_id].couleur, 0, f), led_id); } break; default: break; } } }