راه‌اندازی و کنترل نوار ال‌ای‌دی ws2812 با ATtiny26L

از پاپیروس
پرش به ناوبریپرش به جستجو

فایل‌ها

light_ws2812.h

light_ws2812.c

ws2812_config.h

Makefile

شماتیک هر سه حالت در قالب نرم افزار ایگل ۷.۳.۰

با کلید و بدون ولوم تنظیم سرعت تغییر رنگ

شماتیک

Left

کد برنامه (فایل main.c)

#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include "light_ws2812.h"
#define	PIXEL_NUM	(8)

struct pixel {
	uint8_t g;
	uint8_t r;
	uint8_t b;
} pixels[PIXEL_NUM];


volatile unsigned int		i,j;



int main(void)
{
	DDRA=DDRA & ~(1<<1);
	
	struct pixel p = {255, 0, 0};
	struct pixel q = {0, 255, 0};
	struct pixel r = {0, 0, 255};
	struct pixel s = {255, 0, 255};
	ws2812_setleds((struct cRGB *)&s, 1);
	_delay_ms(1000);

	/* loop */
	while (1) {
		if(PINA & (1<<1))
		{
			if ((i++ % 6)==0)
			{
				j++;
			}
			if (i>PIXEL_NUM*100)
			{
				i=0;
				j=0;
			}
			if (p.r > 0 && p.b == 0) {
				p.r--;
				p.g++;
			}
			if (p.g > 0 && p.r == 0) {
				p.g--;
				p.b++;
			}
			if (p.b > 0 && p.g == 0) {
				p.r++;
				p.b--;
			}

			if (q.r > 0 && q.b == 0) {
				q.r--;
				q.g++;
			}
			if (q.g > 0 && q.r == 0) {
				q.g--;
				q.b++;
			}
			if (q.b > 0 && q.g == 0) {
				q.r++;
				q.b--;
			}

			if (r.r > 0 && r.b == 0) {
				r.r--;
				r.g++;
			}
			if (r.g > 0 && r.r == 0) {
				r.g--;
				r.b++;
			}
			if (r.b > 0 && r.g == 0) {
				r.r++;
				r.b--;
			}

			if (s.r > 0 && s.b == 0) {
				s.r=s.r-1;
				s.g=s.g+1;
			}
			if (s.g > 0 && s.r == 0) {
				s.g=s.g-1;
				s.b=s.b+1;
			}
			if (s.b > 0 && s.g == 0) {
				s.r=s.r+1;
				s.b=s.b-1;
			}

			pixels[(j+0) % 8] = p;
			pixels[(j+1) % 8] = p;
			pixels[(j+2) % 8] = p;
			pixels[(j+3) % 8] = p;
			pixels[(j+4) % 8] = p;
			pixels[(j+5) % 8] = p;
			pixels[(j+6) % 8] = p;
			pixels[(j+7) % 8] = p;
			ws2812_setleds((struct cRGB *)pixels, 8);
			_delay_ms(10);
		}
	}
}

با کلید و با ولوم تنظیم سرعت تغییر رنگ

شماتیک

Left

کد برنامه (فایل main.c)

#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include "light_ws2812.h"

#define	PIXEL_NUM	(8)

static inline void initADC(void) {
ADMUX |= (1 << REFS0) | (1<<MUX1) | (1<<MUX2); //reference voltage on AVCC
ADCSR |= (1 << ADPS2) | (1 << ADPS1); //ADC clock prescaler /64
ADCSR |= (1 << ADEN); //enables the ADC
}

void my_delay_ms(int ms) {
	while (ms--) {
		_delay_ms(1);
	}
}


struct pixel {
	uint8_t g;
	uint8_t r;
	uint8_t b;
} pixels[PIXEL_NUM];


volatile unsigned int		i,j;

int main(void)
{
	DDRA=DDRA & ~(1<<1);
	initADC();

	uint16_t potentiometerValue;
	uint16_t threshold_level;
	threshold_level= 512;

	DDRA=DDRA & ~(1<<1);

	ADCSR |= (1 << ADSC); //start ADC conversion
	loop_until_bit_is_clear(ADCSR, ADSC); //wait until ADC conversion is done
	potentiometerValue= ADC; //read ADC value in

	struct pixel p = {255, 0, 0};
	struct pixel q = {0, 255, 0};
	struct pixel r = {0, 0, 255};
	struct pixel s = {255, 0, 255};
	if ((i++ % 6)==0)
	{
		j++;
	}
	if (i>PIXEL_NUM*100)
	{
		i=0;
		j=0;
	}
	if (p.r > 0 && p.b == 0) {
		p.r--;
		p.g++;
	}
	if (p.g > 0 && p.r == 0) {
		p.g--;
		p.b++;
	}
	if (p.b > 0 && p.g == 0) {
		p.r++;
		p.b--;
	}
	if (q.r > 0 && q.b == 0) {
		q.r--;
		q.g++;
	}
	if (q.g > 0 && q.r == 0) {
		q.g--;
		q.b++;
	}
	if (q.b > 0 && q.g == 0) {
		q.r++;
		q.b--;
	}
	if (r.r > 0 && r.b == 0) {
		r.r--;
		r.g++;
	}
	if (r.g > 0 && r.r == 0) {
		r.g--;
		r.b++;
	}
	if (r.b > 0 && r.g == 0) {
		r.r++;
		r.b--;
	}
	if (s.r > 0 && s.b == 0) {
		s.r=s.r-1;
		s.g=s.g+1;
	}
	if (s.g > 0 && s.r == 0) {
		s.g=s.g-1;
		s.b=s.b+1;
	}
	if (s.b > 0 && s.g == 0) {
		s.r=s.r+1;
		s.b=s.b-1;
	}
	for (int m=0; m<PIXEL_NUM; m++)
	{
		pixels[(4+m) % PIXEL_NUM] = s;
	}

	ws2812_setleds((struct cRGB *)pixels, PIXEL_NUM);

	while (1) {
		if(PINA & (1<<1))
		{
			if ((i++ % 6)==0)
			{
				j++;
			}
			if (i>PIXEL_NUM*100)
			{
				i=0;
				j=0;
			}
			if (p.r > 0 && p.b == 0) {
				p.r--;
				p.g++;
			}
			if (p.g > 0 && p.r == 0) {
				p.g--;
				p.b++;
			}
			if (p.b > 0 && p.g == 0) {
				p.r++;
				p.b--;
			}
			if (q.r > 0 && q.b == 0) {
				q.r--;
				q.g++;
			}
			if (q.g > 0 && q.r == 0) {
				q.g--;
				q.b++;
			}
			if (q.b > 0 && q.g == 0) {
				q.r++;
				q.b--;
			}
			if (r.r > 0 && r.b == 0) {
				r.r--;
				r.g++;
			}
			if (r.g > 0 && r.r == 0) {
				r.g--;
				r.b++;
			}
			if (r.b > 0 && r.g == 0) {
				r.r++;
				r.b--;
			}
			if (s.r > 0 && s.b == 0) {
				s.r=s.r-1;
				s.g=s.g+1;
			}
			if (s.g > 0 && s.r == 0) {
				s.g=s.g-1;
				s.b=s.b+1;
			}
			if (s.b > 0 && s.g == 0) {
				s.r=s.r+1;
				s.b=s.b-1;
			}
			for (int m=0; m<PIXEL_NUM; m++)
			{
			pixels[(4+m) % PIXEL_NUM] = r;
			}
			/*
			pixels[(j+4) % 8] = p;
			pixels[(j+5) % 8] = p;
			pixels[(j+6) % 8] = p;
			pixels[(j+7) % 8] = p;
			*/
			//ws2812_setleds((struct cRGB *)&p, 1);
			//ws2812_setleds((struct cRGB *)&p, 1);
			ws2812_setleds((struct cRGB *)pixels, PIXEL_NUM);

			ADCSR |= (1 << ADSC); //start ADC conversion
			loop_until_bit_is_clear(ADCSR, ADSC); //wait until ADC conversion is done
			potentiometerValue= ADC; //read ADC value in


			int total_delay;
			total_delay = potentiometerValue*10/1023;
			
			my_delay_ms(total_delay);
		}
	}
}

با دکمه فشاری (به جای کلید) و با ولوم تنظیم سرعت تغییر رنگ

شماتیک

Left

کد برنامه (فایل main.c)

#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdbool.h>
#include "light_ws2812.h"

#define	PIXEL_NUM	(8)

volatile bool ccVar;
ISR(INT0_vect)
{
	_delay_ms(150);  	/* Software debouncing control delay */
	ccVar = !ccVar;
	GIFR = (1<<INTF0);
}


static inline void initADC(void) {
ADMUX |= (1 << REFS0) | (1<<MUX1) | (1<<MUX2); //reference voltage on AVCC
ADCSR |= (1 << ADPS2) | (1 << ADPS1); //ADC clock prescaler /64
ADCSR |= (1 << ADEN); //enables the ADC
}

void my_delay_ms(int ms) {
	while (ms--) {
		_delay_ms(1);
	}
}


struct pixel {
	uint8_t g;
	uint8_t r;
	uint8_t b;
} pixels[PIXEL_NUM];


volatile unsigned int		i,j;

int main(void)
{
	DDRB &= ~(1<<PB6);
	PORTB |= (1<<PB6);
	GIMSK |= (1<<INT0);
	MCUCR = (0<<ISC01) | (0<<ISC00);
	sei();

	initADC();

	uint16_t potentiometerValue;
	uint16_t threshold_level;
	threshold_level= 512;

	ADCSR |= (1 << ADSC); //start ADC conversion
	loop_until_bit_is_clear(ADCSR, ADSC); //wait until ADC conversion is done
	potentiometerValue= ADC; //read ADC value in

	struct pixel p = {255, 0, 0};
	struct pixel q = {0, 255, 0};
	struct pixel r = {0, 0, 255};
	struct pixel s = {255, 0, 255};
	if ((i++ % 6)==0)
	{
		j++;
	}
	if (i>PIXEL_NUM*100)
	{
		i=0;
		j=0;
	}
	if (p.r > 0 && p.b == 0) {
		p.r--;
		p.g++;
	}
	if (p.g > 0 && p.r == 0) {
		p.g--;
		p.b++;
	}
	if (p.b > 0 && p.g == 0) {
		p.r++;
		p.b--;
	}
	if (q.r > 0 && q.b == 0) {
		q.r--;
		q.g++;
	}
	if (q.g > 0 && q.r == 0) {
		q.g--;
		q.b++;
	}
	if (q.b > 0 && q.g == 0) {
		q.r++;
		q.b--;
	}
	if (r.r > 0 && r.b == 0) {
		r.r--;
		r.g++;
	}
	if (r.g > 0 && r.r == 0) {
		r.g--;
		r.b++;
	}
	if (r.b > 0 && r.g == 0) {
		r.r++;
		r.b--;
	}
	if (s.r > 0 && s.b == 0) {
		s.r=s.r-1;
		s.g=s.g+1;
	}
	if (s.g > 0 && s.r == 0) {
		s.g=s.g-1;
		s.b=s.b+1;
	}
	if (s.b > 0 && s.g == 0) {
		s.r=s.r+1;
		s.b=s.b-1;
	}
	for (int m=0; m<PIXEL_NUM; m++)
	{
		pixels[(4+m) % PIXEL_NUM] = s;
	}

	ws2812_setleds((struct cRGB *)pixels, PIXEL_NUM);

	while (1) {
		if(!ccVar)
		{
			if ((i++ % 6)==0)
			{
				j++;
			}
			if (i>PIXEL_NUM*100)
			{
				i=0;
				j=0;
			}
			if (p.r > 0 && p.b == 0) {
				p.r--;
				p.g++;
			}
			if (p.g > 0 && p.r == 0) {
				p.g--;
				p.b++;
			}
			if (p.b > 0 && p.g == 0) {
				p.r++;
				p.b--;
			}
			if (q.r > 0 && q.b == 0) {
				q.r--;
				q.g++;
			}
			if (q.g > 0 && q.r == 0) {
				q.g--;
				q.b++;
			}
			if (q.b > 0 && q.g == 0) {
				q.r++;
				q.b--;
			}
			if (r.r > 0 && r.b == 0) {
				r.r--;
				r.g++;
			}
			if (r.g > 0 && r.r == 0) {
				r.g--;
				r.b++;
			}
			if (r.b > 0 && r.g == 0) {
				r.r++;
				r.b--;
			}
			if (s.r > 0 && s.b == 0) {
				s.r=s.r-1;
				s.g=s.g+1;
			}
			if (s.g > 0 && s.r == 0) {
				s.g=s.g-1;
				s.b=s.b+1;
			}
			if (s.b > 0 && s.g == 0) {
				s.r=s.r+1;
				s.b=s.b-1;
			}
			for (int m=0; m<PIXEL_NUM; m++)
			{
			pixels[(4+m) % PIXEL_NUM] = r;
			}

			ws2812_setleds((struct cRGB *)pixels, PIXEL_NUM);

			ADCSR |= (1 << ADSC); //start ADC conversion
			loop_until_bit_is_clear(ADCSR, ADSC); //wait until ADC conversion is done
			potentiometerValue= ADC; //read ADC value in


			int total_delay;
			total_delay = potentiometerValue*10/1023;
			
			my_delay_ms(total_delay);
		}
	}
}