För över 25 år sedan gjorde min mormor och morfar en ängel till min mor, ca 4,5dm hög.
Från början hade hon små glödlampor som låga i ljusen hon höll i händerna men de har i olika omgångar under årens lopp gått sönder och bytts ut mot andra glödlampor och under senare år även LED's.
så i höstas bestämde jag mig, när jag såg den hemma hos mina förldrar, att bygga om den, så ljusen ser lite mer verkliga ut.
Sagt och gjort, för det första filade jag till 2st vanlga 5mm röda LEDar så de mer ser ut som lågor.
Sen programmerade jag en AVR (ATTINY22 som helt utgått men är kompatibel med AT90S2343) med intärn RC-oscillator på 1MHz att slumpa ut två värden som ska driva två mjukvaruPWMer
Här är källkoden (C++, CodeVision):
Kod: Markera allt
/*********************************************
Project : Lucia (Ängel)
Version : 0.01
Date : 2004-11-28
Author : Xyzzy
Comments:
Julängeln som har ett ljus i varje hand:
ljusen (LEDarna, filade som lågor) dimrar slumpmässigt för att efterlikna stearinljus.
Använder intärn RC-oscillator (väljs när man flashar microcontrollern)
Chip type : AT90S2343
Clock frequency : 1,000000 MHz
Memory model : Tiny
Internal SRAM size : 128
External SRAM size : 0
Data Stack size : 32
*********************************************/
#include <90s2343.h>
#include <delay.h>
#include <stdlib.h> //ta bort om RAND inte används
#define min 250 //255 => svagt sken, 0 => starkt sken
#define max 122 //255 => svagt sken, 0 => starkt sken
#define start 240 //255 => svagt sken, 0 => starkt sken
char pwm1, pwm2;
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
char i;
// Reinitialize Timer's 0 value
TCNT0=0xF5; //Högre värde => interruptet körs oftare
for(i = 255; i > 0; i--) //mjukvaruPWM 2 kanaler
{
if(pwm1 > i)
PORTB.3 = 1;
else
PORTB.3 = 0;
if(pwm2 > i)
PORTB.4 = 1;
else
PORTB.4 = 0;
}
}
void main(void)
{
char i1, i2, speed;
// Input/Output Ports initialization
// Port B
PORTB=0x18;
DDRB=0x1F;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 0,977 kHz
// Mode: Output Compare
// OC0 output: Disconnected
TCCR0=0x05;
TCNT0=0x36;
// External Interrupt(s) initialization
// INT0: Off
GIMSK=0x00;
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;
srand(123); //sätt en random-flagga
i1 = i2 = start;
//Global enable interrupts
#asm ("sei")
while (1)
{
i1 = (rand() >> 8) + max; //((0~32768) >> 8) + max => (0~128) + max => max~min => (122~250)
i2 = (rand() >> 8) + max; //((0~32768) >> 8) + max => (0~128) + max => max~min => (122~250)
speed = (rand() / 7000) + 3; //((0~32768) / 7000) + 3 => (0~4) + 3 => max~min => (3~7)
while(pwm1 != i1 && pwm2 != i2) //justera de två pulsbredderna till slumpade värden med slumpad hastighet
{
if(pwm1 > i1)
pwm1--;
if(pwm1 < i1)
pwm1++;
if(pwm2 > i2)
pwm2--;
if(pwm2 < i2)
pwm2++;
delay_ms(speed);
}
};
}
Dessutom (för enkelhetens skull) la jag in mjukvaruPWMen i ett interrupt
2 videos "in action":
Film 1 (låg upplösning, dålig kamera. Ca 4MB)
Film 2 (Hög upplösning, dålig kamera, Ca 16MB)
Film 3 (Hög upplösning, bra kamera. Ca 7,4MB)
Det ser betydligt bättre ut i verkligheten, tack vare det slumpmässiga "fladdrandet".
Här är schemat på kopplingen:
Kom gärna med kommentarer och/eller frågor
// Xyzzy
[Edit1: lagt till två videosnuttar]
[Edit2: lagt till en videosnutt]