9. Unterprogramme,Wiederholungsvorgänge optimieren

Anleitungen für "hausgemachte" LED Projekte

Moderator: T.Hoffmann

Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

So, 14.01.07, 17:01

Unterprogramme
Wer die vorherigen Tuts von mir gelesen hat, weiß durch die Interrupts was Unterprogramme sind.

Denn man kann auch selber Unterprogramme erstellen und diese dann aufrufen.

Eine kurze Erklärung was Unterprogramme sind:

Wenn ein Unterprogramm aufgerufen wird, wird das Hauptprogramm sofort unterbrochen und das ausgewählte Unterprogramm wird ausgeführt. Nach dem das Unterprogramm durchgelaufen ist, kehrt es an der Stelle des Hauptprogramms zurück, an der es vorhin unterbrochen worden ist.

Die Unterprogramme werden unter dem Hauptprogramm geschrieben. Mit dem Befehl wird das Unterprogramm aufgerufen:

Code: Alles auswählen

Gosub Name
Hier ein kompletter Beispiel-Code mit "blinken" und "wechsel" als Unterprogramm:

Code: Alles auswählen

$regfile = "m8def.dat"

$crystal = 1000000

Config Pind.5 = Output
Config Pind.6 = Output
Config Pind.2 = Input

Taster1 Alias Portd.2
Led1 Alias Portd.5
Led2 Alias Portd.6

Do

Gosub Wechsel
Gosub Wechsel
Gosub Wechsel
Gosub Blinken
Gosub Blinken
Gosub Blinken

Loop

Wechsel:		'Unterprogramm Wechsel
Led1 = 1
Waitms 1000
Led1 = 0
Waitms 1000
Led2 = 1
Waitms 1000
Led2 = 0
Waitms 1000
Return

Blinken:		'Unterprogramm Blinken
Led1 = 1
Led2 = 1
Waitms 1000
Led2 = 0
Led1 = 0
Waitms 1000
Durch das wiederholte Aufrufen eines Unterprogramms kann man seinen Code abkürzen. Im Oberen Beispiel würden die Leds 3 x abwechseln blinken und 3 x gemeinsamblinken und dann wieder von vorne...

Situation 2

Nun kommen wir zum nächsten Beispiel.

Wir möchten die oberen Effekte/Ansteuerung (sprich 3 x abwechseln blinken und 3 x gemeinsamblinken) beibehalten und ergänzen. Und zwar soll jetzt die Pause pro Durchlauf eines Unterprogramms verkürzt werden.
Dadurch sollen die Leds schneller blinken bzw. unterschiedlich schnell.

Nun könnte man einfach das ein/ausschalten Leds mit den Pausen einfach hintereinanderschalten und die Pausen verkürzen, sprich nicht mehr in Unterprogrammen unterteilen, dadurch hätte wir aber einen sehr langen Code. :

Einfache / Billige Lösung:

Code: Alles auswählen

'3 x Wechselblinken:

Led1 = 1
Waitms 1000
Led1 = 0
Waitms 1000
Led2 = 1
Waitms 1000
Led2 = 0
Waitms 1000

Led1 = 1
Waitms 600
Led1 = 0
Waitms 600
Led2 = 1
Waitms 600
Led2 = 0
Waitms 600

Led1 = 1
Waitms 300
Led1 = 0
Waitms 300
Led2 = 1
Waitms 300
Led2 = 0
Waitms 300

'3 x blinken:

Led1 = 1
Led2 = 1
Waitms 1000
Led2 = 0
Led1 = 0
Waitms 1000

Led1 = 1
Led2 = 1
Waitms 600
Led2 = 0
Led1 = 0
Waitms 600

Led1 = 1
Led2 = 1
Waitms 300
Led2 = 0
Led1 = 0
Waitms 300

Bessere / Professionellere Lösung

Man löst das Ganze über Zuweisung der Pausen durch Variabel.

Bevor ein Unterprogramm gestartet wird, weist man der Variabel die gewünschte Pausezeit zu und die Pausen in Unterprogrammen nehmen die Variabel als "Pause-Zeit".

Das ganze würde dann folgender Maßen aussehen:

Code: Alles auswählen


$regfile = "m8def.dat"

$crystal = 1000000

Config Pind.5 = Output
Config Pind.6 = Output
Config Pind.2 = Input

Taster1 Alias Portd.2
Led1 Alias Portd.5
Led2 Alias Portd.6

Dim Pause As Integer

Do

Pause = 1000
Gosub Wechsel
Pause = 600
Gosub Wechsel
Pause = 300
Gosub Wechsel
Pause = 1000
Gosub Blinken
Pause = 600
Gosub Blinken
Pause = 300
Gosub Blinken

Loop

Wechsel:  'Unterprogramm Wechsel
Led1 = 1
Waitms Pause
Led1 = 0
Waitms Pause
Led2 = 1
Waitms Pause
Led2 = 0
Waitms Pause
Return

Blinken:  'Unterprogramm Blinken
Led1 = 1
Led2 = 1
Waitms Pause
Led2 = 0
Led1 = 0
Waitms Pause
Je öfters man das Unterprogramm wiederholen möchte, umso mehr spart man an Code bzw. Übersicht.
Zuletzt geändert von Pehu am So, 21.01.07, 18:32, insgesamt 5-mal geändert.
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

So, 14.01.07, 19:29

@Pehu....

Ich muß ehrlich sagen, das mir deine Beiträge sehr gefallen....

Bisher habe ich alle Beiträge diesbezüglich mit Begeisterung gelesen und warte förmlich auf deine nächsten Post´s.

Sehr schön gemacht ...was eventuell noch etwas ausführlicher sein könnte, sind die Kommentare in den Programmen, wie es in deinem ersten Beitrag zu den Programmen der Fall war...aber sonnst 1A.

Ich habe dir soeben von meinem Creditz Konto 200 Creditz überwiesen :wink: weil ich einfach BEGEISTERT bin.
Benutzeravatar
Doc_McCoy
Hyper-User
Hyper-User
Beiträge: 1962
Registriert: Sa, 03.06.06, 15:49
Wohnort: Neualbenreuth
Kontaktdaten:

So, 14.01.07, 20:09

Andy hat geschrieben:@Pehu....

Ich muß ehrlich sagen, das mir deine Beiträge sehr gefallen....

Bisher habe ich alle Beiträge diesbezüglich mit Begeisterung gelesen und warte förmlich auf deine nächsten Post´s.
Sind echt super die Tutorials...
Hab die ersten 6 Topics gelesen, aber die anderen neuen nur überflogen, da ich ja noch nicht mal ein Atmelboard habe... Muss mir umbedingt eins zulegen und dann sollte ich in die Bascom-Programmiersprache einsteigen! :wink:
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

So, 14.01.07, 21:15

@Andy Dankeschön für die Credits.
@Doc dann wird es mal Zeit. :wink: Will jetzt endlich Projekte mit µC von euch sehen. :o
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

So, 14.01.07, 21:30

So...habe jetzt auch ein Progrämmchen geschrieben...allerdings nichts besonderes...soll nachher Verwendung in meinem Badezimmer finden, damit ich die eigentliche Schaltung nicht mehr in diesem Umfang aufbauen muß, wie es ursprünglich mal geplant war.

Funktion...

Taster 1 soll Getastet werden und das Licht um die Badewanne soll eingeschaltet werden.
Taster 1 abermals Getastet und die Badewannenbeleuchtung schaltet wieder aus.
Paralleldazu geht dann auch die Fußbodenbeleuchtung in der Selben Farbe an.. und mit dem 2.Tasterdruck wieder aus...

Mit dem 2. Taster geht die Duschkabinenbeleuchtung an...ebenso auch der Fußboden in der selben Farbe...und beim 2. Druck des 2. Tasters wieder aus...

Ebenso verhält es sich mit der Deckenbeleuchtung und mit der Regalbeleuchtung.

und hier nun das geschriebene Programm....
Allerdings nicht mit nem ATMega 8 oder 16 sondern mit nem ATtiny 2313.


$regfile = "attiny2313.dat" 'definieren des verwendeten Chips Hier ist es ein ATtiny 2313

$crystal = 8000000 'definieren des verwendeten externen Quarz (8MHz)

Dim A As Byte 'dimensionieren der verwendeten Variablen
Dim B As Byte



$crystal = 1000000

Config Pinb.0 = Input
Config Pinb.1 = Input
Config Pinb.2 = Input
Config Pinb.3 = Input
Config Pinb.4 = Output
Config Pinb.5 = Output
Config Pinb.6 = Output
Config Pinb.7 = Output

Taster1 Alias Pinb.0
Taster2 Alias Pinb.1
Taster3 Alias Pinb.2
Taster4 Alias Pinb.3
Led1 Alias Portb.4
Led2 Alias Portb.5
Led3 Alias Portb.6
Led4 Alias Portb.7




Main: 'Hauptprogramm
Do 'Anfang der Schleife

If Taster1 = 1 Then 'Wenn an Pin 0 von Port B ein high level anliegt, dann...

Toggle Led1 '...setze Pin 5 von Port B von high auf low oder umgekehrt
Bitwait Taster1 , Reset 'warte bis an Pin 0 von Port B wieder ein low level anliegt

End If 'Ende der Bedingung


If Taster2 = 1 Then 'Wenn an Pin 1 von Port D ein high level anliegt, dann...

Toggle Led2 '...setze Pin 6 von Port B von high auf low oder umgekehrt
Bitwait Taster2 , Reset 'warte bis an Pin 1 von Port B wieder ein low level anliegt

End If 'Ende der Bedingung

If Taster3 = 1 Then

Toggle Led3
Bitwait Taster3 , Reset

End If




If Taster4 = 1 Then

Toggle Led4
Bitwait Taster4 , Reset

End If





Loop 'zum Anfang der Schleife


Allerdings leicht unübersichtlich...aber dennoch funzt es. :wink:
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

So, 14.01.07, 21:56

Da ist nichts unübersichtlich. :wink:

Aber du hättest die:

Code: Alles auswählen

Config Pinb.0 = Input 
Config Pinb.1 = Input 
Config Pinb.2 = Input 
Config Pinb.3 = Input 
Config Pinb.4 = Output 
Config Pinb.5 = Output 
Config Pinb.6 = Output 
Config Pinb.7 = Output
Mit dem Befehl Ddrb = &B00001111 ersetzen können. :wink:

Edit: Mir sind noch die Variablen aufgefallen. Wird es vielleicht um weitere Funktionen ergänzt?
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

So, 14.01.07, 22:06

Hmmm...das weiß ich noch nicht so genau......eventuell werde ich noch irgendein Gimmik im Badezimmer verbauen, bei denen ich irgendwie ein muster ablaufen lassen könnte...oder per Tastendruck meiner Frau im Wohnzimmer dann ne Nachricht auf dem Monitor schmeißen kann...lol...

Jou...das hätte ich auch machen können..lol werde ich vielleicht noch abändern.
Elektrofreak
Super-User
Super-User
Beiträge: 73
Registriert: Mo, 25.09.06, 15:27
Kontaktdaten:

Di, 16.01.07, 20:33

was ich in den tutorials ggf noch gerne hätte wäre ein Beispiel, wie ich beispielsweise Messwerte an den PC übertragen kann oder über den PC die Schalterzustände des MC einstellen kann.

Ist das zu schwierig?
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

Di, 16.01.07, 21:20

@Elektrofreak Auf dem Pollinboard ist ein Pegelwandler für die Kommunikation über RS232, also über die serielle Schnittstelle. Der Microntroller kann Daten empfangen sowie Daten an den PC senden.

Dadurch kannst du bestimmte Daten an den PC senden oder auch umgekehrt...

Leider habe ich sowas noch nie gemacht und habe keine Ahnung davon.

Über die Hilfe von Bascom dürftest du einiges finden... oder über Google.
Benutzeravatar
Timm
Mega-User
Mega-User
Beiträge: 387
Registriert: So, 25.06.06, 18:53

Do, 18.01.07, 19:03

Hey ich find die Tut's alle richtig gut und finde das irgendein Admin mal ein kleines Unterforum mit den ganzen beiträgen von 1-9 reintun sollte, denn solangsam verliert man den überblick
Benutzeravatar
Fightclub
Post-Hero
Post-Hero
Beiträge: 5114
Registriert: Mi, 01.03.06, 18:40

Do, 18.01.07, 19:09

@timm: lesen bildet: dafür gibts sogar ein extratopic und wer da liest der sieht dass es abgelehnt wurde! danke
Benutzeravatar
Timm
Mega-User
Mega-User
Beiträge: 387
Registriert: So, 25.06.06, 18:53

Mo, 22.01.07, 21:10

@ Pehu

Ist es eigentlich möglich mehrere Unterprogramme mit einem Taster anzuwählen also:

Taster gedrückt:
Unterprogramm1
Nochmal Taster gedrückt:
Unterprogramm2

usw.

Wäre net wenn du einen Bsp Code erstellen könntest sofern es möglich ist.
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

Mo, 22.01.07, 21:49

Ja ist möglich. Denn du kannst aus einem Unterprogramm wiederrum ein weiteres Unterprogramm aufrufen und aus diesem Unterprogramm wiederrum ein weiteres Unterprogramm... Unendlich geht es natürlich nicht, irgendwann sind zu viele Unterprogramme geöffnet und der µC stürzt ab...

Jedoch muss du im Unterprogramm1 so programmieren, dass er im Unterprogramm1 bleibt und bei Tastendruck das Unterprogramm2 öffnet.

Hier ein sinvolles Beispiel :wink: :

Ich rufe Unterprogramm1 auf, dieser lässt die Led1 blinken danach ruft es Unterprogramm2 auf, dieser lässt die Led2 blinken und dieser ruft wiedderum Unterprogramm3 auf und lässt beide Leds blinken, danach wird das Unterprogramm3 beendet und durch return kehrt es an die Stelle zurück an der Unterprogramm2 unterbrochen worden ist und führt es fort sprich führt return im Unterprogramm2 aus und kehrt zum Unterprogramm1 zurück, dieser führt wiederrum return aus und kehrt wieder zum Hauptprogramm zurück, an der Stelle wo das Unterprogramm1 aufgerufen worden ist...

Code: Alles auswählen

$regfile = "m8def.dat"

$crystal = 1000000

Config Pind.5 = Output
Config Pind.6 = Output
Config Pind.2 = Input

Taster1 Alias Pind.2
Led1 Alias Portd.5
Led2 Alias Portd.6

Do

If Taster1 = 1 Then
Gosub Unterprogramm1
End If


Loop

'---- Unterprogramm 1 ----

Unterprogramm1:
Led1 = 1
Waitms 500
Led1 = 0
Gosub Unterprogramm2

Return

'---- Unterprogramm 2 ----

Unterprogramm2:

Led2 = 1
Waitms 500
Led2 = 0
Gosub Unterprogramm3

Return

'---- Unterprogramm 3 ----

Unterprogramm3:

Led1 = 1
Led2 = 1
Waitms 500
Led1 = 0
Led2 = 0

Return
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

Mo, 22.01.07, 22:53

Aber wenn man den Taster 1mal Betätigt, würde dieses Programm automatisch nach 2 springen...und nach der abgelaufenen Zeit doch automatisch nach 3 , ohne den Taster erneut zu betätigen oder nicht?
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

Di, 23.01.07, 06:43

@Andy Jep korrekt. Beim Betätigen des Taster1 springt es zuerst ins Unterprogramm1, dann Unterprogramm2 und anschließend Unterprogramm3.
Benutzeravatar
Timm
Mega-User
Mega-User
Beiträge: 387
Registriert: So, 25.06.06, 18:53

Di, 23.01.07, 13:30

Danke für den Code ich meinte das aber anders :)

So wie Andy es schon sagte springt es ja sobald man den Taster 1x betätigt hat durch alle Unterprogramme. Ich möchte aber gerne das ich durch drücken des Tasters die einzelnen Programme aufrufen kann.
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

Di, 23.01.07, 21:43

@Timm OK, ich habe es verstanden. :wink: Aber ich würde es nicht so realisieren wie du es gesagt hast, also zuerst in Unterprogramm1 gehen und von dort aus Unterprogramm2 aufrufen,... . Sondern das Ganze immer aus dem Hauptprogramm heraus starten (hier mal mit Select-Case):

Code: Alles auswählen


$regfile = "m8def.dat"

$crystal = 1000000

Config Pind.5 = Output
Config Pind.6 = Output
Config Pind.2 = Input

Taster1 Alias Pind.2
Led1 Alias Portd.5
Led2 Alias Portd.6

Dim Auswahl As Integer

Auswahl = 1

Do

If Taster1 = 1 Then

Select Case Auswahl

    Case 1 : Gosub Unterprogramm1

    Case 2 : Gosub Unterprogramm2

    Case 3 : Gosub Unterprogramm3

  End Select

If Auswahl = 3 Then

Auswahl = 1

Else

Auswahl = Auswahl + 1

End If

End If


Loop

'---- Unterprogramm 1 ----

Unterprogramm1:
Led1 = 1
Waitms 500
Led1 = 0
Return

'---- Unterprogramm 2 ----

Unterprogramm2:

Led2 = 1
Waitms 500
Led2 = 0
Return

'---- Unterprogramm 3 ----

Unterprogramm3:

Led1 = 1
Led2 = 1
Waitms 500
Led1 = 0
Led2 = 0
Return

Benutzeravatar
Timm
Mega-User
Mega-User
Beiträge: 387
Registriert: So, 25.06.06, 18:53

Do, 25.01.07, 13:23

Hey danke ich weis ich nerve :oops: habs vergessen es oben schon zu erwähnen.
Das Ausgewählte Unterprogramm sollte sich immer so lange wiederholen bis das nächste ausgewählt wird. Wie bekomm ich das hin?
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

Do, 25.01.07, 19:26

@Timm Das nächste Mal ist es nicht mehr kostenlos. :wink:

Eine Mögliche Lösung:

Code: Alles auswählen


$regfile = "m8def.dat"

$crystal = 8000000

Config Pind.5 = Output
Config Pind.6 = Output
Config Pind.2 = Input

Config Timer0 = Timer , Prescale = 8
On Ovf0 Tasterpruefen

Enable Timer0
Enable Interrupts

Taster1 Alias Pind.2
Led1 Alias Portd.5
Led2 Alias Portd.6

Dim Auswahl As Integer

Auswahl = 1

Do


Select Case Auswahl

    Case 1 : Gosub Unterprogramm1

    Case 2 : Gosub Unterprogramm2

    Case 3 : Gosub Unterprogramm3

  End Select

Loop

'---- Unterprogramm 1 ----

Tasterpruefen:

If Taster1 = 1 Then

If Auswahl = 3 Then

Auswahl = 1

Else

Auswahl = Auswahl + 1

End If

Waitms 800

End If



Return

Unterprogramm1:

Led1 = 1
Waitms 500
Led1 = 0
Waitms 500
Return

'---- Unterprogramm 2 ----

Unterprogramm2:

Led2 = 1
Waitms 500
Led2 = 0
Waitms 500
Return

'---- Unterprogramm 3 ----

Unterprogramm3:

Led1 = 1
Led2 = 1
Waitms 500
Led1 = 0
Led2 = 0
Waitms 500
Return
Benutzeravatar
Timm
Mega-User
Mega-User
Beiträge: 387
Registriert: So, 25.06.06, 18:53

Fr, 26.01.07, 14:39

OK danke :D bei jeder Frage die ich jetzt noch stelle bekommst 20 Credits :lol:
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

Fr, 26.01.07, 16:53

@Pehu
Wann geht es eigentlich mit deinem How To weiter?...binn schon sehr gespannt, welche Thematik du als nächstes aufgreifen wirst.
Vielleicht, was man mit RTC und SPI so alles machen kann...lol..
Oder weitere Befehlserklärungen... und wie man diese Behandelt...also deine vorherigen How To´s haben mir recht gut gefallen...bin schon fast süchtig danach geworden, so genial fand ich die.
Also...bitte bitte...mache so weiter, wie bisher.
Benutzeravatar
Pehu
Mega-User
Mega-User
Beiträge: 469
Registriert: Mi, 01.11.06, 19:33
Kontaktdaten:

Sa, 27.01.07, 09:30

@Andy Das Problem ist, das ich momentan an Zeitmangel leide und so ein Tut locker ein paar Stunden frißt.
Aber mal gucken, wenn ich wieder Zeit habe werde ich es fortführend oder wenn einer ebenfalls Lust zum schreiben eines Tuts hat, kann er es natürlich gerne tuen, aber am Besten sprechen wir davor ab, nicht dass wir das gleiche Thema parallel scheiben. :wink:
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

So, 03.06.07, 22:18

So
an alle, die Ahnung im Umgang mit yC´s haben und im Bascom Programming nicht gerade auf dem Kopf gefallen sind.

Ich habe eine Frage an euch.

Bei Lösungsvorschlägen wenn´s geht bitte mit einem Code in Bascom hier Posten.

weil ich weiß nicht weiter !!!

Ich möchte:

Eine Signalquelle (in meinem Falle einen Micro vorverstärkerausgang)
An einen A/D Pin eines Atmega8 anschließen.
Diese daten dann alle abfragenlassen, sodass diese dann eine Programmabfolge des Hauptprogrammes beeinflussen können.
dieses soll je nach Frequenz und Intensität des Signales geschehen.
Wenn keine Übereinstimmung der zuvor in den speichergeschriebenen Daten vorhanden ist, soll eine Art Peak Level an den Ausgängen stehen.
Bei übereinstimmungen von gewissen Vorraussetzungen soll dann meinetwegen ein Unterprogramm starten, das die LED´s dann alle auf einmal heftigst Flashen oder sich die Farbe plötzlich ändert.
Dann wieder zurück zum Peaklevel springen.

So oder so ähnlich sollte der Atmega dann arbeiten.

Ich weiß aber nicht, wie ich den A/D Anschluß so Programiere, das es zumindest auf einer ähnlichen Art und Weise funktionieren kann.

Bitte Helft mir.
Ich binn schon am Verzweifeln.

Meinetwegen auch in Kombination mit einem Analogeingang für die Intensität des Signals.
synvox
Mega-User
Mega-User
Beiträge: 147
Registriert: Fr, 27.04.07, 04:40
Wohnort: Schweiz

Mo, 04.06.07, 04:33

Hmmm,

da hast du dir ja für den Anfang nicht gerade die leichteste Aufgabe gestellt :wink: .

Vorab mal, die Frequenzanalyse von Musik- oder Mikrofonsignalen (also ein Gemisch von Frequenzen) kannst du mit einem ATMEL AVR-Chip bei all seinen sonstigen Qualitäten vergessen, dazu ist er einfach nicht schnell genug, bzw. auch von seiner Architektur her nicht dafür ausgelegt. Auf digitaler Basis wird sowas mit DSPs (Digitale Signalprozessoren) gemacht, und die sind um Grössenordnungen komplexer und schneller als ein AVR.

Was du aber tun kannst, ist das Signal zunächst auf analoger Basis mit Frequenzweichen (ala klassische Lichtorgel) in versch. Frequenzbereiche zu unterteilen (Bässe, Mitten, Höhen oder noch feiner) und diese aufgeteilten Signale dann verschiedenen Analogeingängen des AVR zuzuführen (ein ATMEGA8 hat ja 6 davon). Dann bekommt man praktischerweise über den Wert des jeweiligen Analogdigitalwandlereingangs jeweils die Intensität des entsprechenden Frequenzbandes zu einer bestimmten Zeit geliefert.

Ok, so weit so gut. Der ADC des ATMEGA8 kann einen Interrupt auslösen bei abgeschlossener Konversion. Dies kann man nun ausnutzen, indem man eine Interruptroutine (ein Interrupt-Unterprogramm) schreibt, in der dann jeweils eine globale Index-Variable (nennen wir mal index) als Element-Index für ein auch globales Werte-Array (Wert(index)) verwendet wird. Wir schreiben dann also im ersten Interrupt das erste Konversionsergebnis in eine Variable zum Bsp. Wert(1), der Index wäre in dem Fall als 1 initialisiert worden. Wir erhöhen dann im Interrupt den Index um eins, prüfen, ob er grösser 6 ist, falls ja dann setzen wir ihn wieder auf 1. Wir wechseln dann im ADMUX-Register den ADC-Kanal auf den nächsten und starten eine neue Konversion. Den einzustellenden Kanal gewinnen wir auch aus dem Index, indem wir davon eins abziehen (ADC-Kanäle beginnen mit 0). Dann verlassen wir den Interrupt. Dieser wird automatisch wieder aufgerufen, sobald auch die zweite Konversion beendet ist... etc. Somit werden mittels einer solchen Interrupt-Funktion die Variablen Wert(1) bis Wert(6) mit den jeweiligen Messwerten der ADC-Eingänge 0 bis 5 gefüllt, also mit den Intensitätswerten der versch. Frequenzbände.
Natürlich müssen wir am Anfang im Hauptprogramm erstmal die ADC-Register korrekt initialisieren, die erste Konversion starten, plus entsprechend die Interrupts freigeben etc. damit überhaupt ein Interrupt stattfinden kann.
Ok, nun weiter im Text... unabhängig vom Interrupt läuft dann unser Hauptprogramm in einem Loop, in dem dann die Variablen Wert(1) bis Wert(6) per If- oder Select-Case-Abfrage bei Über- oder Unterschreiten vorgegebener Werte andere Unterprogramme aufrufen, wo wiederum LEDs angeschaltet oder Farben bei RGB-LEDs gewechselt werden. Man könnte prinzipiell auch einfach in dem Hauptloop den Wert einer dieser Variablen Wert(1) bis Wer(6) direkt an so ein Unterprogramm wie mein Farbumwandlungsprogramm als Hue-Wert (Farbkreis-Wert) übergeben zur direkten Farbsteuerung einer RGB-LED aufgrund der Intensität eines bestimmten Frequenzbandes.

Das ist jetzt zwar alles theoretisch und ohne konkreten Code, aber ich wollte auch eher eine Idee geben, wie man so eine Aufgabe lösen könnte :) .

Wenn du mir aufgrund dieser Ausführungen angeben kannst, wo genau es hapert, kann ich dir vielleicht auch mit entsprechenden Code-Beispielen helfen :) . Ich konnte hier jetzt nicht einfach eine komplette Musiksteuerungsapplikation coden, das wäre etwas zu viel Aufwand gewesen :wink: .

Gruss
Neni
Andy
Hyper-User
Hyper-User
Beiträge: 1284
Registriert: Mi, 17.05.06, 13:03

Mo, 04.06.07, 11:54

Hi Synvox.
Danke für deine Antwort.

Ich kann sicherlich diverse Tastenabfragen und Lauflichtprogramme und Diverse Ein und Ausgänge eines AVR´s Bestimmen und Zuweisen.
Kleine Unterprogramme schreiben etc.
Aber mit dem Auswerten und Zuweisen spezieller Eingänge und den dazugehörigen Codes sowie die Codes zum Beschreiben und Abrufen des Speichers habe i net...kann ich nicht.

Ich habe mir gedacht, das ich einige Externe Filter ( Hoch, Tief und Bandpässe ) Aufbaue, diese dann vom AVR auf Frequenz und Intensität abfragen lassen wollte, die Daten dann mit Festwerten, die vorher schon im Speicher abgelegt wurden, Abgeglichen werden und bei übereinstimmungen dann gewisse Effekte ablaufen.
Bei nichtübereinstimmungen der Daten vom Speicher, dann einfach nur eine Art Peak Level amn den Ausgängen liegt, den man dann auch per TZastendruck abändern könnte.
Peak Level von Unten nach oben oder von der Mitte zu den Endpunkten etc.
Antworten