http://wiki.fablab-cottbus.de/api.php?action=feedcontributions&user=Marcel&feedformat=atomfablab Cottbus - Benutzerbeiträge [de]2024-03-29T09:36:32ZBenutzerbeiträgeMediaWiki 1.32.0http://wiki.fablab-cottbus.de/index.php?title=FablabFreitag1&diff=2494FablabFreitag12018-08-14T14:41:44Z<p>Marcel: /* Bau von Möbeln für den Außenbereich */</p>
<hr />
<div>= Bau von Möbeln für den Außenbereich =<br />
== Wikinger Stuhl ==<br />
* https://www.instructables.com/id/The-Viking-Chair/<br />
* Es fehlen Paletten<br />
<br />
== Klappstuhl ==<br />
* https://www.instructables.com/id/Folding-Cedar-Lawn-Chair/<br />
* Es fehlt Holz<br />
<br />
== Klappliege ==<br />
https://i.ebayimg.com/images/g/nQQAAOSwOVpXVYmY/s-l300.jpg<br />
* 3 Rahmen nachbauen<br />
* Genug stabiles Holz da? Stoff fehlt<br />
<br />
== Luftsack zum sitzen ==<br />
https://img.tvc-mall.com/uploads/details/85050051E-1.jpg<br />
* Material fehlt<br />
<br />
= Luftfilter für die Werkstatt =<br />
* Einsatz für Fenster bauen<br />
* Filter nutzen! und nicht nur unseren Dreck nach draußen blasen<br />
<br />
= Garage entrümpeln =<br />
* Die Gegenstände von VcA soweit wie möglich umlagern<br />
* Die Holzbalken, mit denen seit Jahren keiner etwas machen möchte, entfernen</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Veranstaltungen&diff=2484Veranstaltungen2018-07-30T15:07:56Z<p>Marcel: </p>
<hr />
<div>Hier findet ihr eine Übersicht und Beschreibung aller Veranstaltungen, die mal im FabLab Cottbus stattgefunden haben, stattfinden sollen oder stattfinden. Für aktuelle Termine schaut bitte in unseren [http://blog.fablab-cottbus.de/veranstaltungskalender Kalender].<br />
= [[Workshops]] =<br />
Eine Übersicht über unsere Workshops findet sich [[Workshops|hier]]. <br />
<br />
= [[Repair-Cafe]] =<br />
{{:Repair-Cafe}}<br />
[[Repair-Cafe|mehr...]]<br />
<br />
= [[Computerstammtisch]] =<br />
{{:Computerstammtisch}}<br />
[[Computerstammtisch|mehr...]]<br />
<br />
= [[Wiki-Abend]] =<br />
{{:Wiki-Abend}}<br />
[[Wiki-Abend|mehr...]]<br />
<br />
= [[Crypto-Party]] =<br />
{{:Crypto-Party}}<br />
[[Crypto-Party|mehr...]]<br />
<br />
= [[Fablab-Freitag]] =<br />
[[Fablab-Freitag|Übersichtsseite ist hier]]<br />
<br />
= Filmabend =<br />
<br />
Filmabende zu bestimmten Themen.<br />
* Open Source → siehe z.B. [[Inspirierende Open-Source-Projekte]]<br />
* Bauprojekte<br />
<br />
= Bereits stattgefundene Veranstaltungen =<br />
* [[Veranstaltung zur geplanten Obsoleszenz (2015)]]<br />
* [[Lesekreis - Zur Kritik der instrumentellen Vernunft | Lesekreis - Zur Kritik der instrumentellen Vernunft (Sommersemester 2015) ]]<br />
* [[BGE|Leipziger Initiative Bedingungsloses Grundeinkommen im quasiMONO (Wintersemester 2015)]]<br />
* [[OTIWO 2014]]<br />
* [[Straßenfest MuCheZe]]<br />
* [[OTIWO 2015]]<br />
* [[Sommerfest 2015]]<br />
<br />
= Was hat wer schon gemacht - Abend =<br />
<br />
Jeder der Lust hat stellt seine Bastel-/Bauprojekte vor. Schon fertige Projekte, laufende oder geplante. Fotos zeigen, Teile mitbringen/vorführen etc. Anschließend gemütliches Beisammensein, Fragen, Austausch.<br />
* [[Matrix-Projekt]] des Ecco<br />
* weitere Projekte des Ecco<br />
* Von Dominic weiß ich, dass er nen [[Quadrocopter]] gebaut hat, oder ein [[Timelapse-Stativ]] - [[User:Nanu|Nanu]] ([[User talk:Nanu|talk]]) 15:04, 8 February 2014 (CET)<br />
* Fahrrad-Ladegerät ([[User:Nanu|Nanu]] ([[User talk:Nanu|talk]]), Sarah)<br />
* 3D-Drucker im Eigenbau (Ron)<br />
* Holz-Ständer-Bauwerk ([[User:Nanu|Nanu]] ([[User talk:Nanu|talk]]))<br />
<br />
= Gesellschaftliche und politische Auswirkungen des 3D-Drucks - Atomwaffenbau (Veranstaltungsidee) =<br />
<br />
Das US-Militär forscht längst daran, mit dem 3D-Druck den Atomwaffenbau zu revolutionieren. ( http://rt.com/usa/177064-army-warheads-3d-printing/ )<br><br />
Von der technischen Seite gibt es hierbei viele faszinierende Herausforderungen. <br><br />
Politisch und gesellschaftlich ist es allerdings hochbrisant.<br><br />
Besteht Interesse an diesem Thema?</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=FablabFreitag1&diff=2483FablabFreitag12018-07-30T14:51:20Z<p>Marcel: </p>
<hr />
<div>= Bau von Möbeln für den Außenbereich =<br />
* Klappstühle, Tische, Sonnenschirm, etc.<br />
<br />
= Luftfilter für die Werkstatt =<br />
* Einsatz für Fenster bauen<br />
* Filter nutzen! und nicht nur unseren Dreck nach draußen blasen<br />
<br />
= Garage entrümpeln =<br />
* Die Gegenstände von VcA soweit wie möglich umlagern<br />
* Die Holzbalken, mit denen seit Jahren keiner etwas machen möchte, entfernen</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=FablabFreitag1&diff=2481FablabFreitag12018-07-30T14:49:04Z<p>Marcel: Die Seite wurde neu angelegt: „== Bau von Möbeln für den Außenbereich == * Klappstühle, Tische, Sonnenschirm, etc. == Luftfilter für die Werkstatt == * Einsatz für Fenster bauen * Fil…“</p>
<hr />
<div>== Bau von Möbeln für den Außenbereich ==<br />
* Klappstühle, Tische, Sonnenschirm, etc.<br />
<br />
== Luftfilter für die Werkstatt ==<br />
* Einsatz für Fenster bauen<br />
* Filter nutzen! und nicht nur unseren Dreck nach draußen blasen<br />
<br />
== Garage entrümpeln ==<br />
* Die Gegenstände von VcA soweit wie möglich umlagern<br />
* Die Holzbalken, mit denen seit Jahren keiner etwas machen möchte, entfernen</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Veranstaltungen&diff=2477Veranstaltungen2018-07-30T14:41:54Z<p>Marcel: </p>
<hr />
<div>Hier findet ihr eine Übersicht und Beschreibung aller Veranstaltungen, die mal im FabLab Cottbus stattgefunden haben, stattfinden sollen oder stattfinden. Für aktuelle Termine schaut bitte in unseren [http://blog.fablab-cottbus.de/veranstaltungskalender Kalender].<br />
= [[Workshops]] =<br />
Eine Übersicht über unsere Workshops findet sich [[Workshops|hier]]. <br />
<br />
= [[Repair-Cafe]] =<br />
{{:Repair-Cafe}}<br />
[[Repair-Cafe|mehr...]]<br />
<br />
= [[Computerstammtisch]] =<br />
{{:Computerstammtisch}}<br />
[[Computerstammtisch|mehr...]]<br />
<br />
= [[Wiki-Abend]] =<br />
{{:Wiki-Abend}}<br />
[[Wiki-Abend|mehr...]]<br />
<br />
= [[Crypto-Party]] =<br />
{{:Crypto-Party}}<br />
[[Crypto-Party|mehr...]]<br />
<br />
= [[Fablab-Freitag]] =<br />
<br />
= Filmabend =<br />
<br />
Filmabende zu bestimmten Themen.<br />
* Open Source → siehe z.B. [[Inspirierende Open-Source-Projekte]]<br />
* Bauprojekte<br />
<br />
= Bereits stattgefundene Veranstaltungen =<br />
* [[Veranstaltung zur geplanten Obsoleszenz (2015)]]<br />
* [[Lesekreis - Zur Kritik der instrumentellen Vernunft | Lesekreis - Zur Kritik der instrumentellen Vernunft (Sommersemester 2015) ]]<br />
* [[BGE|Leipziger Initiative Bedingungsloses Grundeinkommen im quasiMONO (Wintersemester 2015)]]<br />
* [[OTIWO 2014]]<br />
* [[Straßenfest MuCheZe]]<br />
* [[OTIWO 2015]]<br />
* [[Sommerfest 2015]]<br />
<br />
= Was hat wer schon gemacht - Abend =<br />
<br />
Jeder der Lust hat stellt seine Bastel-/Bauprojekte vor. Schon fertige Projekte, laufende oder geplante. Fotos zeigen, Teile mitbringen/vorführen etc. Anschließend gemütliches Beisammensein, Fragen, Austausch.<br />
* [[Matrix-Projekt]] des Ecco<br />
* weitere Projekte des Ecco<br />
* Von Dominic weiß ich, dass er nen [[Quadrocopter]] gebaut hat, oder ein [[Timelapse-Stativ]] - [[User:Nanu|Nanu]] ([[User talk:Nanu|talk]]) 15:04, 8 February 2014 (CET)<br />
* Fahrrad-Ladegerät ([[User:Nanu|Nanu]] ([[User talk:Nanu|talk]]), Sarah)<br />
* 3D-Drucker im Eigenbau (Ron)<br />
* Holz-Ständer-Bauwerk ([[User:Nanu|Nanu]] ([[User talk:Nanu|talk]]))<br />
<br />
= Gesellschaftliche und politische Auswirkungen des 3D-Drucks - Atomwaffenbau (Veranstaltungsidee) =<br />
<br />
Das US-Militär forscht längst daran, mit dem 3D-Druck den Atomwaffenbau zu revolutionieren. ( http://rt.com/usa/177064-army-warheads-3d-printing/ )<br><br />
Von der technischen Seite gibt es hierbei viele faszinierende Herausforderungen. <br><br />
Politisch und gesellschaftlich ist es allerdings hochbrisant.<br><br />
Besteht Interesse an diesem Thema?</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Veranstaltungen&diff=2476Veranstaltungen2018-07-30T14:41:33Z<p>Marcel: </p>
<hr />
<div>Hier findet ihr eine Übersicht und Beschreibung aller Veranstaltungen, die mal im FabLab Cottbus stattgefunden haben, stattfinden sollen oder stattfinden. Für aktuelle Termine schaut bitte in unseren [http://blog.fablab-cottbus.de/veranstaltungskalender Kalender].<br />
= [[Workshops]] =<br />
Eine Übersicht über unsere Workshops findet sich [[Workshops|hier]]. <br />
<br />
= [[Repair-Cafe]] =<br />
{{:Repair-Cafe}}<br />
[[Repair-Cafe|mehr...]]<br />
<br />
= [[Computerstammtisch]] =<br />
{{:Computerstammtisch}}<br />
[[Computerstammtisch|mehr...]]<br />
<br />
= [[Wiki-Abend]] =<br />
{{:Wiki-Abend}}<br />
[[Wiki-Abend|mehr...]]<br />
<br />
= [[Crypto-Party]] =<br />
{{:Crypto-Party}}<br />
[[Crypto-Party|mehr...]]<br />
<br />
= [[Fablab-Freitag] =<br />
<br />
= Filmabend =<br />
<br />
Filmabende zu bestimmten Themen.<br />
* Open Source → siehe z.B. [[Inspirierende Open-Source-Projekte]]<br />
* Bauprojekte<br />
<br />
= Bereits stattgefundene Veranstaltungen =<br />
* [[Veranstaltung zur geplanten Obsoleszenz (2015)]]<br />
* [[Lesekreis - Zur Kritik der instrumentellen Vernunft | Lesekreis - Zur Kritik der instrumentellen Vernunft (Sommersemester 2015) ]]<br />
* [[BGE|Leipziger Initiative Bedingungsloses Grundeinkommen im quasiMONO (Wintersemester 2015)]]<br />
* [[OTIWO 2014]]<br />
* [[Straßenfest MuCheZe]]<br />
* [[OTIWO 2015]]<br />
* [[Sommerfest 2015]]<br />
<br />
= Was hat wer schon gemacht - Abend =<br />
<br />
Jeder der Lust hat stellt seine Bastel-/Bauprojekte vor. Schon fertige Projekte, laufende oder geplante. Fotos zeigen, Teile mitbringen/vorführen etc. Anschließend gemütliches Beisammensein, Fragen, Austausch.<br />
* [[Matrix-Projekt]] des Ecco<br />
* weitere Projekte des Ecco<br />
* Von Dominic weiß ich, dass er nen [[Quadrocopter]] gebaut hat, oder ein [[Timelapse-Stativ]] - [[User:Nanu|Nanu]] ([[User talk:Nanu|talk]]) 15:04, 8 February 2014 (CET)<br />
* Fahrrad-Ladegerät ([[User:Nanu|Nanu]] ([[User talk:Nanu|talk]]), Sarah)<br />
* 3D-Drucker im Eigenbau (Ron)<br />
* Holz-Ständer-Bauwerk ([[User:Nanu|Nanu]] ([[User talk:Nanu|talk]]))<br />
<br />
= Gesellschaftliche und politische Auswirkungen des 3D-Drucks - Atomwaffenbau (Veranstaltungsidee) =<br />
<br />
Das US-Militär forscht längst daran, mit dem 3D-Druck den Atomwaffenbau zu revolutionieren. ( http://rt.com/usa/177064-army-warheads-3d-printing/ )<br><br />
Von der technischen Seite gibt es hierbei viele faszinierende Herausforderungen. <br><br />
Politisch und gesellschaftlich ist es allerdings hochbrisant.<br><br />
Besteht Interesse an diesem Thema?</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Mikrocontrollerkurs_(erweitert)&diff=2054Mikrocontrollerkurs (erweitert)2016-06-19T20:27:51Z<p>Marcel: </p>
<hr />
<div>[[Datei:Microcontroller.jpg|300px|miniatur|Mikrocontroller selbst programmieren]]<br />
== Inhalt ==<br />
Wie auch beim Mikrocontrollerkurs werden die Grundlagen des Arduino Systems vermittelt. Es wird jedoch als Einleitung noch eine kurze Einführung in die allgemeine Elektrotechnik gegeben<br><br />
Dauer: 2 Nachmittage zu je 5 Stunden<br><br />
Termin: ''''''<br><br />
<br />
== Benötigt für Teilnehmer ==<br />
* Laptop<br />
* [http://arduino.cc/en/Main/Software Arduino Software]<br />
* [http://cloud.fablab-cottbus.de/public.php?service=files&t=26f9c6bf5b0ce31d10ba1bd071ae6aa3 FabLab Lib für den Kurs] (Nach 'Eigene Dokumente\Arduino\libraries\' entpacken)<br />
* [http://cloud.fablab-cottbus.de/public.php?service=files&t=e993ba31f4a0d30acfd4c4571b187a0c Kurs Unterlagen] Sketches mit den Programmen<br />
* [http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx Treiber für den Programmieradapter]<br />
* 40€ Teilnahmegebühr und Materialkosten (Materialien können mit nach Hause genommen werden)<br />
<br />
== Programm ==<br />
Tag 1: Einleitung<br />
* Was und Strom und Spannung?<br />
* Widerstand, Kondensator, Spule<br />
* Transistor, MOSFET als Schalter<br />
* Operationsverstärker<br />
<br><br />
Tag 1/2: Grundlagen und Licht<br />
* Board bauen<br />
* Einfache Ein-/Ausgabe Funktionen; Digital und Analog<br />
* LED per PWM dimmen<br />
<br><br />
Tag 2: Krach<br />
* einfache Soundausgabe<br />
* erweiterte Soundausgabe<br />
<br><br />
Tag 2: Sonstiges<br />
* Reservezeit, falls Themen offen sind<br />
* Zeit für eure Fragen und Themenwünsche<br />
<br />
== Anmeldung ==<br />
Anmeldung direkt im FabLab zu den Öffnungszeiten oder über info@fablab-cottbus.de<br><br />
Durch den begrenzten Raum können nur eine begrenzte Anzahl Teilnehmer untergebracht werden. Daher bitte nur Anmelden wenn ihr sicher an allen Tagen Zeit habt.<br />
<br />
== Teilnehmer ==<br />
Max. 6 Teilnehmer<br></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Datei:Filmabend_20_5_2016.pdf&diff=2040Datei:Filmabend 20 5 2016.pdf2016-05-17T15:44:02Z<p>Marcel: </p>
<hr />
<div></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=LED_Schild&diff=2028LED Schild2016-05-03T15:41:34Z<p>Marcel: </p>
<hr />
<div><onlyinclude><br />
Ein blinkendes Schild als Logo/Werbung für das Fablab. Inklusive Musikspielereien wie auch im [http://fablab-cottbus.de/index.php/Audio_Board Audio Board].<br />
</onlyinclude><br />
<br />
= Idee =<br />
Eine portable Abwandlung des Audio Projektes, die wir mit auf Ausstellungen nehmen können.<br />
<br />
= Konzept =<br />
Mehrere LED werden in verschiedenen Mustern auf einem Holzbrett angebracht. Es soll autonom laufen und verschiedene Blinkmuster haben.<br />
Es könnten 4 LED Stränge mit je 20 LED benutzt werden. Aussehen z.B.<br />
<gallery mode="packed-hover" widths=320px heights=240px><br />
Datei:Wandding_Zeichnung.svg|Fablab Logo<br />
Datei:Wandding_Zeichnung2.svg|Muster<br />
</gallery><br />
<br />
Die einzelnen LED Streifen können dann mit jedem Beat in Tiefen, Mitten bzw. Höhen blinken und die Farbe bzw. Helligkeit kann Anhand der Intensität angepasst werden. Die Blinkmuster der LED passen sich somit dynamisch an das Lied an. Alternativ können auch statische Animationen und Farbwechsel vorgegeben werden.<br />
<br />
Folgende Anforderungen werden gestellt:<br />
* Portable<br />
* LED auch im hellen sichtbar<br />
* Nachbaubar<br />
* Gut aussehen<br />
* Stabil verarbeitet<br />
<br /><br />
Offene Fragen:<br />
* Bedienung über Display + Taster oder Fernbedienung?<br />
* Controller Arduino (weit verbreitet, einfach zu nutzen) oder Nucleo-F446 (viel mehr Rechenleistung, DSP, DMA, S/PDIF Eingang usw.)?<br />
* Nur Mikrofon oder auch Line-In bzw. S/PDIF?<br />
<br /><br />
Bestehende Analogschaltung muss etwas überarbeitet werden. Anpassung an neue Anforderungen (nur Mono statt Stereo, Mikrofonverstärker). Wird direkt als Schild für das Entwicklungsboard entworfen. Sofern möglich 1-Seitige Platine zum einfacheren Nachbau.</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=LED_Schild&diff=2027LED Schild2016-05-03T15:40:02Z<p>Marcel: /* Konzept */</p>
<hr />
<div><onlyinclude><br />
Ein blinkendes Schild als Logo/Werbung für das Fablab. Inklusive Musikspielereien wie auch im [http://fablab-cottbus.de/index.php/Audio_Board Audio Board].<br />
</onlyinclude><br />
<br />
= Idee =<br />
Eine portable Abwandlung des Audio Projektes, die wir mit auf Ausstellungen nehmen können.<br />
<br />
= Konzept =<br />
Mehrere LED werden in verschiedenen Mustern auf einem Holzbrett angebracht. Es soll autonom laufen und verschiedene Blinkmuster haben.<br />
Es könnten 4 LED Stränge mit je 20 LED benutzt werden. Aussehen z.B.<br />
<gallery mode="packed-hover" widths=320px heights=240px><br />
Datei:Wandding_Zeichnung.svg|Fablab Logo<br />
Datei:Wandding_Zeichnung2.svg|Muster<br />
</gallery><br />
<br />
Die einzelnen LED Streifen können dann mit jedem Beat in Tiefen, Mitten bzw. Höhen blinken und die Farbe passt sich der vorherrschenden Frequenz des Liedes an. Die Blinkmuster der LED passen sich somit dynamisch an das Lied an. Alternativ können auch statische Animationen und Farbwechsel vorgegeben werden.<br />
<br />
Folgende Anforderungen werden gestellt:<br />
* Portable<br />
* LED auch im hellen sichtbar<br />
* Nachbaubar<br />
* Gut aussehen<br />
* Stabil verarbeitet<br />
<br /><br />
Offene Fragen:<br />
* Bedienung über Display + Taster oder Fernbedienung?<br />
* Controller Arduino (weit verbreitet, einfach zu nutzen) oder Nucleo-F446 (viel mehr Rechenleistung, DSP, DMA, S/PDIF Eingang usw.)?<br />
* Nur Mikrofon oder auch Line-In bzw. S/PDIF?<br />
<br /><br />
Bestehende Analogschaltung muss etwas überarbeitet werden. Anpassung an neue Anforderungen (nur Mono statt Stereo, Mikrofonverstärker). Wird direkt als Schild für das Entwicklungsboard entworfen. Sofern möglich 1-Seitige Platine zum einfacheren Nachbau.</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=LED_Schild&diff=2026LED Schild2016-04-30T14:44:10Z<p>Marcel: </p>
<hr />
<div><onlyinclude><br />
Ein blinkendes Schild als Logo/Werbung für das Fablab. Inklusive Musikspielereien wie auch im [http://fablab-cottbus.de/index.php/Audio_Board Audio Board].<br />
</onlyinclude><br />
<br />
= Idee =<br />
Eine portable Abwandlung des Audio Projektes, die wir mit auf Ausstellungen nehmen können.<br />
<br />
= Konzept =<br />
Mehrere LED werden in verschiedenen Mustern auf einem Holzbrett angebracht. Es soll autonom laufen und verschiedene Blinkmuster haben.<br />
Es könnten 4 LED Stränge mit je 20 LED benutzt werden. Aussehen z.B.<br />
<gallery mode="packed-hover" widths=320px heights=240px><br />
Datei:Wandding_Zeichnung.svg|Fablab Logo<br />
Datei:Wandding_Zeichnung2.svg|Muster<br />
</gallery><br />
<br />
Folgende Anforderungen werden gestellt:<br />
* Portable<br />
* LED auch im hellen sichtbar<br />
* Nachbaubar<br />
* Gut aussehen<br />
* Stabil verarbeitet<br />
<br /><br />
Offene Fragen:<br />
* Bedienung über Display + Taster oder Fernbedienung?<br />
* Controller Arduino (weit verbreitet, einfach zu nutzen) oder Nucleo-F446 (viel mehr Rechenleistung, DSP, DMA, S/PDIF Eingang usw.)?<br />
* Nur Mikrofon oder auch Line-In bzw. S/PDIF?<br />
<br /><br />
Bestehende Analogschaltung muss etwas überarbeitet werden. Anpassung an neue Anforderungen (nur Mono statt Stereo, Mikrofonverstärker). Wird direkt als Schild für das Entwicklungsboard entworfen. Sofern möglich 1-Seitige Platine zum einfacheren Nachbau.</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=LED_Schild&diff=2025LED Schild2016-04-30T13:41:29Z<p>Marcel: </p>
<hr />
<div><onlyinclude><br />
Ein blinkendes Schild als Logo/Werbung für das Fablab. Inklusive Musikspielereien.<br />
</onlyinclude><br />
<br />
= Idee =<br />
Eine portable Abwandlung des Audio Projektes, die wir mit auf Ausstellungen nehmen können.<br />
<br />
= Konzept =<br />
Mehrere LED werden in verschiedenen Mustern auf einem Holzbrett angebracht. Es soll autonom laufen und verschiedene Blinkmuster haben.<br />
Es könnten 4 LED Stränge mit je 20 LED benutzt werden. Aussehen z.B.<br />
<gallery mode="packed-hover" widths=320px heights=240px><br />
Datei:Wandding_Zeichnung.svg|Fablab Logo<br />
Datei:Wandding_Zeichnung2.svg|Muster<br />
</gallery><br />
<br />
Folgende Anforderungen werden gestellt:<br />
* Portable<br />
* LED auch im hellen sichtbar<br />
* Nachbaubar<br />
* Gut aussehen<br />
* Stabil verarbeitet<br />
<br /><br />
Offene Fragen:<br />
* Bedienung über Display + Taster oder Fernbedienung?<br />
* Controller Arduino (weit verbreitet, einfach zu nutzen) oder Nucleo-F446 (viel mehr Rechenleistung, DSP, DMA, S/PDIF Eingang usw.)?<br />
* Nur Mikrofon oder auch Line-In bzw. S/PDIF?<br />
<br /><br />
Bestehende Analogschaltung muss etwas überarbeitet werden. Anpassung an neue Anforderungen (nur Mono statt Stereo, Mikrofonverstärker). Wird direkt als Schild für das Entwicklungsboard entworfen. Sofern möglich 1-Seitige Platine zum einfacheren Nachbau.</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=LED_Schild&diff=2024LED Schild2016-04-30T13:38:25Z<p>Marcel: </p>
<hr />
<div><onlyinclude><br />
Ein blinkendes Schild als Logo/Werbung für das Fablab. Inklusive Musikspielereien.<br />
</onlyinclude><br />
<br />
= Idee =<br />
Eine portable Abwandlung des Audio Projektes, die wir mit auf Ausstellungen nehmen können.<br />
<br />
= Konzept =<br />
Mehrere LED werden in verschiedenen Mustern auf einem Holzbrett angebracht. Es soll autonom laufen und verschiedene Blinkmuster haben.<br />
Es könnten 4 LED Stränge mit je 20 LED benutzt werden. Aussehen z.B.<br />
<gallery mode="packed-hover" widths=320px heights=240px><br />
Datei:Wandding_Zeichnung.svg|Fablab Logo<br />
Datei:Wandding_Zeichnung2.svg|Muster<br />
</gallery><br />
<br />
Folgende Anforderungen werden gestellt:<br />
* Portable<br />
* LED auch im hellen sichtbar<br />
* Nachbaubar<br />
* Gut aussehen<br />
* Stabil verarbeitet<br />
<br /><br />
Offene Fragen:<br />
* Bedienung über Display + Taster oder Fernbedienung?<br />
* Controller Arduino (weit verbreitet, einfach zu nutzen) oder Nucleo-F446 (viel mehr Rechenleistung, DSP, DMA, S/PDIF Eingang usw.)?</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=LED_Schild&diff=2023LED Schild2016-04-30T13:37:43Z<p>Marcel: Die Seite wurde neu angelegt: „<onlyinclude> Ein blinkendes Schild als Logo/Werbung für das Fablab. Inklusive Musikspielereien. </onlyinclude> = Idee = Eine portable Abwandlung des Audio P…“</p>
<hr />
<div><onlyinclude><br />
Ein blinkendes Schild als Logo/Werbung für das Fablab. Inklusive Musikspielereien.<br />
</onlyinclude><br />
<br />
= Idee =<br />
Eine portable Abwandlung des Audio Projektes, die wir mit auf Ausstellungen nehmen können.<br />
<br />
= Konzept =<br />
Mehrere LED werden in verschiedenen Mustern auf einem Holzbrett angebracht. Es soll autonom laufen und verschiedene Blinkmuster haben.<br />
Es könnten 4 LED Stränge mit je 20 LED benutzt werden. Aussehen z.B.<br />
<gallery mode="packed-hover" widths=320px heights=240px><br />
Datei:Wandding_Zeichnung.svg|Fablab Logo<br />
Datei:Wandding_Zeichnung2.svg|Muster<br />
</gallery><br />
<br />
Folgende Anforderungen werden gestellt:<br />
* Portable<br />
* LED auch im hellen sichtbar<br />
* Nachbaubar<br />
* Gut aussehen<br />
* Stabil verarbeitet<br />
<br /><br />
Offene Fragen:<br />
Bedienung über Display + Taster oder Fernbedienung?<br /><br />
Controller Arduino (weit verbreitet, einfach zu nutzen) oder Nucleo-F446 (viel mehr Rechenleistung, DSP, DMA, S/PDIF Eingang usw.)?<br /></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Datei:Wandding_Zeichnung2.svg&diff=2022Datei:Wandding Zeichnung2.svg2016-04-30T13:28:46Z<p>Marcel: </p>
<hr />
<div></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Datei:Wandding_Zeichnung.svg&diff=2021Datei:Wandding Zeichnung.svg2016-04-30T13:28:27Z<p>Marcel: </p>
<hr />
<div></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Projekte&diff=2020Projekte2016-04-30T13:23:11Z<p>Marcel: </p>
<hr />
<div>Auf dieser Seite werden die Projekte vorgestellt, welche durch die Mitglieder des Fablabs bearbeitet werden.<br />
<br />
= [[Solarbetriebene Fahrradpumpstation]] =<br />
{{:Solarbetriebene Fahrradpumpstation}}<br />
= [[Ehrenlicht 3.0]] =<br />
{{:Ehrenlicht 3.0}}<br />
= [[Audio Board]] =<br />
{{:Audio Board}}<br />
= [[LED Schild]] =<br />
{{:LED Schild}}<br />
= [[Garderobenständer aus Ästen]] =<br />
{{:Garderobenständer aus Ästen}}<br />
= [[Holzstuhl]] =<br />
{{:Holzstuhl}}</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Mikrocontrollerkurs_(erweitert)&diff=1416Mikrocontrollerkurs (erweitert)2015-05-23T18:22:50Z<p>Marcel: /* Programm */</p>
<hr />
<div>[[Datei:Microcontroller.jpg|300px|miniatur|Mikrocontroller selbst programmieren]]<br />
== Inhalt ==<br />
Wie auch beim Mikrocontrollerkurs werden die Grundlagen des Arduino Systems vermittelt. Es wird jedoch als Einleitung noch eine kurze Einführung in die allgemeine Elektrotechnik gegeben<br><br />
Dauer: 2 Nachmittage zu je 4 Stunden<br><br />
Termin: '''27. und 28. Juni 2015 ab 14:00'''<br><br />
<br />
== Benötigt für Teilnehmer ==<br />
* Laptop<br />
* [http://arduino.cc/en/Main/Software Arduino Software]<br />
* [http://cloud.fablab-cottbus.de/public.php?service=files&t=26f9c6bf5b0ce31d10ba1bd071ae6aa3 FabLab Lib für den Kurs] (Nach 'Eigene Dokumente\Arduino\libraries\' entpacken)<br />
* [http://cloud.fablab-cottbus.de/public.php?service=files&t=e993ba31f4a0d30acfd4c4571b187a0c Kurs Unterlagen] Sketches mit den Programmen<br />
* [http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx Treiber für den Programmieradapter]<br />
* 25€ Teilnahmegebühr und Materialkosten (Materialien können mit nach Hause genommen werden)<br />
<br />
== Programm ==<br />
Tag 1: Einleitung<br />
* Was und Strom und Spannung?<br />
* Widerstand, Kondensator, Spule<br />
* Transistor, MOSFET als Schalter<br />
* Operationsverstärker<br />
<br><br />
Tag 1/2: Grundlagen und Licht<br />
* Board bauen<br />
* Einfache Ein-/Ausgabe Funktionen; Digital und Analog<br />
* LED per PWM dimmen<br />
<br><br />
Tag 2: Krach<br />
* einfache Soundausgabe<br />
* erweiterte Soundausgabe<br />
<br><br />
Tag 2: Sonstiges<br />
* Reservezeit, falls Themen offen sind<br />
* Zeit für eure Fragen und Themenwünsche<br />
<br />
== Anmeldung ==<br />
Anmeldung direkt im FabLab zu den Öffnungszeiten oder über info@fablab-cottbus.de<br><br />
Durch den begrenzten Raum können nur eine begrenzte Anzahl Teilnehmer untergebracht werden. Daher bitte nur Anmelden wenn ihr sicher an allen Tagen Zeit habt.<br />
<br />
== Teilnehmer ==<br />
Max. 6 Teilnehmer<br></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Mikrocontrollerkurs_(erweitert)&diff=1415Mikrocontrollerkurs (erweitert)2015-05-23T18:21:46Z<p>Marcel: /* Benötigt für Teilnehmer */</p>
<hr />
<div>[[Datei:Microcontroller.jpg|300px|miniatur|Mikrocontroller selbst programmieren]]<br />
== Inhalt ==<br />
Wie auch beim Mikrocontrollerkurs werden die Grundlagen des Arduino Systems vermittelt. Es wird jedoch als Einleitung noch eine kurze Einführung in die allgemeine Elektrotechnik gegeben<br><br />
Dauer: 2 Nachmittage zu je 4 Stunden<br><br />
Termin: '''27. und 28. Juni 2015 ab 14:00'''<br><br />
<br />
== Benötigt für Teilnehmer ==<br />
* Laptop<br />
* [http://arduino.cc/en/Main/Software Arduino Software]<br />
* [http://cloud.fablab-cottbus.de/public.php?service=files&t=26f9c6bf5b0ce31d10ba1bd071ae6aa3 FabLab Lib für den Kurs] (Nach 'Eigene Dokumente\Arduino\libraries\' entpacken)<br />
* [http://cloud.fablab-cottbus.de/public.php?service=files&t=e993ba31f4a0d30acfd4c4571b187a0c Kurs Unterlagen] Sketches mit den Programmen<br />
* [http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx Treiber für den Programmieradapter]<br />
* 25€ Teilnahmegebühr und Materialkosten (Materialien können mit nach Hause genommen werden)<br />
<br />
== Programm ==<br />
Tag 1 und 2: Einleitung<br />
* Was und Strom und Spannung?<br />
* Widerstand, Kondensator, Spule<br />
* Transistor, MOSFET als Schalter<br />
* Operationsverstärker<br />
<br><br />
Tag 3: Grundlagen und Licht<br />
* Board bauen<br />
* Einfache Ein-/Ausgabe Funktionen; Digital und Analog<br />
* LED per PWM dimmen<br />
<br><br />
Tag 4: Krach<br />
* einfache Soundausgabe<br />
* erweiterte Soundausgabe<br />
<br><br />
Tag 5: Sonstiges<br />
* Reservezeit, falls Themen offen sind<br />
* Zeit für eure Fragen und Themenwünsche<br />
<br />
== Anmeldung ==<br />
Anmeldung direkt im FabLab zu den Öffnungszeiten oder über info@fablab-cottbus.de<br><br />
Durch den begrenzten Raum können nur eine begrenzte Anzahl Teilnehmer untergebracht werden. Daher bitte nur Anmelden wenn ihr sicher an allen Tagen Zeit habt.<br />
<br />
== Teilnehmer ==<br />
Max. 6 Teilnehmer<br></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Mikrocontrollerkurs_(erweitert)&diff=1414Mikrocontrollerkurs (erweitert)2015-05-23T18:21:33Z<p>Marcel: /* Inhalt */</p>
<hr />
<div>[[Datei:Microcontroller.jpg|300px|miniatur|Mikrocontroller selbst programmieren]]<br />
== Inhalt ==<br />
Wie auch beim Mikrocontrollerkurs werden die Grundlagen des Arduino Systems vermittelt. Es wird jedoch als Einleitung noch eine kurze Einführung in die allgemeine Elektrotechnik gegeben<br><br />
Dauer: 2 Nachmittage zu je 4 Stunden<br><br />
Termin: '''27. und 28. Juni 2015 ab 14:00'''<br><br />
<br />
== Benötigt für Teilnehmer ==<br />
* Laptop<br />
* [http://arduino.cc/en/Main/Software Arduino Software]<br />
* [http://cloud.fablab-cottbus.de/public.php?service=files&t=26f9c6bf5b0ce31d10ba1bd071ae6aa3 FabLab Lib für den Kurs] (Nach 'Eigene Dokumente\Arduino\libraries\' entpacken)<br />
* [http://cloud.fablab-cottbus.de/public.php?service=files&t=e993ba31f4a0d30acfd4c4571b187a0c Kurs Unterlagen] Sketches mit den Programmen<br />
* [http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx Treiber für den Programmieradapter]<br />
* 30€ Teilnahmegebühr und Materialkosten (Materialien können mit nach Hause genommen werden)<br />
<br />
== Programm ==<br />
Tag 1 und 2: Einleitung<br />
* Was und Strom und Spannung?<br />
* Widerstand, Kondensator, Spule<br />
* Transistor, MOSFET als Schalter<br />
* Operationsverstärker<br />
<br><br />
Tag 3: Grundlagen und Licht<br />
* Board bauen<br />
* Einfache Ein-/Ausgabe Funktionen; Digital und Analog<br />
* LED per PWM dimmen<br />
<br><br />
Tag 4: Krach<br />
* einfache Soundausgabe<br />
* erweiterte Soundausgabe<br />
<br><br />
Tag 5: Sonstiges<br />
* Reservezeit, falls Themen offen sind<br />
* Zeit für eure Fragen und Themenwünsche<br />
<br />
== Anmeldung ==<br />
Anmeldung direkt im FabLab zu den Öffnungszeiten oder über info@fablab-cottbus.de<br><br />
Durch den begrenzten Raum können nur eine begrenzte Anzahl Teilnehmer untergebracht werden. Daher bitte nur Anmelden wenn ihr sicher an allen Tagen Zeit habt.<br />
<br />
== Teilnehmer ==<br />
Max. 6 Teilnehmer<br></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Mikrocontrollerkurs_(erweitert)&diff=1328Mikrocontrollerkurs (erweitert)2015-04-16T09:02:14Z<p>Marcel: Die Seite wurde neu angelegt: „Mikrocontroller selbst programmieren == Inhalt == Wie auch beim Mikrocontrollerkurs werden die Grundlagen des Ardu…“</p>
<hr />
<div>[[Datei:Microcontroller.jpg|300px|miniatur|Mikrocontroller selbst programmieren]]<br />
== Inhalt ==<br />
Wie auch beim Mikrocontrollerkurs werden die Grundlagen des Arduino Systems vermittelt. Es wird jedoch als Einleitung noch eine kurze Einführung in die allgemeine Elektrotechnik gegeben<br><br />
Dauer: 5 Nachmittage zu je 2 Stunden<br><br />
Termin: '''25.5.2015 bis 29.5.2015 jeweils 18:00 - 20:00'''<br><br />
<br />
== Benötigt für Teilnehmer ==<br />
* Laptop<br />
* [http://arduino.cc/en/Main/Software Arduino Software]<br />
* [http://cloud.fablab-cottbus.de/public.php?service=files&t=26f9c6bf5b0ce31d10ba1bd071ae6aa3 FabLab Lib für den Kurs] (Nach 'Eigene Dokumente\Arduino\libraries\' entpacken)<br />
* [http://cloud.fablab-cottbus.de/public.php?service=files&t=e993ba31f4a0d30acfd4c4571b187a0c Kurs Unterlagen] Sketches mit den Programmen<br />
* [http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx Treiber für den Programmieradapter]<br />
* 30€ Teilnahmegebühr und Materialkosten (Materialien können mit nach Hause genommen werden)<br />
<br />
== Programm ==<br />
Tag 1 und 2: Einleitung<br />
* Was und Strom und Spannung?<br />
* Widerstand, Kondensator, Spule<br />
* Transistor, MOSFET als Schalter<br />
* Operationsverstärker<br />
<br><br />
Tag 3: Grundlagen und Licht<br />
* Board bauen<br />
* Einfache Ein-/Ausgabe Funktionen; Digital und Analog<br />
* LED per PWM dimmen<br />
<br><br />
Tag 4: Krach<br />
* einfache Soundausgabe<br />
* erweiterte Soundausgabe<br />
<br><br />
Tag 5: Sonstiges<br />
* Reservezeit, falls Themen offen sind<br />
* Zeit für eure Fragen und Themenwünsche<br />
<br />
== Anmeldung ==<br />
Anmeldung direkt im FabLab zu den Öffnungszeiten oder über info@fablab-cottbus.de<br><br />
Durch den begrenzten Raum können nur eine begrenzte Anzahl Teilnehmer untergebracht werden. Daher bitte nur Anmelden wenn ihr sicher an allen Tagen Zeit habt.<br />
<br />
== Teilnehmer ==<br />
Max. 6 Teilnehmer<br></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1225Audio Board2015-01-23T15:18:41Z<p>Marcel: /* Bilder */</p>
<hr />
<div>{{#ev:youtube|id=http://youtu.be/opSofzCnbJo|480x320|right|Beispielanimation|frame}}<br />
<onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere Zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen atmega328 ausgetestet. Da dieser Controller nur mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum Einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareressourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschließen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br /><br />
<br />
Eine Echtzeitauswertung in dem Sinne, dass das System innerhalb weniger ms oder sogar µs auf ein Audiosignal reagiert ist mit dem Aufbau nicht möglich. Der Grundgedanke ist es die Audiodaten 20mal pro Sekunde zu erfassen und auszuwerten. Diese Daten werden gespeichert und durch ein Animationssystem, welches 60 Bilder pro Sekunde berechnet, optisch dargestellt. Dadurch, dass das menschliche Sehempfinden recht träge ist und sich sichtbar immer etwas verändert wirkt es am Ende so, als ob die Animation schnell auf die Musik reagiert, obwohl diese Reaktion nur alle 100ms erfolgt.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Übersteuern entgegen wirkt. Außerdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzen. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schließen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschließen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansprüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu Ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum Debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzen, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im Folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2, TCC0<br />
Der ADC wird im Freerun Modus konfiguriert und der Timer TCC0 auf eine Frequenz von 32kHz gestellt. Wird eine Messung mit '''adc_startSampling()''' gestartet werden die DMA Kanäle aktiviert und laden mit jedem overflow von TCC0 einen Messwert in den Speicher. Auf diese Weise werden 128 Messwerte je Kanal erfasst. Ist diese Datenerfassung abgeschlossen wird ''adc_state'' durch '''adc_check()''' auf ''ADC_STATE_SAMPLING_DONE'' gesetzt.<br /><br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
spectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbereich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösung der Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins Stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind wie folgt eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fließendes Mittel gebildet. Ist der momentane Wert um einen bestimmten Prozent-Wert höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, und meistens auch für die Höhen funktioniert es nicht so gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kalibration der Daten im Quelltext des Matrix Projektes. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kalibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden die Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude werden abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Einlesen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Einlesen der Daten nicht hinausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== WS2812 Lib ==<br />
* CWS2812.cpp, CWS2812.h<br />
* Nutzt USARTC1 und DMA Ch0<br />
Die Vorteile der WS2812 LED liegt darin, dass diese einen eingebauten Treiber besitzen und die Daten über eine einzige Datenleitung übertragen werden. Dies macht einen Hardwareaufbau sehr einfach. Der Nachteil liegt darin, dass das Protokoll für die Daten ein sehr striktes timing erfordern. Andere Libraries machen dies über eine Verzögerung, wodurch Rechenleistung mit warten verschwendet wird.<br /><br />
<br />
Daher erfolgt hier ein Ansatz über den USART (im SPI Modus) und DMA. Dies hat jedoch den Nachteil, dass pro zu sendendem Bit 1 Byte RAM benötigt wird. Eine LED erwartet 3 Byte, also 24 Bit, und benötigt somit 24 Byte RAM im Controller. Dafür werden die Daten mit Hilfe von DMA gesendet, so dass keine Rechenleistung in Warteschleifen verbraucht wird. Da der verwendete Controller 8kb RAM hat und nur 42 LEDs in der Matrix sind ist diese Lösung in dieser Situation gut brauchbar.<br /><br />
<br />
Die Initialisierung der Peripherie erfolgt im Konstruktor der Klasse. Es wird USARTC1 benutzt und der Output liegt an Port C Pin 7. Port C Pin 5 und 6 sind die Clock- bzw. Empfangsleitung und werden nicht benötigt, aber stehen nicht mehr für andere Anwendungen zur Verfügung. Die Anzahl der LEDs muss in der CWS2812.h durch das Symbol ''LED_NUM'' definiert werden. Mit '''input(uint8_t *led_data, uint16_t len)''' werden die RGB Daten in das WS2818 System übertragen. Pro LED werden 3 Byte, je eines für Rot, Grün und Blau, erwartet. '''transfer()''' startet den DMA Transfer und mit '''isBusy()''' kann geprüft werden, ob dieser abgeschlossen ist (!= 0).<br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest.<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden. Dies ist der Fall in der Basic Version des Quelltextes.<br />
<br />
== Weiterführende Ideen ==<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden, wie sie im Video zu sehen ist. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Die Anzahl der leichtenden LEDs pro Spalte richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br /><br />
<br />
= Download =<br />
[http://github.com/MarJong/AudioBoard Download über GitHub]<br />
<br />
= Bilder =<br />
<gallery mode="packed-hover" widths=320px heights=240px><br />
Datei:audioboard_debug_ausgabe.png|Debug Ausgabe auf dem Display. Es zeigt: Name der Animation, Bilder pro Sekunde (FPS) und Samplevorgänge pro Sekunde (SPS), die BPM in den Höhen, Mitten, Tiefen und Alle zusammen, die 7 Bänder für linken und rechten Kanal und ganz unten rechts den Zoomfaktor für den Graphen.<br />
Datei:audioboard_animation1.png|Mono-Spektrum Anzeige. Die Daten vom linken und rechten Kanal werden zusammengefasst und angezeigt.<br />
Datei:audioboard_animation2.png|Stereo-Spektrum Anzeige. Die Daten vom linken und rechten Kanal werden getrennt links und rechts angezeigt und können sich in der Mitte überlagern.<br />
Datei:audioboard_animation3.png|Etwas abstrakter: Mit jedem Beat fliegt 1 Partikel, dessen Farbe und Geschwindigkeit von der Frequenz bzw. den BPM abhängig ist, über die Matrix.<br />
Datei:audioboard_animation4.png|Bunter Kreis, der sich bewegt. Die Farbe ändert sich mit der Frequenz.<br />
</gallery></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Datei:Audioboard_animation4.png&diff=1224Datei:Audioboard animation4.png2015-01-23T15:17:52Z<p>Marcel: </p>
<hr />
<div></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1223Audio Board2015-01-23T15:00:17Z<p>Marcel: </p>
<hr />
<div>{{#ev:youtube|id=http://youtu.be/opSofzCnbJo|480x320|right|Beispielanimation|frame}}<br />
<onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere Zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen atmega328 ausgetestet. Da dieser Controller nur mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum Einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareressourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschließen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br /><br />
<br />
Eine Echtzeitauswertung in dem Sinne, dass das System innerhalb weniger ms oder sogar µs auf ein Audiosignal reagiert ist mit dem Aufbau nicht möglich. Der Grundgedanke ist es die Audiodaten 20mal pro Sekunde zu erfassen und auszuwerten. Diese Daten werden gespeichert und durch ein Animationssystem, welches 60 Bilder pro Sekunde berechnet, optisch dargestellt. Dadurch, dass das menschliche Sehempfinden recht träge ist und sich sichtbar immer etwas verändert wirkt es am Ende so, als ob die Animation schnell auf die Musik reagiert, obwohl diese Reaktion nur alle 100ms erfolgt.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Übersteuern entgegen wirkt. Außerdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzen. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schließen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschließen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansprüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu Ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum Debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzen, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im Folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2, TCC0<br />
Der ADC wird im Freerun Modus konfiguriert und der Timer TCC0 auf eine Frequenz von 32kHz gestellt. Wird eine Messung mit '''adc_startSampling()''' gestartet werden die DMA Kanäle aktiviert und laden mit jedem overflow von TCC0 einen Messwert in den Speicher. Auf diese Weise werden 128 Messwerte je Kanal erfasst. Ist diese Datenerfassung abgeschlossen wird ''adc_state'' durch '''adc_check()''' auf ''ADC_STATE_SAMPLING_DONE'' gesetzt.<br /><br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
spectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbereich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösung der Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins Stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind wie folgt eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fließendes Mittel gebildet. Ist der momentane Wert um einen bestimmten Prozent-Wert höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, und meistens auch für die Höhen funktioniert es nicht so gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kalibration der Daten im Quelltext des Matrix Projektes. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kalibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden die Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude werden abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Einlesen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Einlesen der Daten nicht hinausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== WS2812 Lib ==<br />
* CWS2812.cpp, CWS2812.h<br />
* Nutzt USARTC1 und DMA Ch0<br />
Die Vorteile der WS2812 LED liegt darin, dass diese einen eingebauten Treiber besitzen und die Daten über eine einzige Datenleitung übertragen werden. Dies macht einen Hardwareaufbau sehr einfach. Der Nachteil liegt darin, dass das Protokoll für die Daten ein sehr striktes timing erfordern. Andere Libraries machen dies über eine Verzögerung, wodurch Rechenleistung mit warten verschwendet wird.<br /><br />
<br />
Daher erfolgt hier ein Ansatz über den USART (im SPI Modus) und DMA. Dies hat jedoch den Nachteil, dass pro zu sendendem Bit 1 Byte RAM benötigt wird. Eine LED erwartet 3 Byte, also 24 Bit, und benötigt somit 24 Byte RAM im Controller. Dafür werden die Daten mit Hilfe von DMA gesendet, so dass keine Rechenleistung in Warteschleifen verbraucht wird. Da der verwendete Controller 8kb RAM hat und nur 42 LEDs in der Matrix sind ist diese Lösung in dieser Situation gut brauchbar.<br /><br />
<br />
Die Initialisierung der Peripherie erfolgt im Konstruktor der Klasse. Es wird USARTC1 benutzt und der Output liegt an Port C Pin 7. Port C Pin 5 und 6 sind die Clock- bzw. Empfangsleitung und werden nicht benötigt, aber stehen nicht mehr für andere Anwendungen zur Verfügung. Die Anzahl der LEDs muss in der CWS2812.h durch das Symbol ''LED_NUM'' definiert werden. Mit '''input(uint8_t *led_data, uint16_t len)''' werden die RGB Daten in das WS2818 System übertragen. Pro LED werden 3 Byte, je eines für Rot, Grün und Blau, erwartet. '''transfer()''' startet den DMA Transfer und mit '''isBusy()''' kann geprüft werden, ob dieser abgeschlossen ist (!= 0).<br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest.<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden. Dies ist der Fall in der Basic Version des Quelltextes.<br />
<br />
== Weiterführende Ideen ==<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden, wie sie im Video zu sehen ist. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Die Anzahl der leichtenden LEDs pro Spalte richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br /><br />
<br />
= Download =<br />
[http://github.com/MarJong/AudioBoard Download über GitHub]<br />
<br />
= Bilder =<br />
<gallery mode="packed-hover" widths=320px heights=240px><br />
Datei:audioboard_debug_ausgabe.png|Debug Ausgabe auf dem Display. Es zeigt: Name der Animation, Bilder pro Sekunde (FPS) und Samplevorgänge pro Sekunde (SPS), die BPM in den Höhen, Mitten, Tiefen und Alle zusammen, die 7 Bänder für linken und rechten Kanal und ganz unten rechts den Zoomfaktor für den Graphen.<br />
Datei:audioboard_animation1.png|Mono-Spektrum Anzeige. Die Daten vom linken und rechten Kanal werden zusammengefasst und angezeigt.<br />
Datei:audioboard_animation2.png|Stereo-Spektrum Anzeige. Die Daten vom linken und rechten Kanal werden getrennt links und rechts angezeigt und können sich in der Mitte überlagern.<br />
Datei:audioboard_animation3.png|Etwas abstrakter: Mit jedem Beat fliegt 1 Partikel, dessen Farbe und Geschwindigkeit von der Frequenz bzw. den BPM abhängig ist, über die Matrix.<br />
</gallery></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Datei:Audioboard_animation3.png&diff=1217Datei:Audioboard animation3.png2015-01-21T15:45:55Z<p>Marcel: </p>
<hr />
<div></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1216Audio Board2015-01-21T15:45:36Z<p>Marcel: /* Bilder */</p>
<hr />
<div>{{#ev:youtube|id=http://youtu.be/opSofzCnbJo|480x320|right|Beispielanimation|frame}}<br />
<onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere Zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen atmega328 ausgetestet. Da dieser Controller nur mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum Einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareressourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschließen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br /><br />
<br />
Eine Echtzeitauswertung in dem Sinne, dass das System innerhalb weniger ms oder sogar µs auf ein Audiosignal reagiert ist mit dem Aufbau nicht möglich. Der Grundgedanke ist es die Audiodaten 20mal pro Sekunde zu erfassen und auszuwerten. Diese Daten werden gespeichert und durch ein Animationssystem, welches 60 Bilder pro Sekunde berechnet, optisch dargestellt. Dadurch, dass das menschliche Sehempfinden recht träge ist und sich sichtbar immer etwas verändert wirkt es am Ende so, als ob die Animation schnell auf die Musik reagiert, obwohl diese Reaktion nur alle 100ms erfolgt.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Übersteuern entgegen wirkt. Außerdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzen. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schließen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschließen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansprüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu Ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum Debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzen, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im Folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2, TCC0<br />
Der ADC wird im Freerun Modus konfiguriert und der Timer TCC0 auf eine Frequenz von 32kHz gestellt. Wird eine Messung mit '''adc_startSampling()''' gestartet werden die DMA Kanäle aktiviert und laden mit jedem overflow von TCC0 einen Messwert in den Speicher. Auf diese Weise werden 128 Messwerte je Kanal erfasst. Ist diese Datenerfassung abgeschlossen wird ''adc_state'' durch '''adc_check()''' auf ''ADC_STATE_SAMPLING_DONE'' gesetzt.<br /><br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
spectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbereich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösung der Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins Stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind wie folgt eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fließendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, und meistens auch für die Höhen funktioniert es nicht so gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kalibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kalibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden die Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude werden abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Einlesen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Einlesen der Daten nicht hinausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== WS2812 Lib ==<br />
* CWS2812.cpp, CWS2812.h<br />
* Nutzt USARTC1 und DMA Ch0<br />
Die Vorteile der WS2812 LED liegt darin, dass diese einen eingebauten Treiber besitzen und die Daten über eine einzige Datenleitung übertragen werden. Dies macht einen Hardwareaufbau sehr einfach. Der Nachteil liegt darin, dass das Protokoll für die Daten ein sehr striktes timing erfordern. Andere Libraries machen dies über eine Verzögerung, wodurch Rechenleistung mit warten verschwendet wird.<br /><br />
<br />
Daher erfolgt hier ein Ansatz über den USART (im SPI Modus) und DMA. Dies hat jedoch den Nachteil, dass pro zu sendendem Bit 1 Byte RAM benötigt wird. Eine LED erwartet 3 Byte, also 24 Bit, und benötigt somit 24 Byte RAM im Controller. Dafür werden die Daten mit Hilfe von DMA gesendet, so dass keine Rechenleistung in Warteschleifen verbraucht wird. Da der verwendete Controller 8kb RAM hat und nur 42 LEDs in der Matrix sind ist diese Lösung in dieser Situation gut brauchbar.<br /><br />
<br />
Die Initialisierung der Peripherie erfolgt im Konstruktor der Klasse. Es wird USARTC1 benutzt und der Output liegt an Port C Pin 7. Port C Pin 5 und 6 sind die Clock- bzw. Empfangsleitung und werden nicht benötigt, aber stehen nicht mehr für andere Anwendungen zur Verfügung. Die Anzahl der LEDs muss in der CWS2812.h durch das Symbol ''LED_NUM'' definiert werden. Mit '''input(uint8_t *led_data, uint16_t len)''' werden die RGB Daten in das WS2818 System übertragen. Pro LED werden 3 Byte, je eines für Rot, Grün und Blau, erwartet. '''transfer()''' startet den DMA Transfer und mit '''isBusy()''' kann geprüft werden, ob dieser abgeschlossen ist (!= 0).<br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest. (* In der momentanen Version im Wiki ist ein automatischer Wechsel und ähnliche Features noch nicht implementiert)<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden.<br />
<br />
== Weiterführende Ideen ==<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden, wie sie im Video zu sehen ist. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Die Anzahl der leichtenden LEDs pro Spalte richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br /><br />
<br />
== Bilder ==<br />
<gallery mode="packed-hover" widths=320px heights=240px><br />
Datei:audioboard_debug_ausgabe.png|Debug Ausgabe auf dem Display. Es zeigt: Name der Animation, Bilder pro Sekunde (FPS) und Samplevorgänge pro Sekunde (SPS), die BPM in den Höhen, Mitten, Tiefen und Alle zusammen, die 7 Bänder für linken und rechten Kanal und ganz unten rechts den Zoomfaktor für den Graphen.<br />
Datei:audioboard_animation1.png|Mono-Spektrum Anzeige. Die Daten vom linken und rechten Kanal werden zusammengefasst und angezeigt.<br />
Datei:audioboard_animation2.png|Stereo-Spektrum Anzeige. Die Daten vom linken und rechten Kanal werden getrennt links und rechts angezeigt und können sich in der Mitte überlagern.<br />
Datei:audioboard_animation3.png|Etwas abstrakter: Mit jedem Beat fliegt 1 Partikel, dessen Farbe und Geschwindigkeit von der Frequenz bzw. den BPM abhängig ist, über die Matrix.<br />
</gallery></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1215Audio Board2015-01-21T15:41:35Z<p>Marcel: </p>
<hr />
<div>{{#ev:youtube|id=http://youtu.be/opSofzCnbJo|480x320|right|Beispielanimation|frame}}<br />
<onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere Zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen atmega328 ausgetestet. Da dieser Controller nur mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum Einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareressourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschließen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br /><br />
<br />
Eine Echtzeitauswertung in dem Sinne, dass das System innerhalb weniger ms oder sogar µs auf ein Audiosignal reagiert ist mit dem Aufbau nicht möglich. Der Grundgedanke ist es die Audiodaten 20mal pro Sekunde zu erfassen und auszuwerten. Diese Daten werden gespeichert und durch ein Animationssystem, welches 60 Bilder pro Sekunde berechnet, optisch dargestellt. Dadurch, dass das menschliche Sehempfinden recht träge ist und sich sichtbar immer etwas verändert wirkt es am Ende so, als ob die Animation schnell auf die Musik reagiert, obwohl diese Reaktion nur alle 100ms erfolgt.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Übersteuern entgegen wirkt. Außerdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzen. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schließen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschließen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansprüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu Ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum Debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzen, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im Folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2, TCC0<br />
Der ADC wird im Freerun Modus konfiguriert und der Timer TCC0 auf eine Frequenz von 32kHz gestellt. Wird eine Messung mit '''adc_startSampling()''' gestartet werden die DMA Kanäle aktiviert und laden mit jedem overflow von TCC0 einen Messwert in den Speicher. Auf diese Weise werden 128 Messwerte je Kanal erfasst. Ist diese Datenerfassung abgeschlossen wird ''adc_state'' durch '''adc_check()''' auf ''ADC_STATE_SAMPLING_DONE'' gesetzt.<br /><br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
spectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbereich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösung der Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins Stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind wie folgt eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fließendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, und meistens auch für die Höhen funktioniert es nicht so gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kalibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kalibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden die Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude werden abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Einlesen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Einlesen der Daten nicht hinausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== WS2812 Lib ==<br />
* CWS2812.cpp, CWS2812.h<br />
* Nutzt USARTC1 und DMA Ch0<br />
Die Vorteile der WS2812 LED liegt darin, dass diese einen eingebauten Treiber besitzen und die Daten über eine einzige Datenleitung übertragen werden. Dies macht einen Hardwareaufbau sehr einfach. Der Nachteil liegt darin, dass das Protokoll für die Daten ein sehr striktes timing erfordern. Andere Libraries machen dies über eine Verzögerung, wodurch Rechenleistung mit warten verschwendet wird.<br /><br />
<br />
Daher erfolgt hier ein Ansatz über den USART (im SPI Modus) und DMA. Dies hat jedoch den Nachteil, dass pro zu sendendem Bit 1 Byte RAM benötigt wird. Eine LED erwartet 3 Byte, also 24 Bit, und benötigt somit 24 Byte RAM im Controller. Dafür werden die Daten mit Hilfe von DMA gesendet, so dass keine Rechenleistung in Warteschleifen verbraucht wird. Da der verwendete Controller 8kb RAM hat und nur 42 LEDs in der Matrix sind ist diese Lösung in dieser Situation gut brauchbar.<br /><br />
<br />
Die Initialisierung der Peripherie erfolgt im Konstruktor der Klasse. Es wird USARTC1 benutzt und der Output liegt an Port C Pin 7. Port C Pin 5 und 6 sind die Clock- bzw. Empfangsleitung und werden nicht benötigt, aber stehen nicht mehr für andere Anwendungen zur Verfügung. Die Anzahl der LEDs muss in der CWS2812.h durch das Symbol ''LED_NUM'' definiert werden. Mit '''input(uint8_t *led_data, uint16_t len)''' werden die RGB Daten in das WS2818 System übertragen. Pro LED werden 3 Byte, je eines für Rot, Grün und Blau, erwartet. '''transfer()''' startet den DMA Transfer und mit '''isBusy()''' kann geprüft werden, ob dieser abgeschlossen ist (!= 0).<br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest. (* In der momentanen Version im Wiki ist ein automatischer Wechsel und ähnliche Features noch nicht implementiert)<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden.<br />
<br />
== Weiterführende Ideen ==<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden, wie sie im Video zu sehen ist. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Die Anzahl der leichtenden LEDs pro Spalte richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br /><br />
<br />
== Bilder ==<br />
<gallery mode="packed-hover" widths=320px heights=240px><br />
Datei:audioboard_debug_ausgabe.png|Debug Ausgabe auf dem Display. Es zeigt: Name der Animation, Bilder pro Sekunde (FPS) und Samplevorgänge pro Sekunde (SPS), die BPM in den Höhen, Mitten, Tiefen und Alle zusammen, die 7 Bänder für linken und rechten Kanal und ganz unten rechts den Zoomfaktor für den Graphen.<br />
Datei:audioboard_animation1.png|Mono-Spektrum Anzeige. Die Daten vom linken und rechten Kanal werden zusammengefasst und angezeigt.<br />
Datei:audioboard_animation2.png|Stereo-Spektrum Anzeige. Die Daten vom linken und rechten Kanal werden getrennt links und rechts angezeigt und können sich in der Mitte überlagern.<br />
</gallery></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Datei:Audioboard_animation2.png&diff=1214Datei:Audioboard animation2.png2015-01-21T15:35:37Z<p>Marcel: </p>
<hr />
<div></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Datei:Audioboard_animation1.png&diff=1213Datei:Audioboard animation1.png2015-01-21T15:35:29Z<p>Marcel: </p>
<hr />
<div></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Datei:Audioboard_debug_ausgabe.png&diff=1212Datei:Audioboard debug ausgabe.png2015-01-21T15:34:59Z<p>Marcel: </p>
<hr />
<div></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1211Audio Board2015-01-19T20:33:11Z<p>Marcel: /* Animationen */</p>
<hr />
<div>{{#ev:youtube|id=http://youtu.be/opSofzCnbJo|480x320|right|Beispielanimation|frame}}<br />
<onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere Zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen atmega328 ausgetestet. Da dieser Controller nur mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum Einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareressourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschließen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br /><br />
<br />
Eine Echtzeitauswertung in dem Sinne, dass das System innerhalb weniger ms oder sogar µs auf ein Audiosignal reagiert ist mit dem Aufbau nicht möglich. Der Grundgedanke ist es die Audiodaten mit 10Hz zu erfassen und auszuwerten. Diese Daten werden gespeichert und durch ein Animationssystem, welches 60 Bilder pro Sekunde berechnet, optisch dargestellt. Dadurch, dass das menschliche Sehempfinden recht träge ist und sich sichtbar immer etwas verändert wirkt es am Ende so, als ob die Animation schnell auf die Musik reagiert, obwohl diese Reaktion nur alle 100ms erfolgt.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Übersteuern entgegen wirkt. Außerdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzen. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schließen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschließen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansprüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu Ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum Debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzen, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im Folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2, TCC0<br />
Der ADC wird im Freerun Modus konfiguriert und der Timer TCC0 auf eine Frequenz von 32kHz gestellt. Wird eine Messung mit '''adc_startSampling()''' gestartet werden die DMA Kanäle aktiviert und laden mit jedem overflow von TCC0 einen Messwert in den Speicher. Auf diese Weise werden 128 Messwerte je Kanal erfasst. Ist diese Datenerfassung abgeschlossen wird ''adc_state'' durch '''adc_check()''' auf ''ADC_STATE_SAMPLING_DONE'' gesetzt.<br /><br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
spectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbereich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösung der Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins Stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind wie folgt eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fließendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kalibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kalibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden die Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude werden abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Einlesen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Einlesen der Daten nicht hinausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== WS2812 Lib ==<br />
* CWS2812.cpp, CWS2812.h<br />
* Nutzt USARTC1 und DMA Ch0<br />
Die Vorteile der WS2812 LED liegt darin, dass diese einen eingebauten Treiber besitzen und die Daten über eine einzige Datenleitung übertragen werden. Dies macht einen Hardwareaufbau sehr einfach. Der Nachteil liegt darin, dass das Protokoll für die Daten ein sehr striktes timing erfordern. Andere Libraries machen dies über eine Verzögerung, wodurch Rechenleistung mit warten verschwendet wird.<br /><br />
<br />
Daher erfolgt hier ein Ansatz über den USART (im SPI Modus) und DMA. Dies hat jedoch den Nachteil, dass pro zu sendendem Bit 1 Byte RAM benötigt wird. Eine LED erwartet 3 Byte, also 24 Bit, und benötigt somit 24 Byte RAM im Controller. Dafür werden die Daten mit Hilfe von DMA gesendet, so dass keine Rechenleistung in Warteschleifen verbraucht wird. Da der verwendete Controller 8kb RAM hat und nur 42 LEDs in der Matrix sind ist diese Lösung in dieser Situation gut brauchbar.<br /><br />
<br />
Die Initialisierung der Peripherie erfolgt im Konstruktor der Klasse. Es wird USARTC1 benutzt und der Output liegt an Port C Pin 7. Port C Pin 5 und 6 sind die Clock- bzw. Empfangsleitung und werden nicht benötigt, aber stehen nicht mehr für andere Anwendungen zur Verfügung. Die Anzahl der LEDs muss in der CWS2812.h durch das Symbol ''LED_NUM'' definiert werden. Mit '''input(uint8_t *led_data, uint16_t len)''' werden die RGB Daten in das WS2818 System übertragen. Pro LED werden 3 Byte, je eines für Rot, Grün und Blau, erwartet. '''transfer()''' startet den DMA Transfer und mit '''isBusy()''' kann geprüft werden, ob dieser abgeschlossen ist (!= 0).<br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest. (* In der momentanen Version im Wiki ist ein automatischer Wechsel und ähnliche Features noch nicht implementiert)<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden.<br />
<br />
== Weiterführende Ideen ==<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden, wie sie im Video zu sehen ist. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Die Anzahl der leichtenden LEDs pro Spalte richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br /></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1210Audio Board2015-01-19T20:05:46Z<p>Marcel: </p>
<hr />
<div>{{#ev:youtube|id=http://youtu.be/opSofzCnbJo|480x320|right|Beispielanimation|frame}}<br />
<onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere Zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen atmega328 ausgetestet. Da dieser Controller nur mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum Einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareressourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschließen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br /><br />
<br />
Eine Echtzeitauswertung in dem Sinne, dass das System innerhalb weniger ms oder sogar µs auf ein Audiosignal reagiert ist mit dem Aufbau nicht möglich. Der Grundgedanke ist es die Audiodaten mit 10Hz zu erfassen und auszuwerten. Diese Daten werden gespeichert und durch ein Animationssystem, welches 60 Bilder pro Sekunde berechnet, optisch dargestellt. Dadurch, dass das menschliche Sehempfinden recht träge ist und sich sichtbar immer etwas verändert wirkt es am Ende so, als ob die Animation schnell auf die Musik reagiert, obwohl diese Reaktion nur alle 100ms erfolgt.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Übersteuern entgegen wirkt. Außerdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzen. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schließen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschließen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansprüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu Ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum Debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzen, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im Folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2, TCC0<br />
Der ADC wird im Freerun Modus konfiguriert und der Timer TCC0 auf eine Frequenz von 32kHz gestellt. Wird eine Messung mit '''adc_startSampling()''' gestartet werden die DMA Kanäle aktiviert und laden mit jedem overflow von TCC0 einen Messwert in den Speicher. Auf diese Weise werden 128 Messwerte je Kanal erfasst. Ist diese Datenerfassung abgeschlossen wird ''adc_state'' durch '''adc_check()''' auf ''ADC_STATE_SAMPLING_DONE'' gesetzt.<br /><br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
spectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbereich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösung der Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins Stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind wie folgt eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fließendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kalibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kalibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden die Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude werden abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Einlesen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Einlesen der Daten nicht hinausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== WS2812 Lib ==<br />
* CWS2812.cpp, CWS2812.h<br />
* Nutzt USARTC1 und DMA Ch0<br />
Die Vorteile der WS2812 LED liegt darin, dass diese einen eingebauten Treiber besitzen und die Daten über eine einzige Datenleitung übertragen werden. Dies macht einen Hardwareaufbau sehr einfach. Der Nachteil liegt darin, dass das Protokoll für die Daten ein sehr striktes timing erfordern. Andere Libraries machen dies über eine Verzögerung, wodurch Rechenleistung mit warten verschwendet wird.<br /><br />
<br />
Daher erfolgt hier ein Ansatz über den USART (im SPI Modus) und DMA. Dies hat jedoch den Nachteil, dass pro zu sendendem Bit 1 Byte RAM benötigt wird. Eine LED erwartet 3 Byte, also 24 Bit, und benötigt somit 24 Byte RAM im Controller. Dafür werden die Daten mit Hilfe von DMA gesendet, so dass keine Rechenleistung in Warteschleifen verbraucht wird. Da der verwendete Controller 8kb RAM hat und nur 42 LEDs in der Matrix sind ist diese Lösung in dieser Situation gut brauchbar.<br /><br />
<br />
Die Initialisierung der Peripherie erfolgt im Konstruktor der Klasse. Es wird USARTC1 benutzt und der Output liegt an Port C Pin 7. Port C Pin 5 und 6 sind die Clock- bzw. Empfangsleitung und werden nicht benötigt, aber stehen nicht mehr für andere Anwendungen zur Verfügung. Die Anzahl der LEDs muss in der CWS2812.h durch das Symbol ''LED_NUM'' definiert werden. Mit '''input(uint8_t *led_data, uint16_t len)''' werden die RGB Daten in das WS2818 System übertragen. Pro LED werden 3 Byte, je eines für Rot, Grün und Blau, erwartet. '''transfer()''' startet den DMA Transfer und mit '''isBusy()''' kann geprüft werden, ob dieser abgeschlossen ist (!= 0).<br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest.<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden.<br />
<br />
== Weiterführende Ideen ==<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden, wie sie im Video zu sehen ist. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Die Anzahl der leichtenden LEDs pro Spalte richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br /></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1209Audio Board2015-01-19T15:13:49Z<p>Marcel: </p>
<hr />
<div>{{#ev:youtube|id=http://youtu.be/opSofzCnbJo|480x320|right|Beispielanimation|frame}}<br />
<onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere Zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen atmega328 ausgetestet. Da dieser Controller nur mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum Einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareressourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschließen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br /><br />
<br />
Eine Echtzeitauswertung in dem Sinne, dass das System innerhalb weniger ms oder sogar µs auf ein Audiosignal reagiert ist mit dem Aufbau nicht möglich. Der Grundgedanke ist es die Audiodaten mit 10Hz zu erfassen und auszuwerten. Diese Daten werden gespeichert und durch ein Animationssystem, welches 60 Bilder pro Sekunde berechnet, optisch dargestellt. Dadurch, dass das menschliche Sehempfinden recht träge ist und sich sichtbar immer etwas verändert wirkt es am Ende so, als ob die Animation schnell auf die Musik reagiert, obwohl diese Reaktion nur alle 100ms erfolgt.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Übersteuern entgegen wirkt. Außerdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzen. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schließen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschließen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansprüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu Ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum Debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzen, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im Folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2, TCC0<br />
Der ADC wird im Freerun Modus konfiguriert und der Timer TCC0 auf eine Frequenz von 32kHz gestellt. Wird eine Messung mit '''adc_startSampling()''' gestartet werden die DMA Kanäle aktiviert und laden mit jedem overflow von TCC0 einen Messwert in den Speicher. Auf diese Weise werden 128 Messwerte je Kanal erfasst. Ist diese Datenerfassung abgeschlossen wird ''adc_state'' durch '''adc_check()''' auf ''ADC_STATE_SAMPLING_DONE'' gesetzt.<br /><br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
spectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbereich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösung der Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins Stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind wie folgt eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fließendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kalibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kalibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden die Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude werden abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Einlesen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Einlesen der Daten nicht hinausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest.<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden.<br />
<br />
== Weiterführende Ideen ==<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden, wie sie im Video zu sehen ist. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Die Anzahl der leichtenden LEDs pro Spalte richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br /></div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1208Audio Board2015-01-19T15:13:23Z<p>Marcel: </p>
<hr />
<div><onlyinclude><br />
{{#ev:youtube|id=http://youtu.be/opSofzCnbJo|480x320|right|Beispielanimation|frame}}<br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere Zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen atmega328 ausgetestet. Da dieser Controller nur mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum Einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareressourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschließen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br /><br />
<br />
Eine Echtzeitauswertung in dem Sinne, dass das System innerhalb weniger ms oder sogar µs auf ein Audiosignal reagiert ist mit dem Aufbau nicht möglich. Der Grundgedanke ist es die Audiodaten mit 10Hz zu erfassen und auszuwerten. Diese Daten werden gespeichert und durch ein Animationssystem, welches 60 Bilder pro Sekunde berechnet, optisch dargestellt. Dadurch, dass das menschliche Sehempfinden recht träge ist und sich sichtbar immer etwas verändert wirkt es am Ende so, als ob die Animation schnell auf die Musik reagiert, obwohl diese Reaktion nur alle 100ms erfolgt.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Übersteuern entgegen wirkt. Außerdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzen. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schließen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschließen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansprüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu Ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum Debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzen, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im Folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2, TCC0<br />
Der ADC wird im Freerun Modus konfiguriert und der Timer TCC0 auf eine Frequenz von 32kHz gestellt. Wird eine Messung mit '''adc_startSampling()''' gestartet werden die DMA Kanäle aktiviert und laden mit jedem overflow von TCC0 einen Messwert in den Speicher. Auf diese Weise werden 128 Messwerte je Kanal erfasst. Ist diese Datenerfassung abgeschlossen wird ''adc_state'' durch '''adc_check()''' auf ''ADC_STATE_SAMPLING_DONE'' gesetzt.<br /><br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
spectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbereich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösung der Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins Stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind wie folgt eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fließendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kalibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kalibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden die Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude werden abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Einlesen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Einlesen der Daten nicht hinausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest.<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden.<br />
<br />
== Weiterführende Ideen ==<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden, wie sie im Video zu sehen ist. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Die Anzahl der leichtenden LEDs pro Spalte richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br /><br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1207Audio Board2015-01-19T14:04:06Z<p>Marcel: </p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere Zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen atmega328 ausgetestet. Da dieser Controller nur mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum Einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareressourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschließen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br /><br />
<br />
Eine Echtzeitauswertung in dem Sinne, dass das System innerhalb weniger ms oder sogar µs auf ein Audiosignal reagiert ist mit dem Aufbau nicht möglich. Der Grundgedanke ist es die Audiodaten mit 10Hz zu erfassen und auszuwerten. Diese Daten werden gespeichert und durch ein Animationssystem, welches 60 Bilder pro Sekunde berechnet, optisch dargestellt. Dadurch, dass das menschliche Sehempfinden recht träge ist und sich sichtbar immer etwas verändert wirkt es am Ende so, als ob die Animation schnell auf die Musik reagiert, obwohl diese Reaktion nur alle 100ms erfolgt.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Übersteuern entgegen wirkt. Außerdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzen. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schließen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschließen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansprüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu Ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum Debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzen, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im Folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2, TCC0<br />
Der ADC wird im Freerun Modus konfiguriert und der Timer TCC0 auf eine Frequenz von 32kHz gestellt. Wird eine Messung mit '''adc_startSampling()''' gestartet werden die DMA Kanäle aktiviert und laden mit jedem overflow von TCC0 einen Messwert in den Speicher. Auf diese Weise werden 128 Messwerte je Kanal erfasst. Ist diese Datenerfassung abgeschlossen wird ''adc_state'' durch '''adc_check()''' auf ''ADC_STATE_SAMPLING_DONE'' gesetzt.<br /><br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
spectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbereich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösung der Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins Stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind wie folgt eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fließendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kalibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kalibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden die Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude werden abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Einlesen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Einlesen der Daten nicht hinausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest.<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden.<br />
<br />
== Weiterführende Ideen ==<br />
Video Link<br /><br />
<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Die Anzahl der leichtenden LEDs pro Spalte richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br /><br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1204Audio Board2015-01-18T19:06:14Z<p>Marcel: </p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere Zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen atmega328 ausgetestet. Da dieser Controller nur mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum Einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareressourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschließen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Übersteuern entgegen wirkt. Außerdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzen. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schließen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschließen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansprüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu Ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum Debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzen, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im Folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
verbessern<br /><br />
<br />
Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
spectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbereich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösung der Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins Stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind wie folgt eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fließendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kalibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kanlibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden die Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude werden abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Einlesen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Einlesen der Daten nicht hinausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest.<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden.<br />
<br />
== Weiterführende Ideen ==<br />
Video Link<br /><br />
<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Die Anzahl der leichtenden LEDs pro Spalte richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1203Audio Board2015-01-18T15:56:54Z<p>Marcel: /* Weiterführende Ideen */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
verbessern<br /><br />
<br />
Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
sprectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbreich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösungder Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind folgendermassen eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fliessendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kablibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kanlibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden diese Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude wird abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Samplen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Samplen der Daten nicht harausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest.<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden.<br />
<br />
== Weiterführende Ideen ==<br />
Video Link<br /><br />
<br />
Als Idee für eine Animation soll hier kurz eine existierende Vorgestellt werden. Die Matrix ist 7 LEDs breit und das Animationssystem fasst das Spektrum in 7 Bänder zusammen. Dadurch kann auf jeder Spalte eines dieser Bänder wiedergegeben werden. Jedes Band hat eine vorgegebene Grundfarbe, welche sich in Abhängigkeit von der Amplitude verändert. Wieviele LEDs pro Spalte leuchten richtet sich nach dem Wert im zugeordneten Band. Dadurch ergibt sich eine einfacher Frequenzanzeigen, welche über die Zeit leicht ihre Farbe verändert. Zusätzlich blitzen die Tiefen, Mitten bzw. Höhen kurz auf, wenn ein Beat in dem Bereich erkannt wurde.<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1202Audio Board2015-01-18T15:44:18Z<p>Marcel: </p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
verbessern<br /><br />
<br />
Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
sprectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbreich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösungder Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind folgendermassen eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fliessendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kablibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kanlibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden diese Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude wird abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Samplen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Samplen der Daten nicht harausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== Animationen ==<br />
Für das Matrix-Projekt soll es viele verschiedene Animationen geben, die manuell oder automatisch ausgewählt werden sollen. Daher wurde ein komplexes System mit einer Tabelle mit Funktionszeigern geplant. In der Tabelle ''anim_list_t anim_list[ANIM_LIST_NUM]'' (animation.cpp) werden die Animationen mit ihrer Funktion zum initialisieren, zur Berechnung eines Bildes und einem Namen eingetragen. Über die Funktion '''anim_start(uint16_t num)''' wird Animation Nummer ''num'' gestartet. Nun muss nur noch periodisch '''anim_frame()''' aufgerufen werden und das System kümmert sich um den Rest.<br /><br />
<br />
Zur Vereinfachung oder wenn nur 1 Animation vorhanden sein soll kann der komplette Inhalt der Funktion '''anim_frame()''' durch eigenen Code ersetzt werden. Dadurch muss jedoch auch die Kalibration und/oder die Standartwerte angepasst werden.<br />
<br />
== Weiterführende Ideen ==<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1201Audio Board2015-01-18T15:38:18Z<p>Marcel: /* Hauptschleife */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
verbessern<br /><br />
<br />
Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
sprectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbreich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösungder Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind folgendermassen eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fliessendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kablibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kanlibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden diese Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude wird abgeglichen.<br />
<br />
== Hauptschleife ==<br />
* MusikDing.cpp<br />
* Nutzt TCC1<br />
<br />
Timer TCC1 wird als Systemtimer genutzt und löst jede ms einen Interrupt aus. Die Anzahl der vergangenen ms können über die globale Variable ''volatile uint32_t systick'' abgefragt werden. Zusätzlich werden im Timer die Flags für Events gesetzt, wie z.B. ein neuen Frame berechnen und das Samplen der Daten zu starten.<br /><br />
<br />
In der Hauptschleife werden diese Flags abgefragt und entsprechend darauf reagiert. Es sind einige stellen mit TODO markiert. Hier ist der eigene Code einzutragen, sofern die Funktionen genutzt werden sollen. Wichtig ist, dass die Funktionen das System nicht zu lange blockieren, z.B. bei der Ausgabe auf Displays, damit die Animationen und das Samplen der Daten nicht harausgezögert werden.<br /><br />
<br />
Das System zum Daten einlesen und auswerten wird alle 100ms aktiviert. Sobald das Einlesen fertig ist wird ''adc_state == ADC_STATE_SAMPLING_DONE'' wahr und die FFT wird gestartet. Nun wird solange '''fft.doStep()''' aufgerufen bis alle Schritte abgearbeitet sind. Danach wird das ''FLAG_FFTDONE'' Flag gesetzt und das ADC-System geht in einen Idle Zustand, wodurch es bereit ist neue Daten einzulesen. Durch das Flag wird '''anim_inputData(fft.getLeft(), fft.getRight())''' aufgerufen und die Daten der FFT werden in das Animationssystem übertragen.<br /><br />
<br />
== Weiterführende Ideen ==<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1200Audio Board2015-01-18T15:11:01Z<p>Marcel: /* Auswertung */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
verbessern<br /><br />
<br />
Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
sprectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbreich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösungder Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind folgendermassen eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fliessendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br /><br />
<br />
Es gibt eine einfach Funktion zur Kablibration der Daten. Diese sind in der Struktur<br />
<pre><br />
typedef struct {<br />
uint8_t ident;<br />
uint16_t bands_calib_l[ANIM_BAND_NUM], bands_calib_r[ANIM_BAND_NUM];<br />
uint16_t amplitude_l, amplitude_r;<br />
} bands_calibration_t;<br />
</pre><br />
zusammengefasst. In der Funktion '''anim_init()''' werden diese Werte mit Standardwerten belegt bzw. werden aus dem EEPROM geladen. Mit '''anim_startCalibration()''' kann die Kanlibration gestartet werden, sofern das erweiterte Animationssystem benutzt wird. Diese Funktion muss aufgerufen werden, wenn das Audiokabel verbunden ist und kein Signal anliegt. Die Störungen, die nun auf der Leitung, sind werden gemessen, gemittelt und gespeichert. Danach werden diese Kalibrationswerte in '''anim_inputData()''' benutzt um diese Störungen herauszurechnen. Die Daten der FFT werden dabei nicht verändert. Lediglich die zusammengefassten 7 Bänder und die Amplitude wird abgeglichen.<br />
<br />
== Hauptschleife ==<br />
<br />
== Weiterführende Ideen ==<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1199Audio Board2015-01-18T15:00:51Z<p>Marcel: /* Auswertung */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
verbessern<br /><br />
<br />
Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type ''fft_result_t''.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
sprectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbreich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösungder Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert ''FFT_STATE_IDLE'' zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br />
<br />
* animation.cpp, animation.h<br />
Die durch die FFT erhaltenen Daten werden über die Funktion '''anim_inputData(fft_result_t *left, fft_result_t *right)''' in das Animationssystem eingelesen. Diese fasst die Daten der FFT in 7 Bänder zusammen und führt eine einfache Beat Erkennung durch. Die Bänder sind folgendermassen eingeteilt:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Band<br />
! Frequenzbreich<br />
! FFT Buckets<br />
|-<br />
| 0<br />
| 0 ... 250<br />
| 0<br />
|-<br />
| 1<br />
| 250 ... 500<br />
| 1<br />
|-<br />
| 2<br />
| 500 ... 1000<br />
| 2 ... 3<br />
|-<br />
| 3<br />
| 1000 ... 2000<br />
| 4 ... 7<br />
|-<br />
| 4<br />
| 2000 ... 4000<br />
| 8 ... 15<br />
|-<br />
| 5<br />
| 4000 ... 8000<br />
| 16 ... 31<br />
|-<br />
| 6<br />
| 8000 ... 16000<br />
| 32 ... 63<br />
|}<br />
Die Ergebnisse davon lassen sich in den globalen Variablen ''uint16_t bands_l[ANIM_BAND_NUM], bands_r[ANIM_BAND_NUM]'' für den linken und rechten Kanal finden.<br /><br />
<br />
Diese Funktion berechnet ebenfalls die Amplitude und stellt diese als globale Variablen ''uint16_t amplitude_l, amplitude_r'' zur verfügung.<br /><br />
<br />
Die Beaterkennung läuft ebenfalls über die Ergebnisse der FFT. Es wird für Tiefen (16Hz ... 750Hz), Mitten (750Hz ... 5kHz) und Höhen (5kHz ... 16kHz) durchgeführt. Für jedes dieser 3 Frequenzbänder wird ein fliessendes Mittel gebildet. Ist der momentane Wert um 50% höher als dieses Mittel wird es als Beat gewertet. Für die Tiefen und Höhen funktioniert dies recht gut, aber für die Mitten, gerade wenn Gesang vorhanden ist, funktioniert es nicht gut. Die BPM werden über die globalen Variablen ''uint8_t bpm_h, bpm_m, bpm_l, bpm_all'' (h - Höhe, m - Mitte, l - Tiefe, all - in irgendeinem Band) bereitgestellt. Zusätzlich kann über ''uint8_t beats'' abgefragt werden ob gerade ein Beat erkannt wurde, indem auf die Bits ''BEAT_HIGH'', ''BEAT_MID'' bzw. ''BEAT_LOW'' geprüft wird.<br />
<br />
== Hauptschleife ==<br />
<br />
== Weiterführende Ideen ==<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1198Audio Board2015-01-18T14:39:17Z<p>Marcel: /* Auswertung */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
verbessern<br /><br />
<br />
Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type fft_result_t.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
sprectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbreich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösungder Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br /><br />
<br />
Die Elemente adc_min und adc_max sind die Werte für den minimalen bzw. maximalen ADC Wert. Damit kann die Amplitude des Signals berechnet werden.<br /><br />
<br />
Die Berechnung ist mit Hilfe einer State-Maschine in kleine Schritte aufgeteilt. Mit der Funktion '''doFFT()''' wird dies gestartet. Danach muss solange '''doStep()''' aufgerufen werden bis diese Funktion den Wert FFT_STATE_IDLE zurückgibt. Der Sinn besteht darin die rechenintensiven Sachen, die die CPU blockieren, möglichst auseinander zu ziehen. Wird wie CPU zu lange blockiert können andere Events, wie z.B. das auswerten einer Eingabe oder die Berechnung der Ausgabe verzögert werden. Die Animation läuft dann teilweise flüssig und kommt teilweise ins stocken. Dies ist für den Betrachter sichtbar und sieht nicht schön aus. Ähnlich kann auch die Eingabe mal mehr und mal weniger empfindlich wirken.<br /><br />
<br />
* animation.cpp, animation.h<br />
<br />
== Hauptschleife ==<br />
<br />
== Weiterführende Ideen ==<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1197Audio Board2015-01-18T14:30:59Z<p>Marcel: /* Auswertung */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
verbessern<br /><br />
<br />
Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet]. Wenn die Daten mit 32kHz eingelesen werden ist des möglich Frequenzen bis 16kHz zu rekonstruieren. Mit Hilfe der FFT werden diese Frequenzen bestimmten Bändern zugeordnet. Mit den Funktionen '''getLeft()''' bzw. '''getRight()''' lassen sich die letzten Ergebnisse abrufen. Diese ist ein Zeiger auf einen Datensatz vom Type fft_result_t.<br /><br />
<pre><br />
typedef struct {<br />
uint16_t spectrum[FFT_N / 2];<br />
uint16_t adc_min, adc_max;<br />
} fft_result_t;<br />
</pre><br />
sprectrum ist in diesem Fall ein Array mit 64 Elementen (128 Abtastwerte / 2). Jeder dieser Werte umfasst die Intensität für einen bestimmten Frequenzbereich. spectrum[0] gibt einen Wert für Frequenzen im Bereich 0 ... 250Hz; spectrum[1] für den Bereich 250Hz ... 500Hz. Dies ergibt sich aus dem gesamten Frequenzbreich 16kHz und den 64 Elementen der FFT. 16kHz / 64 = 250. Somit lassen sich Frequenzen bis auf 250Hz bestimmen. Es ist möglich die Auflösungder Gesamtfrequenz zu verbessern, indem die Anzahl der Samples erhöht wird. Dadurch steigt natürlich die CPU- und Speicherauslastung.<br />
<br />
== Hauptschleife ==<br />
<br />
== Weiterführende Ideen ==<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1196Audio Board2015-01-18T14:16:21Z<p>Marcel: /* Datenerfassung */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
verbessern<br /><br />
<br />
Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet].<br />
<br />
== Hauptschleife ==<br />
<br />
== Weiterführende Ideen ==<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1195Audio Board2015-01-18T14:15:53Z<p>Marcel: /* Datenerfassung */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
verbessern<br />
<br /><br />
<br />
Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet].<br />
<br />
== Hauptschleife ==<br />
<br />
== Weiterführende Ideen ==<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1194Audio Board2015-01-18T13:23:07Z<p>Marcel: /* Software */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
* adc.cpp, adc.h<br />
* Nutzt ADCA Ch0, ADCB Ch0, DMA Ch1 und DMA Ch2<br />
Jeder Audiokanal hat seinen eigenen ADC und DMA Kanal. Dadurch läuft die Datenerfassung vollkommen in der Hardware ab. Es werden 128 Datenpunkte aufgenommen mit einer Rate von 62500Hz (32MHz CPU Takt / 512 Prescaler). Mit '''adc_startSampling()''' wird die Messung gestartet. '''adc_check()''' prüft ob die Messung fertig ist und setzt den globalen adc_state, welcher innerhalb der Hauptschleife abgefragt wird.<br />
<br />
== Auswertung ==<br />
* fffft.S, fffft.h, CFFT.cpp, CFFT.h<br />
Für die Berechnung der FFT wird die [http://elm-chan.org/works/akilcd/report_e.html FFT Lib von elmchan verwendet].<br />
<br />
== Hauptschleife ==<br />
<br />
== Weiterführende Ideen ==<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1193Audio Board2015-01-18T11:51:05Z<p>Marcel: /* Software */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
Die Software ist natürlich je nach der Anwendung sehr unterschiedlich. Daher wird ein Basis-Quelltext angeboten, welcher die Datenerfassung und -auswertung für das Matrix-Projekt beinhaltet. Weitere Anpassungen sollten problemlos möglich sein.<br /><br />
<br />
Download des Quelltext (als Atmel Studio Projekt)<br /><br />
<br />
Im folgenden werden die grundlegenden Gedanken und Funktionen besprochen. Diese sollten eine eigenständige Weiterentwicklung vereinfachen.<br />
<br />
== Datenerfassung ==<br />
<br />
== Auswertung ==<br />
<br />
== Weiterführende Ideen ==<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1192Audio Board2015-01-17T17:04:15Z<p>Marcel: /* Hardware */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein 5V Netzteil. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt, um den Controller damit zu versorgen. Es ist auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br /><br />
<br />
Das PC Netzteil versorgt die LEDs mit 5V und wird benötigt, da USB nicht genug Strom liefern kann. Die Versorgung der Logik erfolgt wahlweise über USB oder ebenfalls das Netzteil.<br /><br />
<br />
In der finalen Version soll die Logik in einem Holzkasten verschwinden und das PC Netzteil soll gegen ein kompakteres 5V Netzteil ausgetauscht werden. Dieser Kasten kann dann an die Wand gehängt werden und erzeugt dynamische Animationen mit Farbwechseln und -verläufen in Abhängigkeit zum eingegebenen Audiosignal. Eine mögliche Erweiterung wäre es ein Mikrofon einzusetzten, um das Audiokabel einzusparen. Dann würden jedoch alle Umgebungsgeräusche mit aufgenommen. Dies kann je nach Situation ein Vorteil oder Nachteil sein.<br />
<br />
= Software =<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1191Audio Board2015-01-17T16:45:41Z<p>Marcel: /* Technische Details und Anmerkungen */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein anderes externes 5V Signal. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt. Es ist jedoch auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemals mit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br />
<br />
= Software =<br />
<br />
= Bilder =</div>Marcelhttp://wiki.fablab-cottbus.de/index.php?title=Audio_Board&diff=1190Audio Board2015-01-17T16:39:49Z<p>Marcel: /* Hardware */</p>
<hr />
<div><onlyinclude><br />
Ein Projekt, welches Lichter oder sonstige Geräte in Abhängigkeit von einem Audiosignal ansteuern kann. Die ursprüngliche Idee war es eine Matrix aus RGB-LEDs so anzusteuern, dass eine Lichtshow abläuft, welche durch die Frequenz und Geschwindigkeit eines Liedes beeinflusst wird.<br />
</onlyinclude><br />
= Idee =<br />
Ich wollte eine Beleuchtung haben, welche je nach Takt bzw. Frequenz einer Melodie ihre Farbe ändert. Es gibt zwar einige Projekte, welche LEDs aufblinken lassen, wenn ein Beat innerhalb eines Frequenzbandes vorliegt (z.B. [http://www.dieelektronikerseite.de/Circuits/3%20Kanal%20LED-Lichtorgel.htm diese Lichtorgel]). Jedoch gibt es kein Projekt, welches komplexere zusammenhänge zwischen Licht und Musik erlaubt und vollkommen autark, ohne z.B. einen PC, arbeitet.<br />
<br />
= Konzept und Vorüberlegungen =<br />
Ein analoges Audiosignal von einem Klinkenstecker wird durch einen Mikrocontroller eingelesen. Die Daten werden ausgewertet und folgende Parameter berechnet: Amplitude, Beats und Intensität verschiedener Frequenzen. Diese Werte werden benutzt, um Farbveränderungen bzw. Animationen auf einer LED-Matrix zu steuern.<br /><br />
<br />
In einem ersten Test wurde eine Eingangs- und Filterstufe aufgebaut, welche ein Mono-Audiosignal aufbereitet. Ein atmega328 hat dieses Abgetastet und eine FFT des Signals durchgeführt. Damit wurde eine einzelne RGB-LED angesteuert. Diese hat ihre Farbe in Abhängigkeit der Frequenz geändert. Mit diesem System wurden die Grenzen des 16MHz schnellen atmega328 ausgetestet. Da dieser Controller nut mit 16MHz läuft waren diese Grenzen zwar schnell erreicht, jedoch waren die Ergebnisse schon sehr schön. Das Einlesen der Daten und die FFT wurde 10x pro Sekunde durchgeführt, so dass die resultierenden Daten für eine flüssige Animation gesorgt hat. Für ein Stereo-Signal wären jedoch nur noch 5 Updates der Daten pro Sekunde und Kanal möglich.<br /><br />
<br />
Für das fertige System sollte also ein anderer Controller zum einsatz kommen. Die Anforderungen waren: 2 ADC, DMA, auch für Hobby-Bastler leicht zu beschaffen, programmieren und löten. Daher wurde ein atxmega128-A3U gewählt. Dieser ist durch den Bootloader [http://matrixstorm.com/avr/tinyusbboard/ von diesem Projekt] einfach zu programmieren, auch ohne Programmiergerät. Vorprogrammierte Controller sind bei ebay durch den Händler [http://www.ebay.de/usr/matrixprog matrixprog] erhältlich. Durch die Kombination aus 2 unabhängigen ADC und DMA kann ein Stereo-Audiosignal problemlos umgewandelt werden. Es sind genügend Pins und Hardwareresourcen vorhanden, um weitere Geräte, wie z.B. Taster und LCD anzuschliessen. Auch die Audio-Eingangsstufe wurde leicht angepasst.<br />
<br />
= Hardware =<br />
[[Datei:audio_board_schematic.svg|400px|miniatur|Schematics der momentanen Version]]<br />
Das Audiosignal wird über einen Stereo-Klinkenstecker in das System eingegeben. Die Audio-Eingangsstufe beinhaltet eine [http://de.wikipedia.org/wiki/Automatische_Verst%C3%A4rkungsregelung AGC], welche die maximale Amplitude des Signales so begrenzt, dass es einem Überseuern entgegen wirkt. Ausserdem wird ein Bandpass-Filter eingesetzt, welcher alle Signale zwischen ca. 16Hz und 16kHz durchlässt. Der Aufbau der Eingangsstufe orientiert sich an [http://sound.westhost.com/project62b.htm diesem Projekt].<br /><br />
<br />
Als Controller wird ein atxmega128A3U eingesetzt. Die Hauptgründe dafür sind, dass er über 2 unabhängige ADC verfügt, damit linker und rechter Kanal gleichzeitig in ein digitales Signal umgewandelt werden kann, und dass DMA vorhanden ist, damit dieses Umwandeln komplett von der Hardware erledigt werden kann. Durch die Pinkompatibilität ist es möglich alle Controller der atxmega A3U Reihe einzusetzten. Je nach Anwendung ist jedoch mindestens der 128A3U anzuraten, da die kleineren Controller über weniger RAM verfügen. Alle nicht benutzten Leitungen sind herausgeführt und können frei verwendet werden.<br /><br />
<br />
Die Spannungsversorgung erfolgt entweder über USB oder ein anderes externes 5V Signal. Dieses wird über einen Spannungsregler auf 3,3V heruntergesetzt. Es ist jedoch auch möglich das Board direkt mit 3,3V zu versorgen.<br /><br />
<br />
Download KiCAD und Gerber Dateien<br />
<br />
== Technische Details und Anmerkungen ==<br />
* Der Controller arbeitet mit 3,3V, daher niemals mehr an den Signalleitungen anlegen<br />
* Den internen Spannungsregler niemalsmit mehr als 5V betreiben<br />
* Jumper JP1 offen lassen, wenn mit Stereo-Signalen gearbeitet wird. Schliessen, um aus einem Stereo-Signal ein Mono-Signal zu machen<br />
* Benutzte Pins:<br />
** Port A, Pin 7: Audio Input<br />
** Port B, Pin 0: Analoge Referenz Spannung<br />
** Port B, Pin 1: Audio Input<br />
** Port D, Pin 6 und 7: USB<br />
* Pin Header P17 "Stereo Pot" war vorgesehen, um ein Potentiometer anzuschliessen, damit die Empfindlichkeit der Eingangsstufe eingestellt werden kann. Es hat sich jedoch gezeigt, dass dieses nicht notwendig ist. An P17 können Pin 1 und 3 bzw. Pin 2 und 4 direkt mit einem 100 Ohm Widerstand verbunden werden. ('''Wichtig für Nachbau!''')<br />
* Taster SW1 ist nicht verbunden. Dieser kann, je nach verwendetem Bootloader oder anderen Ansrpüchen frei benutzt werden<br />
<br />
== Konkreter Testaufbau ==<br />
[[Datei:audioboard_testaufbau_konkret.png|400px|miniatur|Aktueller Testaufbau des Boards (grüne Platine) mit einem I/O Board (darüber) und einem Audioverstärker (darunter). Dazu eine 7x6 Matrix aus RGB LEDs]]<br />
Ein Anwendungsbeispiel ist die Ansteuerung einer Matrix aus RGB LEDs. Es werden LEDs mit einem WS2812 Controller verwendet, da diese schon einen Treiber eingebaut haben und der Hardware Aufbau (zu ungunsten des Softwareteils) vereinfacht wird. Auf die LEDs wurden billige Tischtennisbälle (Bastelladen, EBay) geklebt und dienen als Diffusionsfläche für das Licht.<br />
<br /><br />
<br />
Auf einem kleinen Stück Lochrasterplatine befindet sich ein ca. 1" kleines OLED Display, welches mit I2C angesteuert wird, und ein Drehgeber mit eingebautem Taster. Diese Platine wird derzeit zum debuggen benutzt und soll es später ermöglichen zwischen unterschiedlichen Betriebsmodi zu wählen.<br /><br />
<br />
Der Audioverstärker mit Lautsprecher dient lediglich als Debug-Ausgabe für das Audiosignal, damit zu hören ist was am Ende des AGC und Filters herauskommt.<br />
<br />
= Software =<br />
<br />
= Bilder =</div>Marcel