void user_init(void) { uart_init(BIT_RATE_115200, BIT_RATE_115200); uart0_sendStr("\r\nesp8266 ws2812 driver\r\n"); // int opm = wifi_get_opmode(); // if( opm == 1 ) need_to_switch_opmode = 120; // wifi_set_opmode_current(2); //Uncomment this to force a system restore. // system_restore(); CSSettingsLoad( 0 ); CSPreInit(); pUdpServer = (struct espconn *)os_zalloc(sizeof(struct espconn)); ets_memset( pUdpServer, 0, sizeof( struct espconn ) ); espconn_create( pUdpServer ); pUdpServer->type = ESPCONN_UDP; pUdpServer->proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp)); pUdpServer->proto.udp->local_port = 7777; espconn_regist_recvcb(pUdpServer, udpserver_recv); if( espconn_create( pUdpServer ) ) { while(1) { uart0_sendStr( "\r\nFAULT\r\n" ); } } CSInit(); SetServiceName( "ws2812" ); AddMDNSName( "cn8266" ); AddMDNSName( "ws2812" ); AddMDNSService( "_http._tcp", "An ESP8266 Webserver", 80 ); AddMDNSService( "_ws2812._udp", "WS2812 Driver", 7777 ); AddMDNSService( "_cn8266._udp", "ESP8266 Backend", 7878 ); //Add a process system_os_task(procTask, procTaskPrio, procTaskQueue, procTaskQueueLen); //Timer example os_timer_disarm(&some_timer); os_timer_setfn(&some_timer, (os_timer_func_t *)myTimer, NULL); os_timer_arm(&some_timer, 100, 1); ws2812_init(); uint8_t ledout[] = { 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00 }; ws2812_push( ledout, sizeof( ledout ) ); system_os_post(procTaskPrio, 0, 0 ); }
//Called when new packet comes in. static void ICACHE_FLASH_ATTR udpserver_recv(void *arg, char *pusrdata, unsigned short len) { struct espconn *pespconn = (struct espconn *)arg; uart0_sendStr("X"); ws2812_push( pusrdata+3, len-3 ); len -= 3; if( len > sizeof(last_leds) + 3 ) { len = sizeof(last_leds) + 3; } ets_memcpy( last_leds, pusrdata+3, len ); last_led_count = len / 3; }
/* * An ADC measurement is made every time this timer triggers. * The ADC input is connected to a: * SparkFun MEMS Microphone Breakout - INMP401 (ADMP401) * https://www.sparkfun.com/products/9868 * * This callback also contains the logic that simulates an * equalizer by changing the LED colors of a ws2812 LED strip */ void softwareTimerCallback(void *arg) { /* ====================================== */ /* ADC */ /* ====================================== */ uint16 i; /* Current ADC value (volume level of the most recent ADC measurement)*/ uint16 adc_value; /* Previous ADC value (volume level of previous ADC capture)*/ static uint16 prev_adc_value; /* The absolute value of the difference of the current and previous ADC values */ uint16 abs_val_diff = 0; /* Color in RGB space */ rgb my_rgb; /* Color in HSV space */ hsv my_hsv; /* TODO: make rainbow when no volume */ static int count = 0; /* defines the number of ws2812 LEDs */ static int num_leds = 30; /* Changes of volume below the threshold are ignored */ static int threshold = 20; /* Controls the gradual LED color change animation */ static bool lock = false; /* Controls the heatmap of the LEDs */ static int heatmap = 0; /* Buffer that stores the colors of each LED in the strip */ uint8_t led_out[num_leds * 3]; const uint16 red_up_num_cycles = 25; static bool count_up = true; /* Init saturation and value for HSV color */ my_hsv.s = 1.0; my_hsv.v = 0.1; /* Read ADC */ adc_value = system_adc_read(); /* Calculate the absolute value of the previous and current ADC values */ abs_val_diff = ( adc_value > prev_adc_value ) ? adc_value - prev_adc_value : prev_adc_value - adc_value; /* Save adc_value */ prev_adc_value = adc_value; /* Gradual color change animation taking place? * OR * Is the measured value larger than the last value * that triggered the animation?*/ if ( lock == false || abs_val_diff > heatmap ) { #if 0 os_printf("\r\nheatmap: %d", heatmap); #endif /* Is the measured value larger than the threshold? */ if ( abs_val_diff >= threshold ) { /* Trigger detected! Start animation! */ lock = true; /* Save the value that triggered the animation */ heatmap = abs_val_diff; /* Reset important variables used in the animation */ count_up = true; count = 0; } } else { /* No, then continue with animation */ } /************************************ * GRADUAL LED COLOR CHANGE ANIMATION ************************************/ /* Enter only if an animation was triggered above */ if ( lock == true ) { /* Are we 'heating up' or 'cooling down'? */ if ( count_up == true ) { /* Heat up (faster than cooling down) */ count += 3; count_up = (count >= red_up_num_cycles) ? false : true ; } else { /* Cool down */ count--; if ( count <= 2 ) { /* Stop gradual color change */ lock = false; } } #if 0 os_printf("\r\ncount: %d", count); #endif /* Set color for each LED */ for (i = 0; i < num_leds; i++) { if ( i == 0 ) { /* The first LED is always set to blue */ my_hsv.h = 240.0; } else { /* Decrease hue depending on the change in volume */ my_hsv.h = (uint16)my_hsv.h - (uint16)(heatmap * 0.005 * count); } /* Clip hue if below 0 */ my_hsv.h = my_hsv.h < 0 ? 0 : my_hsv.h; /* Convert color from HSV to RGB space */ my_rgb = hsv2rgb(my_hsv); /* Store RGB color in the output buffer */ led_out[i * 3 + 0] = my_rgb.g * 255; led_out[i * 3 + 1] = my_rgb.r * 255; led_out[i * 3 + 2] = my_rgb.b * 255; } ws2812_push(led_out, sizeof(led_out)); #if 0 os_printf("\r\nG R B: %x %x %x", led_out[0], led_out[1],led_out[2]); // os_printf("\r\nhue: %d", (int)my_hsv.h); #endif #if 0 // os_printf("\r\nsystem_adc_read: %x", adc_value); // os_printf("\r\ndiff_abs_val: %x", diff_abs_val); #endif } return; }