From 6533eb9cf1d72c61ac63833edc2d6c2a22cb3e80 Mon Sep 17 00:00:00 2001 From: Max Braungardt Date: Fri, 23 Mar 2018 00:03:12 +0100 Subject: [PATCH] Finished LED Rainbow --- sketches/led-driver/Makefile | 14 +- sketches/led-driver/a.out | Bin 3428 -> 0 bytes sketches/led-driver/colors.h | 26 +++ sketches/led-driver/colors.notc | 62 +++++++ sketches/led-driver/led-driver.c | 244 +++++++++++++++++++------- sketches/led-driver/old-but-gold.jojo | 203 +++++++++++++++++++++ 6 files changed, 485 insertions(+), 64 deletions(-) delete mode 100755 sketches/led-driver/a.out create mode 100644 sketches/led-driver/colors.h create mode 100644 sketches/led-driver/colors.notc create mode 100644 sketches/led-driver/old-but-gold.jojo diff --git a/sketches/led-driver/Makefile b/sketches/led-driver/Makefile index 8dd6f30..7cefb7c 100644 --- a/sketches/led-driver/Makefile +++ b/sketches/led-driver/Makefile @@ -1,9 +1,10 @@ -CFLAGS = -O3 -Wall --std=c11 +CFLAGS = -Os -Wall --std=c11 -g CHIP = atmega328p SOURCE_FILES = $(wildcard *.c) OBJ_FILES = $(SOURCE_FILES:%.c=%.o) BIN = led-driver.bin HEX = led-driver.hex +ASM = led-driver.asm default: $(HEX) @@ -13,11 +14,18 @@ default: $(HEX) $(BIN): $(OBJ_FILES) avr-gcc $(CFLAGS) -o $@ $^ +$(ASM): $(BIN) + avr-objdump -d -g -l -S $^ > $@ + $(HEX): $(BIN) avr-objcopy -O ihex -j .text -j .data $^ $@ +asm: $(ASM) + flash: $(HEX) - avrdude -p $(CHIP) -c arduino -B 115200 -P /dev/ttyACM1 -v -v -e -Uflash:w:$(HEX):a + avrdude -p $(CHIP) -c arduino -B 115200 -P /dev/ttyACM0 -v -v -e -Uflash:w:$(HEX):a clean: - $(RM) $(OBJ_FILES) $(BIN) $(HEX) + $(RM) $(OBJ_FILES) $(BIN) $(HEX) $(ASM) + + diff --git a/sketches/led-driver/a.out b/sketches/led-driver/a.out deleted file mode 100755 index c04cebb451a9ad94dffcc5ae3fe516d3e4ca3dde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3428 zcmeHKJ7^R^7@l0Bi4Zjre1L@~hz}%-ce!XHs8P|V1QA8iYFY0l$zpc**xSS?f)Nx2 z8;hu5tBswYg*Ha8Q`AbZl30t6vx#7Fe*er(_P^0W3kx9wGxL4(Klk6+nY)Yo2KP5L zH3`!);+Qb3fW>v~LR`UI5LuBC8%3K~pyY`$!2GR6_XWTibg~~J(ln`LK&maoNV4{+ z0{YH>-aFT=dHUwdyP5aXucntw^&{TdO#74&mu9X$x%Ncoq{mf{Ir|mQYtPq&D)7JV z6Z`G``W%frd|uzKz~9#A#)msMtFz+S%U9p0YHtSi?%kf%l+Q z_fIyH5t|wB0MA+aJ1lRuSSzL_DQdcSV$7Spkh3g(W;vR5a4F)whx^F;%Bq+PF z99HRHGz^ys=T{mV#30Onm~+4^wq2&WQBN4eneP zk<~j-Ih$n3t$s%H#5#yB6V{4n@G8`S-{`wn&?|;ajdT7e5#xIc!}J==dT)yJTg-R( zC-Z73;nUJL0`3p>AAlK>jM`ds!t{TD8vU0r=N)luchxpvBt4S^`RmjoHImH8TiN;q x^!gdEf11jc-&T*IcaZ6kFKRTK9Ei6d(FZW37>kLccc3pq=l&jHAz+5a-%m +#include + +#define RGB_MAX 128 + +typedef struct { + uint8_t r; + uint8_t g; + uint8_t b; +} rgb_t; + +typedef struct { + uint16_t hue; + uint8_t sat; + uint8_t val; +} hsv_t; + +hsv_t makeHSV(uint16_t hue, uint8_t sat, uint8_t val); +rgb_t hsv2rgb(hsv_t* hsv); +void hsv2rgbList(hsv_t* hsv, rgb_t* rgb, size_t count); +void interpolateLinearly(hsv_t start, hsv_t end, size_t steps, hsv_t *colors); + +#endif diff --git a/sketches/led-driver/colors.notc b/sketches/led-driver/colors.notc new file mode 100644 index 0000000..90c0a86 --- /dev/null +++ b/sketches/led-driver/colors.notc @@ -0,0 +1,62 @@ +#include "colors.h" + +void interpolateLinearly(hsv_t start, hsv_t end, size_t steps, hsv_t *colors) { + if( steps == 1 ) { + colors[0] = start; + return; + } + + for( size_t i = 0; i < steps; i++ ) { + hsv_t tmp; + tmp.hue = (uint16_t)((int16_t)start.hue + ((int16_t)end.hue - (int16_t)start.hue) * (int16_t)i / ((int16_t)steps-1)); + tmp.sat = (uint8_t)((int16_t)start.sat + ((int16_t)end.sat - (int16_t)start.sat) * (int16_t)i / ((int16_t)steps-1)); + tmp.val = (uint8_t)((int16_t)start.val + ((int16_t)end.val - (int16_t)start.val) * (int16_t)i / ((int16_t)steps-1)); + colors[i] = tmp; + } +} + +void hsv2rgbList(hsv_t* hsv, rgb_t* rgb, size_t count) { + for(size_t i = 0; i < count; ++i) { + rgb[i] = hsv2rgb(&hsv[i]); + } +} + +rgb_t hsv2rgb(hsv_t* hsv) { + rgb_t res; + + if(hsv->sat == 0) { + res.r = res.g = res.b = hsv->val; + } else { + float hue = (float) (hsv->hue<360?hsv->hue:hsv->hue-360); + float val = ((float) hsv->val ) / 100.0; + float sat = ((float) hsv->sat ) / 100.0; + + uint8_t h = hue / 60; + float f = ( hue / 60 ) - h; + + uint8_t p = RGB_MAX * ( val * ( 1 - sat )); + uint8_t q = RGB_MAX * ( val * ( 1 - sat * f )); + uint8_t t = RGB_MAX * ( val * ( 1 - sat * ( 1 - f ))); + + switch(h) { + case 0: + case 6: res.r = hsv->val; res.g = t; res.b = p; break; + case 1: res.r = q; res.g = hsv->val; res.b = p; break; + case 2: res.r = p; res.g = hsv->val; res.b = t; break; + case 3: res.r = p; res.g = q; res.b = hsv->val; break; + case 4: res.r = t; res.g = p; res.b = hsv->val; break; + case 5: res.r = hsv->hue; res.g = p; res.b = q; break; + + } + } + return res; +} + +hsv_t makeHSV(uint16_t hue, uint8_t sat, uint8_t val) { + hsv_t tmp; + tmp.hue = hue; + tmp.sat = sat; + tmp.val = val; + + return tmp; +} diff --git a/sketches/led-driver/led-driver.c b/sketches/led-driver/led-driver.c index 3f737af..852e1c3 100644 --- a/sketches/led-driver/led-driver.c +++ b/sketches/led-driver/led-driver.c @@ -1,36 +1,19 @@ -#define F_CPU 20000000UL #include +#include #include +#define F_CPU 20000000UL #include +#include #define BAUD 9600 #include +#include "colors.notc" - - -void uart_init(void) { - #define BAUDRATE ((F_CPU)/(BAUD*8UL)-1) // set baud rate value for UBRR - UBRR0H = (BAUDRATE>>8); // shift the register right by 8 bits to get the upper 8 bits - UBRR0L = BAUDRATE; // set baud rate - - // UCSR0A |= (1 << U2X0); // double transmission speed - // UCSR0B = (1 << TXEN0) | (1 << RXEN0); - // UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); - - // UBRR0H = UBRRH_VALUE; - // UBRR0L = UBRRL_VALUE; - - - UCSR0A |= _BV(U2X0); - // UCSR0A &= ~(_BV(U2X0)); - - - // UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */ - UCSR0C = 0x06; /* 8-bit data */ - UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0); /* Enable RX and TX */ - - -} +/* + 255 0 0 + 255 255 0 + 0 0 255 + */ /* // f=20MHz -> T=0,05 µs @@ -41,12 +24,130 @@ uint8_t T1L = 8; // == 0.35 µs ~ 0.45µs (+- 150ns) == [0.30, 0.60] µs uint8_t RES = 51; // > 50 µs */ -#define wait6 __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t") -#define wait8 __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t") -#define wait14 __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t") -#define wait15 __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t") +// #define VAR1 -uint8_t const CMAX = 32; +#ifdef VAR1 + #define nop __asm__ ("nop") + + #define wait6 __asm__ ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop") + #define wait8 __asm__ ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop") + #define wait14 __asm__ ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop") + #define wait15 __asm__ ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop") +#else + // https://github.com/cpldcpu/light_ws2812/blob/master/light_ws2812_AVR/Light_WS2812/light_ws2812.c + #define w_nop1 __asm__("nop \n\t") + #define w_nop2 __asm__("rjmp .+0 \n\t") + #define w_nop4 w_nop2; w_nop2 + #define w_nop8 w_nop4; w_nop4 + #define w_nop16 w_nop8; w_nop8 + + #define wait6 w_nop2; w_nop4 + #define wait8 w_nop4; w_nop4 + #define wait14 wait8; wait6 + #define wait15 wait14; w_nop1 +#endif + +#define HUE_DEGREE 120 +#define HUE_MAX 610 +#define HUE_MIN 350 +#define LEDS 30 +#define DELAYS 536 + +void uart_init(); +void writeZero(); +void writeOne(); +void writeRGB(uint8_t red, uint8_t green, uint8_t blue); +void writeNothing(uint8_t c); + +void mydelay(uint16_t ms) { + while(ms--) { + _delay_loop_2(5000); // 1ms + } +} + +int mainz() +{ + DDRC = 1; + uint8_t d = 14; + + while(1) + { + for(int i = 0; i < LEDS; i += 1) + writeRGB(85,0,0); + + mydelay(DELAYS); + + for(int i = 0; i < LEDS; i += 1) + writeRGB(0,0,85); + + mydelay(DELAYS); + + //~ for(int i = 0; i < LEDS; i += 1) + //~ writeRGB(0,128,0); + + //~ mydelay(DELAYS); + } + + return 0; +} + +int main() { + DDRC = 1; // PORT C0 output + // uart_init(); + + uint16_t min = HUE_MIN, max = HUE_MAX; + uint8_t vl = 40; + uint16_t steps = 1; + bool falling = true; + hsv_t colorsHSV[LEDS]; + rgb_t colorsRGB[LEDS]; + + do{ + //~ if(left == 360){ + //~ left = 180; + //~ right = 360; + //~ }else{ + //~ left = 360; + //~ right = 180; + //~ } + + interpolateLinearly(makeHSV(min, 100, 30), makeHSV(max, 100, 30), LEDS, colorsHSV); + + hsv2rgbList(colorsHSV, colorsRGB, LEDS); + + for( int i = 0; i < LEDS; i++){ + writeRGB( colorsRGB[i].r, colorsRGB[i].g, colorsRGB[i].b); + } + + // switch + if(falling){ + min = min + steps; + max = max - steps; + } else { + min = min - steps; + max = max + steps; + } + + if(min == HUE_MAX || max == HUE_MAX) { + falling = !falling; + } + + // pulse + //~ if(falling){ + //~ vl -= steps; + //~ // right = right - steps; + //~ } else { + //~ vl += steps; + //~ right = right + steps; + //~ } + + //~ if(vl == 5 || vl == 40){ + //~ falling = !falling; + //~ } + + //_delay_us(100); + }while(true); +} inline void writeZero() { PORTC = 1; @@ -62,39 +163,60 @@ inline void writeOne() { wait8; } -int main() { - DDRC = 1; // PORT C0 output - // uart_init(); +void writeRGB(uint8_t red, uint8_t green, uint8_t blue) { + int i; - do{ - // for( int i = 0; i < 7; i++) { - // if( i%2==0){ - writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeOne(); - writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero(); - writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero(); - // } else { - writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero(); - writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero(); - writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero();writeZero(); - // } - - // } - _delay_ms(500); - - - // loop_until_bit_is_set(UCSR0A, UDRE0); - // UDR0 = 'D'; + for( i = 128; i > 0; i >>= 1 ) { + if( green & i ){ + writeOne(); + } else { + writeZero(); + } + } - }while(1); + for( i = 128; i > 0; i >>= 1 ) { + if( red & i ){ + writeOne(); + } else { + writeZero(); + } + } + + for( i = 128; i > 0; i >>= 1 ) { + if( blue & i ){ + writeOne(); + } else { + writeZero(); + } + } } -int main2( void ) -{ - DDRC = 0xff; // (1 << PC0); +void uart_init(void) { + #define BAUDRATE ((F_CPU)/(BAUD*8UL)-1) // set baud rate value for UBRR + UBRR0H = (BAUDRATE>>8); // shift the register right by 8 bits to get the upper 8 bits + UBRR0L = BAUDRATE & 0xff; // set baud rate + + // UCSR0A |= (1 << U2X0); // double transmission speed + // UCSR0B = (1 << TXEN0) | (1 << RXEN0); + // UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); + + // UBRR0H = UBRRH_VALUE; + // UBRR0L = UBRRL_VALUE; + - while(1) { - PORTC ^= 0xff; //(1 << PC0); - _delay_ms(1000); - } - return 0; + UCSR0A |= _BV(U2X0); + // UCSR0A &= ~(_BV(U2X0)); + + + // UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */ + UCSR0C = 0x06; /* 8-bit data */ + UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0); /* Enable RX and TX */ +} + + +void writeNothing(uint8_t c){ + for(uint8_t i = 0; i < c; i++){ + writeRGB(0,0,0); + } + _delay_ms(500); } diff --git a/sketches/led-driver/old-but-gold.jojo b/sketches/led-driver/old-but-gold.jojo new file mode 100644 index 0000000..29f6c72 --- /dev/null +++ b/sketches/led-driver/old-but-gold.jojo @@ -0,0 +1,203 @@ +#define F_CPU 20000000UL +#include +#include +#include +#define BAUD 9600 +#include + + + + +void uart_init(void) { + #define BAUDRATE ((F_CPU)/(BAUD*8UL)-1) // set baud rate value for UBRR + UBRR0H = (BAUDRATE>>8); // shift the register right by 8 bits to get the upper 8 bits + UBRR0L = BAUDRATE; // set baud rate + + // UCSR0A |= (1 << U2X0); // double transmission speed + // UCSR0B = (1 << TXEN0) | (1 << RXEN0); + // UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); + + // UBRR0H = UBRRH_VALUE; + // UBRR0L = UBRRL_VALUE; + + + UCSR0A |= _BV(U2X0); + // UCSR0A &= ~(_BV(U2X0)); + + + // UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */ + UCSR0C = 0x06; /* 8-bit data */ + UCSR0B = _BV(RXEN0) | _BV(TXEN0) | _BV(RXCIE0); /* Enable RX and TX */ + + +} + +/* +// f=20MHz -> T=0,05 µs +uint8_t T0H = 6; // == 0.3 µs ~ 0.4 µs (+- 150ns) == [0.25, 0.55] µs +uint8_t T1H = 14; // == 0.7 µs ~ 0.8 µs (+- 150ns) == [0.65, 0.95] µs +uint8_t T0L = 15; // == 0.75 µs ~ 0.85µs (+- 150ns) == [0.70, 1.00] µs +uint8_t T1L = 8; // == 0.35 µs ~ 0.45µs (+- 150ns) == [0.30, 0.60] µs +uint8_t RES = 51; // > 50 µs +*/ + +#define nop __asm__("nop\n\t") +#define wait6 __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t") +#define wait8 __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t") +#define wait14 __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t") +#define wait15 __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t") + +uint8_t const CMAX = 32; +uint8_t const STEPWIDTH = 4; + +void writeZero(); +void writeOne(); +void writeRGB(uint8_t red, uint8_t green, uint8_t blue); + +static uint8_t dNext[] = {1,2,0}; + +int main() { + DDRC = 1; // PORT C0 output + // uart_init(); + uint8_t d = 0; + uint8_t r = 120, g = 120, b = 0; + +/* + 255 0 0 + 255 255 0 + 0 0 255 + */ + + + do{ + for(uint8_t i = 120; i > 0; i -= STEPWIDTH) { + if( i >= 60 ) + writeRGB( 120, (120-i)*2 , 0 ); + if( i <= 60 ) + writeRGB( i, (60+i)/2, 120-i); + } + _delay_ms(500); + + + /*if( d == 0 ) { + do{ + for( uint8_t i = 0; i < 10; i++) { + writeRGB(r,g,b); + } + for( uint8_t i = 0; i < 10; i++) { + writeRGB(b,g,r); + } + for( uint8_t i = 0; i < 10; i++) { + writeRGB(g,r,b); + } + _delay_ms(1); + r -=1; + b +=1; + }while(r > 0); + + } + if( d == 1 ) { + do{ + for( uint8_t i = 0; i < 10; i++) { + writeRGB(r,g,b); + } + for( uint8_t i = 0; i < 10; i++) { + writeRGB(b,g,r); + } + for( uint8_t i = 0; i < 10; i++) { + writeRGB(g,r,b); + } + _delay_ms(1); + r +=1; + g -=1; + }while(g > 0); + + } + if( d == 2 ) { + do{ + for( uint8_t i = 0; i < 10; i++) { + writeRGB(r,g,b); + } + for( uint8_t i = 0; i < 10; i++) { + writeRGB(b,g,r); + } + for( uint8_t i = 0; i < 10; i++) { + writeRGB(g,r,b); + } + _delay_ms(1); + b -=1; + g +=1; + }while(b > 0); + + } + /* for( int i = 0; i<30; i++) { + // if( d == 0 ) + writeRGB(r,g,b); + if( d == 1 ) + writeRGB(0,128,0); + if( d == 2 ) + writeRGB(0,0,128); + d = dNext[d]; + }*/ + // _delay_ms(500); + d = dNext[d]; + + + // loop_until_bit_is_set(UCSR0A, UDRE0); + // UDR0 = 'D'; + + }while(1); +} + +int main2( void ) +{ + DDRC = 0xff; // (1 << PC0); + + while(1) { + PORTC ^= 0xff; //(1 << PC0); + _delay_ms(1000); + } + return 0; +} + +void writeZero() { + PORTC = 1; + wait6; + PORTC = 0; + wait15; +} + +void writeOne() { + PORTC = 1; + wait14; + PORTC = 0; + wait8; +} + +void writeRGB(uint8_t red, uint8_t green, uint8_t blue) { + int i,j; + + for( i = 128; i > 0; i >>= 1 ) { + if( green & i ){ + writeOne(); + } else { + writeZero(); + } + } + + for( i = 128; i > 0; i >>= 1 ) { + if( red & i ){ + writeOne(); + } else { + writeZero(); + } + } + + for( i = 128; i > 0; i >>= 1 ) { + if( blue & i ){ + writeOne(); + } else { + writeZero(); + } + } +}