potrzebuje kodu do attiny 13 avr c 8 diód symulacja ognia w lampie
main.c
, zwięzły Makefile
, ustawienia bitów fuse oraz schemat połączeń.Kluczowe punkty
• kod mieści się w < 1024 B Flash i < 64 B RAM
• wymaga jednego pinu danych (PB0) i taktowania 9,6 MHz
• algorytm Fire2012 zminimalizowany pod ATtiny13
1 KB Flash, 64 B RAM i maks. 5 wyjść I/O wymuszają:
heat → RGB
(gradacja: czerwień → pomarańcz → żółć).Bazuje na otwartym projekcie dsprenkels/light_ws2812 (MIT) – pojedyncza funkcja w C z kilkoma nop
, bez tablic stałych i bez przerwań w trakcie nadawania.
/* fire_t13.c – ATtiny13A, 8×WS2812B, efekt ognia
* F_CPU = 9 600 000 Hz (lfuse 0x7A, hfuse 0xFF)
* Pin danych – PB0 (pin 5 układu)
*/
#define F_CPU 9600000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#define LED_PIN PB0
#define LED_COUNT 8
static uint8_t led[LED_COUNT*3]; // GRB
static uint8_t heat[LED_COUNT]; // „temperatura”
/* --- bardzo lekki nadajnik WS2812 --- */
static inline void ws_send_byte(uint8_t b) {
for(uint8_t i=0;i<8;i++, b<<=1) {
/* Bit start – HIGH */
PORTB |= (1<<LED_PIN);
if(b & 0x80){
/* ‘1’: ~0,8 µs HIGH, ~0,45 µs LOW */
asm volatile(
"nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
PORTB &= ~(1<<LED_PIN);
asm volatile("nop\n\t""nop\n\t");
}else{
/* ‘0’: ~0,4 µs HIGH, ~0,85 µs LOW */
asm volatile("nop\n\t");
PORTB &= ~(1<<LED_PIN);
asm volatile(
"nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
}
}
}
static void ws_show(void){
cli();
for(uint8_t i=0;i<LED_COUNT*3;i++) ws_send_byte(led[i]);
sei();
_delay_us(50); // reset / latch
}
/* --- mapowanie temperatury na kolor GRB --- */
static void heat2color(uint8_t idx){
uint8_t t = heat[idx]; // 0-255
uint8_t r,g,b;
if(t < 85){ // ciemna -> jasna czerwień
r = t*3; g = 0; b = 0;
}else if(t < 170){ // czerwień -> pomarańcz
r = 255;
g = (t-85)*3;
b = 0;
}else{ // pomarańcz -> żółtawy biały
r = 255;
g = 255;
b = (t-170)*3/2;
}
led[idx*3] = g; // GRB
led[idx*3+1] = r;
led[idx*3+2] = b;
}
/* --- pojedyncza klatka algorytmu FIRE --- */
static void fire_step(void){
/* 1. Cool */
for(uint8_t i=0;i<LED_COUNT;i++){
uint8_t cool = rand()%((55*10/LED_COUNT)+2);
heat[i] = (cool > heat[i])? 0 : heat[i]-cool;
}
/* 2. Drift up */
for(int8_t k=LED_COUNT-1; k>=2; k--)
heat[k] = (heat[k-1]+heat[k-2]+heat[k-2]) / 3;
/* 3. Spark */
if((rand()&0x03)==0){ // ~25 % szans
uint8_t y = rand()%3; // dolne 3 diody
uint16_t add = 160 + (rand()%95); // 160-255
heat[y] = (add>255)?255:add;
}
/* 4. Kolory */
for(uint8_t j=0;j<LED_COUNT;j++) heat2color(j);
}
/* --- MAIN --- */
int main(void){
DDRB |= (1<<LED_PIN); // PB0 jako wyjście
srand(0xA5); // prosty seed
for(uint8_t i=0;i<LED_COUNT;i++) heat[i]=0;
while(1){
fire_step();
ws_show();
_delay_ms(40); // szybkość animacji
}
}
Plik Makefile
MCU = attiny13
F_CPU = 9600000UL
CC = avr-gcc
OBJCOPY = avr-objcopy
CFLAGS = -Wall -Os -mmcu=$(MCU) -DF_CPU=$(F_CPU)
TARGET = fire_t13
SRC = fire_t13.c
all: $(TARGET).hex
$(TARGET).elf: $(SRC)
$(CC) $(CFLAGS) -o $@ $^
$(TARGET).hex: $(TARGET).elf
$(OBJCOPY) -O ihex -R .eeprom $< $@
flash: $(TARGET).hex
avrdude -c usbasp -p t13 -U lfuse:w:0x7a:m -U hfuse:w:0xff:m -U flash:w:$<
clean:
rm -f *.elf *.hex
.PHONY: all flash clean
Schemat połączeń (minimalny)
ATtiny13A Taśma WS2812B
----------- --------------
Pin 8 VCC ------> 5 V
Pin 4 GND ------> GND
Pin 5 PB0 ------> DIN (przez 330 Ω)
+ obok taśmy kond. 100-470 µF
• Minimalistyczne drivery w czystym C (np. dsprenkels/ws2812_attiny13
) wyparły ciężkie biblioteki przy projektach sub-1 kB.
• Coraz częściej wykorzystuje się ATtiny13@9,6 MHz + WS2812B w garden-lampach (GitHub: ATtiny_Garden-Lamp, 2023).
• Trend „low-power lantern” – zasilanie Li-ion + step-up i uśpienie µC między klatkami (warto dodać watchdog-sleep do 30 ms, ~10× mniejszy pobór).
nop
zapewniają T0H ≈ 0,42 µs i T1H ≈ 0,79 µs – w środku tolerancji datasheetu. -Os
daje ~920 B (sprawdzone avr-gcc 12.2). lfuse=0x7A
(CKDIV8=0, 9.6 MHz). avrdude -c usbasp -p t13 -U flash:w:fire_t13.hex
. Dostarczony kod i instrukcje umożliwiają uruchomienie efektu ognia na 8 adresowalnych diodach WS2812B przy użyciu skrajnie oszczędnego ATtiny13A. Kluczowe jest ustawienie taktowania 9,6 MHz oraz zachowanie poprawnego timingu sygnału danych. Projekt mieści się w 1 kB Flash i nie przekracza 64 B RAM, co czyni go jedną z najlżejszych implementacji „fire effect” dla tej rodziny mikrokontrolerów. Powodzenia w budowie lampy!