Download - Projektdokumentation Kai Aras Ss08

Transcript

Kai Aras - Matrikel Nr. 18464 – Medieninformatik – SS08

ProjektdokumentationAlgoRythm - Mikrocontroller basierter Audio Synthesizer

Betreuender Professor: Prof. Walter Kriha

Inhaltsverzeichnis1.Projektbeschreibung ............................................................................................................. 3

2.Motivation / Ziele .................................................................................................................. 4

3.Konzept ................................................................................................................................ 5

3.1.Synthesizer .................................................................................................................... 5

3.2.Klangerzeuger (DDS) .................................................................................................... 6

3.3.Sequenzer ..................................................................................................................... 7

4.Hardware .............................................................................................................................. 9

4.1.Digitaler Schaltungsteil .................................................................................................. 9

4.1.1.Verwendete Hardware ............................................................................................. 9

4.1.2.Blockdiagramm ..................................................................................................... 10

4.2.Analoger Schaltungsteil ............................................................................................... 10

5.Software ............................................................................................................................. 11

5.1.Klangerzeugung ........................................................................................................... 11

5.1.1.Abstrakt ................................................................................................................. 11

5.1.2.Direkt Digitale Synthese ........................................................................................ 11

5.1.3.Definitionen ........................................................................................................... 11

5.1.4.Globale Variablen .................................................................................................. 12

5.1.5.Interrupt Service Routine (ISR) ............................................................................. 13

5.1.6.Blockdiagramm ..................................................................................................... 13

5.2.Sequenzer .................................................................................................................. 14

5.2.1.Abstrakt ................................................................................................................. 14

5.2.2.Definitionen .......................................................................................................... 15

5.2.3.Globale Variablen .................................................................................................. 16

5.2.4.Intterupt Service Routine ....................................................................................... 17

5.2.5.Blockdiagramm ..................................................................................................... 18

6.Probleme ........................................................................................................................... 19

7.Fazit .................................................................................................................................. 19

8.Quellen ............................................................................................................................... 20

9.Anhänge ............................................................................................................................. 20

S e i t e | 2

1. Projektbeschreibung„Es soll ein hybrider Audio Synthesizer auf Basis eines einfachen "low-cost" Mikrocontrollers gebaut werden.

Zur Klangerzeugung soll das Verfahren der "Direkt digitalen Synthese" verwendet werden.

Als Hardware- Platform dienen zwei 8Bit- Atmel AVR Mikrocontroller, die mittels freiem C-Compiler "avr-gcc" komplett in "C" programmiert werden kann.

Das vom AVR digital erzeugte Signal soll anschließend durch ein analoges "multimode" Filter geformt werden können.

Als kleines Highlight sollen verschiedene algorithmische kompositions hilfen implementiert werden, die es dem Benutzer ermöglichen sollen auf "andere" art und Weise Musik zu kreieren als gewohnt.

Das Gerät soll vom funktionalen Umfang her mit kleineren kommerziellen Synthesizern mithalten können, allerdings soll vor allem auf die Grundsätze "low-cost" und "low-parts" großen wert gelegt werden.

Unter anderem sollte das Instrument folgendes bieten:

- zwei digitale Oszillatoren mit versch. Wellenformen ( Sinus, Square, Sawtooth + Userdefined )

- ein analoges multimode Filter

- ein kleiner interner Sequencer

- einfache midi Implementierung

- verschiedene algorithmische Kompositionshilfen

- evtl. verschiedene digitale Effekte

Während der Entwicklung bekam ich jedoch schnell Lust auf „mehr“, so beschloss ich den analogen Schaltungsteil um einen spannungsgesteuerten Verstärker, sowie zwei 4- stufige Hüllkurven zu erweitern. Der Digitalteil wurde um einen Niederfrequenzoszillator (LFO) erweitert, und das Sequenzermodul bekam eine 8x8 LED-Matrix zur Bedienung verpasst.Alles in allem bietet das Gerät jetzt folgendes:

- zwei digitale Oszillatoren mit versch. Wellenformen ( Sinus, Square, Sawtooth + Noise )

- ein digitaler LFO mit versch. Wellenformen ( Sinus, Square, Sawtooth + Noise )

- ein analoges multimode Filter

- ein analoger spannungsgesteuerter Verstärker (VCA)

- zwei analoge 4-stufige Hüllkurven (ADSR)

S e i t e | 3

- 8x8 LED-Matrix-Sequenzer mit diversen algorithmischen Kompositionshilfen und modi

2. Motivation / ZieleMotiviert einen Synthesizer zu bauen haben mich verschiedene Dinge, zum einen bin ich selbst begeisterter elektronischer Musiker, zum anderen liebe ich aber auch die Softwareentwicklung. Da dies ganz gut Hand- in Hand mit einander geht war schnell klar, dass ein Audioprojekt her muss. Zunächst wollte ich dies komplett in Software realisieren bis ich zufällig über einen Podcast auf das Thema Mikrocontroller gestoßen bin, was mich wiederum dazu bewegt hat mich intensiver mit dieser Materie auseinander zu setzen.

Obwohl ich zu diesem Punkt kaum Verständnis für Elektrontechnik mitbrachte, fand ich schnell Spaß am löten, basteln und experimentieren. Natürlich wollte ich auch hier meine Begeisterung für Audiotechnik einbringen und so versuchte ich auf unterschiedlichen Wegen Klänge mit Hilfe eines Mikrocontrollers zu erzeugen. Überraschender weise ließen erste Ergebnisse nicht lange auf sich warten und die Idee vom „billig- selbstbau- Synthi“ war geboren.

Damals motivierte mich vor allem die Herausforderung ein Instrument vom ersten IC bis hin zur Frontplattengestaltung selbst nach eigenen Vorstellen zu Entwickeln, bzw. die Kunst zu erlernen die einen erst befähigt dies zu tun.

Auf den Punkt gebracht waren meine Ziele also:

- Verstehen und Realisieren der Direkt digitalen Synthese

- Wissen rund um Elektronik erweitern

- Wissen im Bereich hardwarenahe Softwareentwicklung sammeln

- Eigene Ideen umsetzen, bzw. Erfahrung sammeln um dies tun zu können

- Erschaffen eines ernsthaften Instruments

S e i t e | 4

3. Konzept

3.1.SynthesizerFolgende Grafik soll den Aufbau des Synthesizers und das Zusammenspiel von Digital- und Analogtechnik verdeutlichen.

Wie man der oben Grafik entnehmen kann, besteht der digitale Teil des Gesammtsystems aus:

1. Der Klangerzeugung, realisiert in Form von 3 Oszillatoren die unabhängig von einander Sinus, Rechteck, Sägezahn und Rauschen erzeugen können.

2. Dem Sequenzer, der Komposition von Sequenzen erlaubt, und über eine 8x8 LED-Matrix bedien bar ist.

Der analoge Teil des Systems leistet folgendes zur Formung des Signals:

1. Ein aktives analoges multimode Filter

2. Ein analoger „Verstärker“, um Lautstärkeverläufe oder Tastenanschläge zu simulieren

S e i t e | 5

Hüllkurven Generator

Hüllkurven Generator

Sequenzer

AnalogDigital

3. Zwei Hüllkurven Generatoren, welche Steuerspannungen erzeugen, die wiederum Filter und VCA beeinflussen, bzw. steuern können

3.2.Klangerzeuger (DDS)Zur Klangerzeugung wurde hier das Verfahren der Direkt Digitalen Synthese implementiert. Im Folgenden möchte ich dieses Verfahren kurz erläutern.

Ein Direkt Digitaler Synthesizer besteht mindestens aus den folgenden Bausteinen:

- Einem festen Systemtakt, der Abtastfrequenz oder eng. Samplerate

- Einer Tabelle welche eine Periode der zu erzeugenden Wellenform(en) enthält, einem so genannten Look up Table (LuT)

- Einem Phasenakkumulator zur Adressierung des LuT

- Einem Digital-Analogwandler oder eng. DAC

- Einem Tiefpassfilter zur Glättung des Ausgangssignals

Siehe nachfolgende Grafik.

1. TuningwordDas Tuningword ist ein Binärwort, welches dem Phasenakkumulator zugeführt wird um ein Ausganssignal in einer bestimmten Frequenz zu erzeugen.

2. PhasenakkumulatorHier wird bei jedem Systemtakt der neue Phasenwert des zu erzeugenden Abtastwertes bestimmt. Wird der Phasenakkumulator getaktet läuft die Funktion:

ab.

S e i t e | 6

AnalogesAusgangsignalTuningword

Abtastfrequenz

Digitale Phasenwerte Abtastwerte aus LuT Quantisiertes Signal Digital erzeugte Wellenform

3. Phase TruncationDas Ergebnis des Phasenakkumulators, die „neue Phase“ repräsentiert die Adresse des neuen Abtastwertes innerhalb des Look up Tables. Da der Phasenakkumulator in der Regel „breiter“ ist als der Adressbereich des Look up Tables, ( hier z.b. 24bit, während der LuT nur einen Adressbereich von 8bit bietet) wird in der Phase Truncation die Bitbreite aus dem Phasenakkumulator auf den vom LuT gegebenen Adressraum angepasst. Man tut dies, indem man die niederwertigen Bit (LSB) abschneidet und nur die höherwertigen Bit (MSB) zur Adressierung verwendet.

4. Look up Tableim LuT liegt jeweils eine Periode der zu erzeugenden Wellenformen vor.

5. Digital-Analogwandler (DAC)im DAC wird der momentane Amplitudenwert des aktuellen Abtastwerts erzeugt.

6. Tiefpassfilterdas Tiefpassfilter befreit das erzeugte Analogsignal von unerwünschten Frequenzkomponenten, erst er stellt die gewünschte Wellenform wieder her. Hier gilt das Theorem von Nyquist, was im Wesentlichen besagt, dass die Grenzfrequenz des Filters kleiner oder gleich der halben Taktfrequenz des Systems gewählt werden sollte.

3.3.SequenzerDer hier verwendete Sequenzer zeichnet sich vor allem durch seine ungewöhnliche Bedienung aus. Während herkömmliche Sequenzer meist verlangen jede zu spielende Note und deren Tonhöhe einzeln zu bestimmen (siehe nachfolgender Grafik), stellt mein Matrix- Sequenzer bereits einen Pool von miteinander harmonierenden Notenwerten zur Verfügung, der die Grundlage einer jeden Sequenz darstellt, und so eine vollkommen andere Art des Komponierens ermöglicht.Dieser Pool besteht in den meisten Fällen aus den Notenwerten einer bestimmten Skala, wie z.B. der wohl bekannten A-Moll Skala, es kann hier neben den Dur- und Mollskalen aus jeder beliebigen Kirchentonart beginnend mit jedem beliebigen Grundton gewählt werden.Zusätzlich stehen in Abhängigkeit der jeweiligen Tonart eine Vielzahl von Akkorden und Kadenzen zur Verfügung, um die der Notenpool erweitertet oder dezimiert werden kann.

Die Komposition von Sequenzen erfolgt durch das Setzen sogenannter Events, die entweder einen Tastenaschlag auslösen, oder einen Wechsel der Tonart, des Grundtons oder des Akkords… bewirken können. Man tut dies, indem man durch betätigen der Taster für die jeweilige Zeile und Reihe, das einzelne Element der Matrix auswählt, von dem ein Event ausgelöst werden soll. Visualisiert wird ein aktiver Event durch das „einschalten“ des LEDs, welches das jeweilige Element repräsentiert.

Der Notenpool und aktive Events stehen, anders als beim herkömmlichen Sequenzer, in keinem fest definierten Verhältnis zueinander, sondern können sich wie folgt verhalten:

- Der Pool kann auf unterschiedliche Weise mit den Zeilen und Spalten der Matrix verknüpft werden.

- Die Matrix kann auf unterschiedliche Weise durchlaufen werden.

S e i t e | 7

Herkömmlicher Sequenzer Tonhöhe

(AN), wenn Note gesetzt

Note setzen

1 2 3 4 5 6 7 8

8 x Einzelnoten = 1 Takt

- Events können von diversen Algorithmen automatisch generiert oder alteriert werden.

Nachfolgende Grafik soll den Unterschied zwischen diesen Beiden Modellen deutlich machen.

S e i t e | 8

Matrix Sequenzer

Legende

Poti

LED

Taster

(AN), wenn Note gesetzt

Note setzen

Takte oder Einzelnoten

Takte oder Einzelnoten

Tonhöhe der einzelnen Noten liegen im Pool bereit und werden auf die Matrix abgebildet.

Legende

LED

Taster

4. Hardware

4.1.Digitaler Schaltungstei l

4.1.1.Verwendete HardwareAls Hardwareplatform zur Realisierung des Projekts, wurden zwei 8Bit Mikrocontroller der Firma Atmel verwendet:

1. AVR#1 - Atmel AVR 8Bit RISC Atmega 8

- 8kb Flashspeicher

- 1kb SRAM

- 16Mhz

- 3x Timer

- 3x PWM

- 6x ADC

Dient als Klangerzeuger und implementiert die Direkt digitale Synthese

2. AVR#2 - Atmel AVR 8Bit RISC Atmega 32

- 32kb Flashspeicher

- 2kb SRAM

- 16Mhz

- 3x Timer

- 4x PWM

- 8x ADC

Dient als Sequenzer und steuert den Klangerzeuger

ISP: Als Programmieradapter kam eine einfache Selbstbaulösung zum Zug, (Link siehe Quellenverzeichnis) welche es durch lediglich 4 Widerständen erlaubt sämtliche 8Bit AVRs über den LPT Port zu programmieren.

IDE: Als Programmierumgebung wurde das von Atmel stammende AVR-Studio zusammen mit dem freien C-Compiler avr-gcc verwendet.

S e i t e | 9

4.1.2.Blockdiagramm

4.2.Analoger Schaltungstei lAuf die theoretische Funktionsweise der analogen Schaltungsteile: Filter, Verstärker und Hüllkurven wird hier nicht weiter eingegangen, da dies den Rahmen dieser Arbeit sprengen würde. Alle analogen Schaltungen die hier verwendet wurden stammen aus selbstbau- Modularsystemen und wurden lediglich nachgebaut. Quellen hierfür sind im Anhang verlinkt.

Trotzdem mir keine Zeit blieb mich ausgiebig mit dieser Thematik zu befassen, war es mir doch sehr wichtig zumindest mal so etwas gebaut zu haben, wodurch ich letztendlich auch unglaublich viel über analoge Schaltungstechnik und Elektronik allgemein gelernt habe.

S e i t e | 10

AtMega8 AtMega32

DDS

ADC

DAC

LuTSinus Rechteck …

UI

DAC

UI

LuT

Sequenzer

CV to Pitch conversion

LED-Matrix

TasterLEDsTasterAnaloger- Schaltungs

teil

Tiefpass- Filter

Klangerzeuger Sequenzer

5. Software

5.1.Klangerzeugung

5.1.1.AbstraktDer Softwareteil der Klangerzeugung besteht im Wesentlichen aus 3 Teilen:

1. Programm- und I/O Initialisierungen

2. Endlosschleife innerhalb der Main Methode

a. Benutzer- I/O überprüfen, und aktualisieren

3. Interrupt Service Routine (ISR)

a. Tonhöhe vom ADC lesen und aktualisieren

b. DDS ausführen

c. Neuen Abtastwert auf DAC schreiben

5.1.2.Direkt Digitale SyntheseDie DDS ist wie folgt implementiert:

- Abtastrate = Interruptperiode generiert durch Timer0 Overflow Interrupt

- Phasenakkumulator = 24bit Integer Variable OSCx_PhaseAccu

- Phase Truncation = 16bit rechts shift des Phasenakkumulators

- Look Up Table = 8bit integer Array, abgelegt im Programmspeicher

- DAC = Pulsweitenmodulation durch Timer1 / Timer2

- Tuningword = 32bit integer Array mit Tuningwords für den Gesamten Notenumfang (C0-C9)

5.1.3.Definit ionen

#define F_CPU 16000000ULDefiniert den Prozessortakt mit 16Mhz

#define PINOUT_OSC2 PB1Ausgabepin des zweiten Oszillators

#define PINOUT_OSC1 PB2Ausgabepin des ersten Oszillators

#define PINOUT_LFO PB3Ausgabepin des Niederfrequenzoszillators

#define OSC1_WAVELED_DATA PD5Datenpin des Schieberegisters zur Visualisierung der ausgewählten Wellenform am Bedienfeld des ersten Oszillators

#define OSC2_WAVELED_DATA PB4

S e i t e | 11

Datenpin des Schieberegisters zur Visualisierung der ausgewählten Wellenform am Bedienfeld des zweiten Oszillators

#define LFO_WAVELED_DATA PD6Datenpin des Schieberegisters zur Visualisierung der ausgewählten Wellenform am Bedienfeld des Niederfrequenzoszillators

#define ALL_WAVELED_MR PB0Master-Resetpin des Schieberegisters zur Visualisierung der ausgewählten Wellenform an allen Bedienfeldern

#define ALL_WAVELED_CLK PD7Clockpin des Schieberegisters zur Visualisierung der ausgewählten Wellenform an allen Bedienfeldern

#define OSC1_WAVE_SELECT_BTN PD1Eingabepin des Tasters zur Auswahl der Wellenform des ersten Oszillators

#define OSC1_OCTAVE_SELECT_BTN Eingabepin des Tasters zur Auswahl der Oktave des ersten Oszillators

#define OSC2_WAVE_SELECT_BTN PD2Eingabepin des Tasters zur Auswahl der Wellenform des zweiten Oszillators

#define OSC2_OCTAVE_SELECT_BTN PD3Eingabepin des Tasters zur Auswahl der Oktave des zweiten Oszillators

#define LFO_WAVE_SELECT_BTN PD4Eingabepin des Tasters zur Auswahl der Wellenform des Niederfrequenzoszillators

#define LFO_FREQ_POT PC5Analogeingang – Frequenz- Potentiometer des Niederfrequenzoszillators

#define OSC1_DETUNE_POT PC4Analogeingang – Detune- Potentiometer des ersten Oszillators

#define OSC2_DETUNE_POT PC3Analogeingang – Detune- Potentiometer des zweiten Oszillators

#define CV_PITCH_IN PC2Analogeingang – Tonhöhe des ersten Oszillators

#define CV_PITCH_IN2 PC1Analogeingang – Tonhöhe des zweiten Oszillators

5.1.4.Globale Variablenvolatile uint16_t isr_counter=0;

Countervariable, wird mit jeder Interruptperiode imkrementiertvolatile uint16_t ms_counter=0;

Countervariable, wird jede Millisekunde inkermentiertvolatile uint8_t OSC_gate =0;

Statusvariable, volatile uint8_t OSC1_currentNote=0;

Aktueller Notenwert des ersten Oszillatorsvolatile uint8_t OSC2_currentNote=0;

Aktueller Notenwert des ersten Oszillatorsvolatile uint16_t LFO_currentFreq=0;

Aktuelle Ausgabefrequenz des Niederfrequenzoszillatorsvolatile uint8_t OSC1_octave=0;

Statusvariable, dient als index von OCTAVE_SELECT[]volatile uint8_t OSC2_octave=0;

Statusvariable, dient als index von OCTAVE_SELECT[]volatile uint16_t OSC1_detune=0;

Aktueller Verstimmungswert des ersten Oszillatorsvolatile uint16_t OSC2_detune=0;

Aktueller Verstimmungswert des zweiten Oszillatorsvolatile uint8_t OSC1_Wave=0;

S e i t e | 12

Statusvariable, dient als index von WAVEFORMS[]volatile uint8_t OSC2_Wave=0;

Statusvariable, dient als index von WAVEFORMS[]volatile uint8_t LFO_Wave=0;

Statusvariable, dient als index von WAVEFORMS[]uint32_t OSC_calibration_offset=0;

Offset zur Korrektur der Ausgangsfrequenzconst uint8_t WAVE_SELECT[4] = {1,2,4,8 };

Array mit Konstanten für die Wellenformauswahlconst uint8_t OCTAVE_SELECT[3] = { 64, 32, 16 };

Array mit Konstanten für Oktaven- Umschaltungconst uint8_t *WAVEFORMS[4] = {sinewave,sawtoothwave,squarewave, userwave};

Array mit Zeigern auf die hinterlegten Look Up Tables

5.1.5.Interrupt Service Routine (ISR)Die Interruptperiode der ISR stellt die Abtastrate des Systems dar. Diese wurde hier auf 32khz festgelegt, was nach Nyquist erlaubt ein Signal mit bis zu 16khz erzeugen zu können.Ausgelöst wird die ISR durch einen Overflow Interrupt in Timer0. Timer0 ist ein 8Bit Counter und wird alle 8- Systemtakte inkrementiert, erreicht der Counter einen bestimmten Compare-Match Wert (hier 192) , wird er zurückgesetzt und ein Overflow Interrupt ausgelöst.

Zur Berechnung der Timereinstellungen ist im Anhang ein Excel Sheet verlinkt.

5.1.6.Blockdiagramm

S e i t e | 13

Programminitialisierungint main (void) {

Includes

Init()

While(1) {

}

init() {

}

- Initialize I/O Ports

- Initialize Timer0 (samplefreq.)

- Initialize Timer1 (DAC 1+2)

- Initialize Timer2 (DAC 3)

- Enable global Interrupts

- Check Input pins

- Switch Modes checkButtons()setLEDS(…)

checkPots() {

}- Read ADCs and updateglobal variables

setLEDS(…) {

}- Write display-values to shiftregisters

checkPots()

.

5.2.Sequenzer

5.2.1.AbstraktDer Softwareteil des Sequenzers besteht im Wesentlichen aus folgenden Bestandteilen:

1. Programm und I/O Initialisierungen

S e i t e | 14

Defines

Globale Variable

n

ISR(TIMER0_OVF_vect) {

}

- Increment isr_counter

- Synchronize ms_counter

- Read Pitch from ADC

- run the DDS and output new value to DAC

checkButtons() {

}

2. Endlosschleife innerhalb der Main() Funktion

a. Durchlaufen der Matrix

b. Analoge Hüllkurven triggern falls aktuelles Element aktiv ist

c. Taster zur Matrixsteuerung überprüfen und Änderungen Ausführen

3. ISR 1 (Timer0 Overflow Interrupt)

a. Steuerspannung für Synthmodul erzeugen

4. ISR 2 (Timer2 Overflow Interrupt)

a. Timing ableiten

b. Taster überprüfen und Änderungen ausführen

c. LED-Matrix anzeigen

5.2.2.Definit ionen #define LED_MATRIX_DATA1 PD2

Datenleitung des ersten Schieberegisters zur Steuerung der LED Matrix#define LED_MATRIX_DATA2 PD3

Datenleitung des zweiten Schieberegisters zur Steuerung der LED Matrix#define LED_MATRIX_MR PD7

Master- Resetpin der Schieberegister#define LED_MATRIX_CLK PD6

Clockleitung der Schieberegister#define BUTTON_ROW PA0

Analogeingang – 8 Taster zur Reihenwahl der Matrix#define BUTTON_COL PA1

Analogeingang – 8 Taster zu Zeilenwahl der Matrix#define CV_PITCH_OUT1 PD4

PWM Ausgang #1#define CV_PITCH_OUT2 PD5

PWM Ausgang #2#define CV_GATE_OUT1 PC0

Gate Ausgang zum triggern der analogen Hüllkurven#define CV_GATE_OUT2 PC1

Gate Ausgang zum triggern der analogen Hüllkurven#define LED_COL1_DATA PC6

Datenleitung Schieberegister #3#define LED_COL2_DATA PC7

Datenleitung Schieberegister #4#define BUTTON_LEFT0 PB4

Eingang Taster #1#define BUTTON_RIGHT0 PD0

Eingang Taster #2#define BUTTON_RIGHT1 PB3

Eingang Taster #3#define BUTTON_RIGHT2 PD1

Eingang Taster #4

S e i t e | 15

5.2.3.Globale Variablenuint8_t const MOD_REF_MATRIX[8] = …

Referenzwerte für Sequenzmodulationuint16_t const RES_REF[8] = …

Referenzwerte für Modulation der Sequenzauflösungvolatile uint8_t LED_MatrixA[8][8] = {};

8x8 Array – repräsentiert die 8x8 LED Matrixvolatile uint8_t LED_MatrixB[8][8] = {};

8x8 Array – Puffervolatile uint8_t LED_runMatrix[8][8] = { };

uint8_t LED_ROW_left =0;Anzeigewert LED Reihe auf Benutzeroberfläche

uint8_t LED_ROW_right1 =0;Anzeigewert LED Reihe auf Benutzeroberfläche

uint8_t LED_ROW_right2 =0;Anzeigewert LED Reihe auf Benutzeroberfläche

volatile uint16_t ms_counter=0;Zählervariable, von ihr wird das globale Timing abgeleitet

volatile uint16_t step_counter=0;Zählervariable der Steps

volatile uint16_t bar_counter=0;Zählervariable der Takte

uint8_t mod_counter=16;Zählervariable – gibt an wann moduliert warden soll

uint8_t seq_direction=0;Laufrichtung des Sequenzers, vertical/horizontal

volatile uint8_t CV1_currentPitch=0;Tonhöhe des ersten Oszillators

volatile uint8_t CV2_currentPitch=0;Tonhöhe des zweiten Oszillators

volatile uint8_t currentNote=0;Tonhöhe des Sequenzers

volatile uint8_t currentScale[28]={0,0,0,0,0,0,0,0};Hält die aktive Skala

volatile uint8_t currentChord[3]= {0,2,4};Hält den aktiven Akkord

volatile uint8_t currentChordBaseNote=0;Hält den aktiven Grundton

volatile uint8_t currentMode=0;Hält den aktiven Sequenzermodus

uint8_t RES_counter=125;Aktuelle Auflösung des Sequenzers

volatile uint8_t currentPitchSrc=0;Aktive Quelle für Tonhöheninformation

volatile uint8_t *currentLEDMatrix= &LED_MatrixA[0][0];Zeiger auf aktive Matrix

volatile uint8_t currentCadence[4] = { 0, 3,4,7 };Hält die aktive Kadenz

volatile uint8_t majorScale[28] = …Hält die C-Dur Skala als Grundlage für die Generierung weitererer

volatile uint8_t currentSequence[64 = …] Hält die aktuelle Sequenz

S e i t e | 16

5.2.4.Intterupt Service RoutineDer Sequenzer arbeitet mit zwei Interrupt Service Routinen:

1. ISR1 Timer0 Overflow Interruptdieser Interrupt taktet, genau wie beim Synthesizer- Modul den DAC, der in diesem Fall jedoch kein Audio-, sondern ein Steuerspannungssignal (CV) erzeugt.Dieses Signal enthält die Tonhöheninformationen des Sequenzers und wird dem Synthesizer zugeführt, der es wiederum digitalisiert und die entsprechende Tonhöhe ausliest.

2. ISR 2 Timer2 Overflow Interruptdie Interruptperiode von Timer2 beträgt 1ms, von ihr wird das Timing des Sequenzers abgeleitet.

S e i t e | 17

5.2.5.Blockdiagramm

S e i t e | 18

Programminitialisierung

int main (void) {

Includes

Defines

Globale Variable

n

Init()

While(1) {

}

init() {

}

ISR(TIMER0_OVF_vect) { }- Clk DAC and output new CV

value

- Initialize I/O Ports

- Initialize Timer0 (samplefreq.)

- Initialize Timer1 (DAC 1+2)

- Initialize Timer2 (Mux freq.)

- Enable global Interrupts

checkButtonMatrix() {

}

- Read ADCs to find out which Buttons have been pressed

- Update current Matrix

checkButtonMatrix()

checkStep()

doSeqMode() {

}

- Switch to current mode

- Do the actual sequencing

checkStep() {

}

- Check if current step is set

- If it is, trigger Envelope to generate a NoteOn

doSeqMode()

ISR(TIMER2_OVF_vect) {

}

- Ms_counter++

- Sychronize to 100ms

displayLedMatrix()

checkButtons()

checkButtons() {

}

- Check for User input

- Update states

displayLedMatrix() {

}

- Calculate control words for shiftregisters

- Transfer data in serial

6. Probleme Im allgemeinen gab es glücklicherweise kaum bzw. keine größeren Probleme, der Softwareteil des Projekts verlief größtenteils reibungslos und auch sonst konnte ich fast alle meine Ziele verwirklichen, einzig allein die Implementierung digitaler Effekte musste ich streichen, da die Hardwareressourcen der verwendeten Mikrocontroller, insbesondere deren RAM dafür nicht ausreichend dimensioniert waren.

7. Fazit Für mich war dieses Projekt ein voller Erfolg, der Lerneffekt war riesig, noch viel größer als ich gedacht hätte. Zu Beginn des Projekts konnte noch kaum Widerstand und Kondensator unterscheiden, geschweige denn Schaltpläne lesen oder gar zeichnen, heute kenne ich Pinbelegungen auswendig und spreche fast fließend binär Das Entwickeln von Software auf unterstem Level und die damit verbundenen Möglichkeiten haben mich sehr begeistertet und auch bis jetzt nicht losgelassen. Auch wenn dieses Projekt offiziell hiermit abgeschlossen ist, bleibt noch einiges zu tun, und ich freue mich jetzt schon daran weiterzuarbeiten und vor allem damit zu „spielen“.

Alles in allem hat dieses Projekt unglaublich viel zu meinem Gesammtverständnis für Hardwarevorgänge, sowie digitale Audiotechnik, aber auch Elektronik beigetragen und ich kann nur froh sein meine Zeit in dieses Projekt investiert zu haben.

S e i t e | 19

8. Quellen1. Infos rund um AVR und Mikrocontroller

a. http://www.mikrocontroller.net

b. http://www.scienceprog.com

2. Datenblätter und Applicationotes zu den verwendeten Mikrocontrollern

a. www.atmel.com

3. Direkt Digitale Synthese

a. http://en.wikipedia.org/wiki/Direct_digital_synthesis

b. http://www.scienceprog.com/category/avr-controlled-signal-generator/

c. http://www.mikrocontroller.net/articles/Digitaler_Funktionsgenerator

4. AVR Programmieradapter (ISP)

a. http://mikrocontroller.com/de/isp.php

5. AVR Programmierumgebung (IDE)

a. http://www.atmel.com/dyn/Products/tools_card.asp?tool_id=2725

6. AVR C-Compiler (avr-gcc)

a. http://winavr.sourceforge.net/

7. DIY Modular Synth (Analogtechnik)

a. René Schmitz http://www.uni-bonn.de/~uzs159/

b. Yves Usson http://yusynth.net/Modular/index.html

c. Forum http://www.sequencer.de/synthesizer/

8. Schaltpläne (analoger Schaltungsteil)

a. Filter (VCF) http://yusynth.net/archives/ElectronicDesign/N-Steiner-VCF-1974.pdf

b. Verstärker (VCA)http://yusynth.net/Modular/index.html

c. Hüllkurven (ADSR) http://www.uni-bonn.de/~uzs159/

9. Anhänge1. Quellcode inkl. Avr-Studio Projekt des Synthesizer Moduls

2. Quellcode inkl. Avr-Studio Projekt des Sequencer Moduls

S e i t e | 20

3. Excel Sheet für sämtliche Berechnungen (Tuningwords, Timer, R/C Filter…)

4. Power Point Präsentation vom Präsentationstag

S e i t e | 21