/* Example SPI transfert * * This sample code is in the public domain. */ #include "espressif/esp_common.h" #include "esp/uart.h" #include "FreeRTOS.h" #include "task.h" #include "esp8266.h" #include #include "esp/spi.h" #include "math.h" #include #define DAYTIME(h,m,s) (h*3600+m*60+s) struct { time_t sunrise_start = DAYTIME(5,30,0); time_t sunrise_end = DAYTIME(6,0,0); time_t sunrise_shutdown = DAYTIME(7,0,0); time_t sunset_time = DAYTIME(22,0,0); } settings; struct { uint8_t r = 255; uint8_t g = 160; uint8_t b = 80; } white; time_t day_seconds() { time_t t1, t2; struct tm tms; time(&t1); localtime_r(&t1, &tms); tms.tm_hour = 0; tms.tm_min = 0; tms.tm_sec = 0; t2 = mktime(&tms); return t1 - t2; } struct led_t{ struct { unsigned int mod : 5, marker : 3; } __attribute__((packed)) global = {0x1F, 0x7}; uint8_t b = 0; uint8_t g = 0; uint8_t r = 0; }; led_t leds[4][10]; float square(float x){ return x*x; } float lerp(float a, float b, float x){ return (1.-x)*a + x *b; } float clamp(float x, float a, float b){ if(xb) return b; return x; } float fade(float x, float offset, float factor){ float val = (x*factor-offset); return lerp(square(clamp(val,0,1)),square(1-clamp(1-val,0,1)),val); } void write_leds(){ spi_transfer_32(1, 0x00000000); for(int i = 0; i < 10; i++) spi_transfer_32(1, *(uint32_t*)&leds[0][i]); for(int i = 0; i < 10; i++) spi_transfer_32(1, *(uint32_t*)&leds[1][9-i]); for(int i = 0; i < 10; i++) spi_transfer_32(1, *(uint32_t*)&leds[2][i]); for(int i = 0; i < 10; i++) spi_transfer_32(1, *(uint32_t*)&leds[3][9-i]); spi_transfer_32(1, 0xFFFFFFFF); spi_transfer_32(1, 0xFFFFFFFF); } enum state_t{ BOOT_S, SUNRISE_S, MORNING_S, DAY_S, NIGHT_S }; state_t s = BOOT_S; bool maual_mode = false; extern "C" void manual_switch(){ maual_mode = !maual_mode; printf("%d\n", (int)maual_mode); if(maual_mode){ if(s == NIGHT_S){ for(int j = 0; j < 4; j++) for(int i = 0; i < 8; i+=2){ leds[j][i].global.mod = 2; leds[j][i].r = 128; leds[j][i].g = 30; leds[j][i].b = 15; } }else{ for(int j = 0; j < 4; j++) for(int i = 0; i < 10; i++){ leds[j][i].global.mod = 31; leds[j][i].r = white.r; leds[j][i].g = white.g; leds[j][i].b = white.b; } } write_leds(); }else{ for(int j = 0; j < 4; j++) for(int i = 0; i < 10; i++){ leds[j][i].global.mod = 0; leds[j][i].r = 0; leds[j][i].g = 0; leds[j][i].b = 0; } write_leds(); } } void loop(void *pvParameters) { spi_init(1, SPI_MODE0, SPI_FREQ_DIV_1M, 1, SPI_LITTLE_ENDIAN, false); while(1){ time_t rt = day_seconds(); if(maual_mode){ if(s == NIGHT_S){ for(int j = 0; j < 4; j++) for(int i = 0; i < 8; i+=2){ leds[j][i].global.mod = 2; leds[j][i].r = 128; leds[j][i].g = 30; leds[j][i].b = 15; } }else{ for(int j = 0; j < 4; j++) for(int i = 0; i < 10; i++){ leds[j][i].global.mod = 31; leds[j][i].r = white.r; leds[j][i].g = white.g; leds[j][i].b = white.b; } } write_leds(); }else{ if( s == BOOT_S ) { if( rt >= settings.sunrise_start ) { s = SUNRISE_S; printf("SUNRISE_S\n"); } if( rt >= settings.sunrise_end ) { s = MORNING_S; printf("MORNING_S\n"); } } else if( s == SUNRISE_S ){ if( rt >= settings.sunrise_end ) { s = MORNING_S; printf("MORNING_S\n"); }else{ int steps = (settings.sunrise_end - settings.sunrise_start)*(1000/50); int t = (rt - settings.sunrise_start)*(1000/50); for(; t < steps && !maual_mode; t++) { for(int j = 0; j < 4; j++) for(int i = 0; i < 10; i++){ float val = (-i*30.+t*3.*(4./5.))/(float)steps; leds[j][i].global.mod = 8 + fade(val,0.,0.5)*23; leds[j][i].r = fade(val,0.01,1.) * white.r; leds[j][i].g = fade(val,0.1,0.5) * white.g; leds[j][i].b = fade(val,0.6,0.7) * white.b; } write_leds(); if ((t%25)==0) { printf("Time: %d%% %d %d/%d\n", (t*100)/steps, (int)day_seconds(), t, steps); printf("%d %d %d %d\n", leds[0][0].global.mod, leds[0][0].r, leds[0][0].g, leds[0][0].b); } vTaskDelay(50/portTICK_PERIOD_MS); } } } else if( s == MORNING_S ) { if( rt >= settings.sunrise_shutdown ) { s = DAY_S; printf("DAY_S\n"); }else{ for(int j = 0; j < 4; j++) for(int i = 0; i < 10; i++){ leds[j][i].global.mod = 31; leds[j][i].r = white.r; leds[j][i].g = white.g; leds[j][i].b = white.b; } write_leds(); } } else if( s == DAY_S ) { if( rt >= settings.sunset_time ) { s = NIGHT_S; printf("NIGHT_S\n"); }else{ for(int j = 0; j < 4; j++) for(int i = 0; i < 10; i++){ leds[j][i].global.mod = 0; leds[j][i].r = 0; leds[j][i].g = 0; leds[j][i].b = 0; } write_leds(); } } else if( s == NIGHT_S ) { if( rt >= settings.sunrise_start && rt < settings.sunset_time) { s = SUNRISE_S; printf("SUNRISE_S\n"); } } } vTaskDelay(1000/portTICK_PERIOD_MS); } } extern "C" void register_app(void) { xTaskCreate(loop, "loop", 1024, NULL, 2, NULL); }