Jag tror jag får förtydliga mig en smula. Ber om ursäkt om det har varit rörigt.
Vi tar det i steg:
1. Jag kommer ha 60 lysdioder i en cirkel, inte 180 eller något annat (förutom om vi börjar prata rgb).
2. Det enklaste fallet är ett enda "rinnande ljus" som stegar en diod per sekund. Då är exakt en diod tänd hela tiden (och jag skulle i princip kunna skifta ett steg per sekund). Detta är (förstås) löst. Samma principutseende kommer vi ha hela tiden - typ en diod tänd, inte halvcirklar eller något.
3. Men nu vill jag dessutom ha tim- och minut-visare, så att det blir en riktig klocka. (Vi kan anta att om två visare ligger på samma diod, så ser det bara ut som en enda.)
Det är ju ganska enkelt, jag kan till exempel göra ngt i stil med:
Kod: Markera allt
int sec_pos = ..., min_pos = ..., hour_pos=...;
for(i=0; i<60; i++){
if(i == sec_pos || i == min_pos || i == hur_pos)
set_data_high(); // slå på "serial input"-utgången
else
set_data_low(); // slå av "serial input"-utgången
next_output(); //slå på och av klockan
}
update_output(); // slå på och av latchen.
Här funkar ju inte lösningen med att bara skifta ett steg per sekund, utan jag måste tömma alla shift-register varje gång (vilket görs implicit eftersom jag skiftar ut nya).
Här skulle jag kunna vara klar och montera upp skiten. Nackdelar med denna är att det är svårt att se vad som är timme och minut, och att den inte är så fräck.
Här är 1,2 eller 3 tända samtidigt.
4. Ytterligare en intressant grej jag skulle vilja ha är att få mjuka övergångar. Om vi då går tillbaka till steg 2 (bara sekundvisare), och lägga till detta på sekundvisaren skulle man kunna göra så här, med en slags hemmasnickrad kod-PWM:
Kod: Markera allt
iteration++; //denna räknas upp för varje iteration i main-loopen
if(iteration==10) iteration = 0;
int sec_pos = ..., tenth_of_second = ...;
for(i=0; i<60; i++){
if(i == sec_pos){
if(iteration > tenth_of_second)
set_data_high();
else
set_data_low();
}
else if(i == sec_pos + 1){
if(iteration <= tenth_of_second)
set_data_high();
else
set_data_low();
}
else{
set_data_low();
}
next_output();
}
update_output();
Detta har jag också löst, det är färdigt och funkar. Har alltså ett mjukt rinnande ljus. Här har vi då 1 eller 2 dioder tända samtidigt, beroende på iteration och tiondel.
Kan lägga upp video när jag kommer hem för att visa ungefär hur det ser ut.
5. Sen vill jag utöka detta till att även ha med timmar och minuter, och också de med mjuka övergångar. Då duger inte längre tenth_of_second, etc., det blir för rörigt. Principen jag tänkte mig då var att istället ha en array med 60 tal (med värden mellan 0->9).
Är det då så här:
Kod: Markera allt
array[0] = 0
array[1] = 1
array[2] = 2
...
array[10->60] = 0
Så betyder det att första dioden ska vara helt släckt, andra dioden bara ska vara tänd när iteration = 0 (dvs 10% av tiden), tredje dioden när iteration = 0 eller iteration = 1 (20% av tiden) osv.
Då blir principen istället:
Kod: Markera allt
iteration++;
if(iteration==10) iteration = 0;
int array[60] = ...;
for(i=0; i<60; i++){
if(iteration < array[i])
set_data_high();
else
set_data_low();
next_output();
}
update_output();
I princip kan då alla dioder vara tända samtidigt, men i praktiken blir det max 6 st. (2 per visare)
Detta är också implementerat och funkar - så länge jag har 8 dioder istället för 60. När jag drar upp det till 60 tar varje iteration för lång tid, och det börjar flimra.
Min fråga är då helt enkelt: Kan man ta ovanstående lilla kodsnutt och skriva om den till en SPI-variant? Kommer det löna sig?