Hi!
Aus besonderen Anlässen habe ich mir eine LED-Kette gebastelt ;-) Diese
besteht aus jeweils zwei gegenüberliegend angeordneten LEDs in Rot,
Grün, Gelb und Blau wovon ich jeweils immer eine Farbe per Portpin
ansteuern kann.
Zum Einsatz kam ein ATtiny13. Da ich das Ding gerne in C programmieren
würde, ergibt sich nun ein Dickes Problem mit der Codegröße.
Wenn mein Programm aus lauter Einzelanweisungen à la
PORTB = (0 << yellow) | (0 << green) | (1 << red) | (0 << blue);
_delay_ms(100);
besteht, wächst schon nach zwei Effekten der Programmcode auf 500bytes
an was schon 50% des Speichers vollmachen. Ich hätte jedoch gerne mehr
verschiedene Effekte. Darunter eventuell auch mal Fading-Effekte. Das
meiste werden jedoch nur 1/0-Folgen sein die dann wie ein Film ein paar
mal wiederholt hintereinander ablaufen.
Da ich nicht so der C-Geek bin und mit µCs 2 Monate Pause gemacht hab,
wollte ich mal Fragen ob jemand eine Idee hat, wie man die
Programmierung von solchen Folgen mit knappem Code realisieren kann und
ob das in C überhaupt so möglich ist oder ob ich assembler verwenden
muss.
Ach ja, es sei noch zu erwähnen dass es da noch einen Taster gibt mit
dem man z.B. ins nächste Programm springen oder die Geschwindigkeit der
Programmabfolge bestimmen können soll.
lg PoWl
Wenn mit der Delay-Bibliothek gearbeitet wird:
Die Optimierung einschalten.
Sonst werden die .hex mal schnell seeeeehr groß ^^
Aber besser noch: Interrupts verwenden.
Danke, die Optimierung hat leider keine Codereduktion erbraucht. Mir ist
das grad was eingefallen
Am besten wäre wohl eine Funktion die ich mit Daten folgender Struktur
füttern kann:
Jeweils ein Byte
Rot | Grün | Blau | Gelb | 4-Bit Delay
Dann kann ich die ganzen Effekte einfach in einer einfachen Liste
speichern, das was da vorher 300 Byte lang war wär somit nur noch 20
byte lang :-) Fragt sich nur wie viel Overhead das produziert. Muss sich
mal testen
Wenn man fürs Delay nur zwei oder drei Bit einplant könnte man ja noch
so dinge wie ein/ausfaden mit einplanen :-)
lg PoWl
in einem Timerinterrupt gibst Du das nächste Element auf PORTB aus
1
ISR(TIMER0_OVF_vect){
2
staticuint8_tfolge=0;
3
4
PORTB=pgm_read_byte(&Animation[folge]);
5
folge++;
6
if(folge>=4)
7
folge=0;
8
}
Du kannst ein 2 Dimensionales Array anlegen, für verschiedene Effekte.
Die Erste Dimension läuft im Timer Durch, die Zweite schaltest Du mit
Deinem Taster um.
Gruß Sebastian
Statt den Flash (= CSEG) zum Speichern von Datenmengen zu verwenden,
kann man diese auch ins EEPROM (= ESEG) auslagern. Eine Routine, die
ein Byte aus der übergebenen EEPROM-Adresse ausliest, ist fix
geschrieben, und benötigt nur wenig Platz.
AVRFan wrote:
> Statt den Flash (= CSEG) zum Speichern von Datenmengen zu verwenden,> kann man diese auch ins EEPROM (= ESEG) auslagern. Eine Routine, die> ein Byte aus der übergebenen EEPROM-Adresse ausliest, ist fix> geschrieben, und benötigt nur wenig Platz.
An sich ne gute Idee aber das EEPROM umfasst beim Tiny13 nur 64 Byte,
ist leider etwas wenig, das reicht vielleicht für 2-3 Animationen.
Wenn die Ausgaberoutine 200-500Byte braucht hab ich noch 500 Byte nur
für Animationen, das langt dicke :-)
Bin noch nicht dazu gekommen was zu schreiben, mach ich morgen mal.
das hintere nibble eines solchen Animationsdatenbytes kann man ja
benutzen um den Delay vorzugeben in 16 Stufen (4 Bit) mit jeweils
meinetwegen 25ms.
Mit dem Button kann man ja dann noch auswählen wie viel ms ein delay
wirklich umfasst und die Animation somit schneller und langsamer machen
:-)
lg PoWl
@AVRFan,
Genau, EEPROM ist auch ein guter Ablageort.
> Eine Routine, die>ein Byte aus der übergebenen EEPROM-Adresse ausliest, ist fix>geschrieben, und benötigt nur wenig Platz.
Das ist nicht nötig,
ersetze PROGMEM durch EEMEM
und pgm_read_byte durch eeprom_read_byte
fertig.
Gruß Sebastian
Hi, danke nochmal für die Hilfe! Mein Akutelles Programm sieht so aus
und funktioniert auch recht ordentlich :-)
Wie kann ich denn nun mehrdimensionale Arrays erstellen? Im
lightshow-Array sollen nun mehrere Arrays mit den einzelnen Szenen
eingespeichert sein. Um die szene automatisch neu beginnen zu lassen
wenn sie fertig durchgelaufen ist brauch ich eine Endemarke 0x00 oder?
lg PoWl
Matthias Lipinsky wrote:
> Warum machst du das nicht so. Sortiere doch einfach deine "Farbbits"> passend zur Anschlussbelegung.
Das ist nur für mich so, weil Die Kette so aufgebaut ist: Gelb Grün Rot
Blau und ich das gerne auch in der Reihenfolge so programmieren würde
:-)
> Das Delay würde ich durch einen Timer> ersetzen...
Danke, aber wozu, das wird ja mega kompliziert. Ich möchte doch die
delay-Zeit durch die Angabe im jeweiligen Szenenschritt bestimmen.
Wie erstellt man denn nun mehrdimensionale Arrays? Mein kleines
Experiment scheint nicht zu funktionieren:
>Danke, aber wozu, das wird ja mega kompliziert
Das ist wohl ein Scherz...
>Ich möchte doch die delay-Zeit durch die Angabe im jeweiligen Szenenschritt >bestimmen.
Kannst du doch. Beispiel siehe mein Post.
>Mein kleines Experiment scheint nicht zu funktionieren:
Das sind ja auch zwei einzelne Arrays.
>Wie erstellt man denn nun mehrdimensionale Arrays?
Danke schonmal für deine Posts.
Hast Recht, mit deinem Beispiel geht es. Aber ich verstehe nicht ganz,
was mir das für Vorteile bringen soll? Wozu einen Timer verwenden? Einen
Linearen Programmablauf finde ich übersichtlicher und einfacher zu
handlen für den Anfang.
lightshow dient als zeiger auf die beiden arrays. Demnach müsste
&(lightshow[x]) die Adresse des arrays nummer x haben. Sollte ich die
Eckige klammer danach noch in die Runde mit reinholen?
Mit deiner Methode, mehrdimensionale Arrays zu erstellen, kann man nur
Unterarrays gleicher Länge definieren. Meine Einzelnen Lichtszenen sind
allerdings alle unterschiedlicher Länge.
lg PoWl