IFD:Fire Water Air and Earth. And Electricity!/Martin Johr

From Medien Wiki

Elektronische Spieluhr

unter Verwendung eines Arduino

Martin Johr

Bauhaus-Universität Weimar Fakultät Medien

martin.johr@uni-weimar.de


Auszug

Diese Publikation befasst sich mit dem Konzept und Auf-bau einer Apparatur, welche es ermöglicht Informationen von einem selbsterstellten Medium elektronisch zu erfas-sen und in ein hörbares Signal umzuwandeln.

Schlagwörter

Spieluhr, Arduino, Elektronik, Schrittmotor, Gabellicht-schranke, Optokoppler, R_2R Leiter


EINLEITUNG

Beim Betrachten einer kleinen Walzenspieldose kam mir vor einiger Zeit die Idee ein Gerät zu entwickeln, mit dem man seine eigenen Lieder oder Lieblingslieder mit gerin-gem Aufwand auf einer selbstgebauten elektronisch be-triebenen Spieluhr genießen kann.


GRUNDLAGEN

Um den Aufbau der Apparatur und die Vorgänge darin verstehen zu können ist ein grundliegendes Verständnis der Elektrotechnik nötig.


Verwendete Elemente

Folgende zu verbauende Gegenstände werden benötigt, um die Spieluhr realisieren zu können:

Mikrokontroller

Um Signale erfassen und senden zu können, emp-fehle ich einen Arduino Mega, da dieser im Gegen-satz zu den meisten Arduino Modellen, über mehr di-gitale Pins und Speicher verfügt.

Medium

Auf dem Medium werden die Informationen für das Lied gespeichert. Bevor man mit dem Aufbau des Gerätes beginnt ist wichtig zu wissen, auf welche Art und Weise Informationen gelesen und auch geschrie-ben werden können. Es bietet sich das Konzept der altbekannten Lochkarten an, auf denen Informatio-nen durch gestanzte Löcher festgehalten wurden, aber es gibt auch viele andere Möglichkeiten, Infor-mationen festzuhalten, wie zum Beispiel ähnlich wie bei einer Walzenspieluhr das Platzieren von Stiften, welche beim Berühren eines Auslösers eine Signal-übertragung ermöglichen.

Elektromotor

Damit die Informationen, welche auf dem Medium geschrieben worden sind, gelesen werden können, muss dieses mittels eines Motors eingezogen oder ge-dreht werden. Es spielt dabei keine Rolle, ob dafür ein Schritt- oder ein Gleichspannungsmotor verwen-det wird. Beide Motoren haben sowohl Vor- als auch Nachteile zu denen ich später kommen möchte.

Sensor/Schalter

Um die Informationen auf dem Medium erfassen zu können, wird ein Sensor benötigt, welcher an den Mikrokontroller die Information weitergibt, damit letztendlich ein Ton gespielt werden kann. Als Sensor kommen viele Optionen in Frage. Selbst ein impro-visierter Schalter (Kabelkontakte) kann als Sensor dienen. Durch Verwendung eines lichtempfindlichen Widerstandes und einer Leuchtdiode kann eine Licht-schranke improvisiert werden, welche aber durch umliegende Lichteinwirkung stark beeinflusst wer-den kann.

Ausgabe

Um eine Melodie oder ein Lied spielen zu können be-nötigen wir ein Ausgabeelement. Naheliegend ist da-für ein Lautsprecher, aber auch ein Piezoelement (Piezo-Buzzer) kommt dafür in Frage.

Weitere benötigte Teile

4x 100 Ohm Widerstände pro Motorkontakt (MK) 2x kleine npn Transistoren bis 40 mA pro MK 1x stärkerer npn und pnp Transistor bis 2A pro MK 3x 130 Ohm pro Bit der R_2R_Leiter + 1x 130 Ohm oder alternativ Infrarot LED und Infrarot Fototransis-tor pro zu spielenden Ton Empfehlenswert ist ein Breadboard und jede Menge Juperkabel


Entwicklung eines Rotors für das Medium

Ich habe mich zu Anfang dazu entschieden einen Schritt-motor zu verwenden, um mein Medium zu drehen, da man bei diesem genau erfassen kann, wie weit dieser sich ge-dreht hat. Meinen Schrittmotor habe ich aus einem abge-schriebenen Brother-Drucker ausgebaut.

Motor1.jpg

Bild 1: Schrittmotor.


Der Schrittmotor hat, wie man leicht erkennen kann, drei Kontakte. Diese sind über eine Sternverbindung alle mit-einander verbunden, sodass, wenn zwischen zwei An-schlüssen ein Spannungsunterschied herrscht, ein Strom fließt und der Motor sich ausrichtet. Um den Motor flüs-sig in Drehung zu versetzen, ist es nötig an den drei An-schlüssen in richtiger Reihenfolge Spannungsunter-schiede anzulegen. Dabei fließen bei einem Zustand nur durch zwei Anschlüsse Strom. Um die Reihenfolge ge-nauer zu erklären stelle man sich die Kontakte als drei Bit vor, wobei ein Bit die Werte ‚1‘ (HIGH), ‚0‘ (LOW/GND) und sogar einen weiteren Wert annehmen kann, bei dem der Anschluss kein Potential hat und nicht am Stromkreis-lauf beteiligt ist. Diesen Zustand kennzeichne ich mit ei-nem „Minus“ Folgendermaßen ist der Motor anzusteuern:

10- (Start, 0 und – tauschen)

1-0 (1 und – tauschen)

-10 (0 und – tauschen)

01- (1 und – tauschen)

0-1 (0 und – tauschen)

-01 (1 und – tauschen)

Somit haben wir einen Zyklus des Motors erreicht. Um die Steuerung des Motors physikalisch umsetzen zu können, habe ich zunächst eine Simulation erstellt.

Bild 2 weiß.PNG

Bild 2: Steuerschaltung des Schrittmotors unten, gro-bes Schaltsymbol für den Motor oben.


Der erste Ansatz ist eine erweiterte H-Brücke mit NPN- und PNP-Transistoren als Schalter, um den Strom in beide Richtungen fließen lassen zu können. Anhand der Simu-lation habe ich die Widerstände mit 100 Ω gewählt, damit der Strom aus den Arduino-Pins unter 40 mA liegt. Es wird hier eine separate Spannungsversorgung benötigt, da der Arduino nicht genügend Leistung zur Verfügung stel-len kann, um den Motor in Bewegung zu setzen oder be-schädigt werden würde. Außerdem ist zu beachten, dass die Last (Motor) immer am Kollektor der Transistoren lie-gen muss, da die Stromverstärkung sonst zu schwach ist. Nun haben wir hier ein paar Probleme. Unter diesem Auf-bau müssen wir die Output-Pins 3, 5 und 7 zum Sperren der PNP-Transistoren konstant auf HIGH einstellen. Das kann bei größeren Versorgungsspannungen als 5 V dazu führen, dass Strom genau in diese Output-Pins fließt, was den Arduino beschädigen kann sobald der Strom über 40 mA ansteigt. Zumal jeder Pin auch nicht mehr als 40 mA ausgeben darf. Da der Verstärkungsfaktor meiner Transis-toren zu klein ist, sind 40 mA auch nicht ausreichend um den Motor mit genügend Leistung zu versorgen. Beide Probleme lassen sich mit einer Darlington-Schaltung lö-sen.

Bild 3(2) weiß.PNG

Bild 3(2): Steuerschaltung des Schrittmotors mit Dar-lington-Schaltung. Aus Platzgründen nur eine einfa-che H-Brücke (Bilder sind in dem Ordner „paper & documentation/pictures“ zu finden).


Ich verwende hier kleine NPN-Transistoren vor allen Out-put-Pins und jeweils große PNP- und NPN-Transistoren an der Last, welche mehr Leistung vertragen können. Das ist wichtig, da wir nicht genügend Strom an der Basis ha-ben um die Transistoren vollständig zu öffnen. Das hat zur Folge, dass Spannung über die Transistoren abfällt und somit auch Leistung. Ideal wäre die Wahl eines Transis-tors welcher mit dem, uns zur Verfügung stehenden Strom vollständig öffnet und somit einen nur sehr kleinen Wi-derstand hat. Dies hätte mehr Leistung am Motor und we-niger am Transistor zur Folge. Parallel zu den großen Transistoren liegt, zum Schutz der Transistoren, jeweils eine Freilaufdiode, da sich die Spulen des Motors durch-aus in entgegengesetzter Richtung über die Transistoren entladen können als eigentlich gewünscht. Die Freilaufdi-ode verhindert dies, indem sie den Strom ableitet. Bei Beschaffung der der großen Transistoren viel auf, dass diese bereits intern als eine Darlington-Schaltung aufgebaut sind. Somit entsteht letztendlich folgende Schaltung.

Bild 4(2) weiß.PNG

Bild 4(2): Steuerschaltung des Schrittmotors mit Dar-lington-Schaltung und genauerem Aufbau der großen Transistoren.


Nun haben wir gleich zwei Freilaufdioden parallel ge-schaltet vor der Last. Da ich nicht weiß wie groß die Di-ode in dem Transistor ist, gehe ich lieber auf Nummer si-cher und lasse es dabei. Ich könnte nun noch ein Foto meiner Schaltung hinterlas-sen, da diese aber durch die vielen Jumper-Kabel absolut unübersichtlich ist, werde ich lediglich es kurz in einem Video vorzeigen. Nun können wir einen Zyklus, der Motor-Ansteuerung durchlaufen und beginnen wieder von vorne. Der Motor hat sich nun aber nur um 45° gedreht. Somit müssen wir diesen Zyklus acht Mal durchlaufen, um den Motor ein-malig um 360° zu drehen.

Motor 2.jpg

Bild 5: Zahnrad und Motor.


Der Motor aus dem zerlegten Drucker ist direkt mit einem sehr großen Zahnrad verbunden, welches – wie sich spä-ter zeigte – perfekt zu meinem Rotor passt auf dem ich mein Medium befestige. Wichtig war nun zu wissen, wie oft sich der Motor drehen müsse oder wie viele Zyklen durchlaufen werden müssen, um das Zahnrad einmalig um 360° zu drehen, denn eine Drehung dieses Zahnrades entspricht der Länge, des zu spielenden Liedes. Um dies heraus zu finden, habe ich lediglich eine Markierung an das Zahnrad gelegt und den Motor so lange drehen lassen, bis das Zahnrad sich einmal vollständig um 360° gedreht hat. Ich fand heraus, dass 131 Zyklen durchlaufen werden müssen, damit sich das Zahnrad einmal um die eigene Achse dreht. Das entspricht 16,375 Umdrehungen des Motors. Anstelle dieses Verfahrens, hätte man auch auf-wendig am Motor und am Zahnrad die Zähne zählen und das Verhältnis zueinander aufstellen können. Wir wissen nun wie oft wir den Motor drehen müssen, um einen Lieddurchlauf zu erzielen, jedoch ist beim Abspie-len eines Liedes wichtig, mit welcher Geschwindigkeit es gespielt wird. Dies will ich lediglich durch die Länge des Liedes festlegen. Die Länge des Liedes beeinflusst wie lang ein Schritt innerhalb eines Zyklus dauern wird. Die Dauer eines Zyklusschrittes in Mikrosekunden berechnet sich folgender Maßen:

Motor power time in microseconds.png


Code-Motor

int one_cycle_step_count = 6;
int one_motorrotation_cycle_count = 8;
float gear_factor = 16.375;
float one_gearrotation_cycle_count = gear_factor * one_motorrotation_cycle_count;
float one_gearrotation_step_count = one_gearrotation_cycle_count * one_cycle_step_count;

int full_track_minutes = 0;
float rest_track_seconds = 5;
float track_length_in_seconds = full_track_minutes * 60 + rest_track_seconds;
float track_length_in_milliseconds = track_length_in_seconds * 1000;

float motor_power_time_in_mikroseconds = track_length_in_milliseconds / (one_gearrotation_cycle_count * one_cycle_step_count) * 1000;

short i = 0;
bool break_ = true;               // "Bremse": Bei schneller Drehung dreht der Motor nach, sobald keine Spannung mehr anliegt. Die Bremse soll dies verhindern.

void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);


  Serial.begin(9600);

  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  Serial.println("motor_power_time");
  Serial.println(motor_power_time_in_mikroseconds);


  Serial.println("track_length_in_milliseconds");
  Serial.println(track_length_in_milliseconds);

  Serial.println("one_gearrotation_cycle_count");
  Serial.println(one_gearrotation_cycle_count);

  Serial.println("one_cycle_step_count");
  Serial.println(one_cycle_step_count);

  Serial.println("one_gearrotation_cycle_count");
  Serial.println(one_gearrotation_cycle_count);

  Serial.println("one_gearrotation_cycle_count");
  Serial.println(motor_power_time_in_mikroseconds);
}

void loop() {
  
  while(i < one_gearrotation_cycle_count)
  {
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      delayMicroseconds(motor_power_time_in_mikroseconds);
      digitalWrite(4, LOW);
      digitalWrite(6, HIGH);
      delayMicroseconds(motor_power_time_in_mikroseconds);
      digitalWrite(3, LOW);
      digitalWrite(5, HIGH);
      delayMicroseconds(motor_power_time_in_mikroseconds);
      digitalWrite(6, LOW);
      digitalWrite(2, HIGH);
      delayMicroseconds(motor_power_time_in_mikroseconds);
      digitalWrite(5, LOW);
      digitalWrite(7, HIGH);
      delayMicroseconds(motor_power_time_in_mikroseconds);
      digitalWrite(2, LOW);
      digitalWrite(4, HIGH);
      delayMicroseconds(motor_power_time_in_mikroseconds);
      digitalWrite(7, LOW);
    i++;
  }
  
  if(break_ == true)            //Halte den Motor um ein ausrollen zu verhindern.
  {
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    delay(100);
    break_ = false;             //Deaktiviere die Bremse
  }
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
}


Medium

Als Medium wollte ich vorerst eine Walze verwenden, auf denen ich vorhatte Kontakte/Stifte zu platzieren, welche bei Berühren eines Kontaktes, wie ein Auslöser eines Schalters, einen Stromkreislauf ermöglichen. Die Kosten für Bauteile fallen dabei sehr geringer aus. Von dieser Idee hatte ich mich distanziert, da es viel Feingefühl erfordert und aufwendig zu bauen gewesen wäre. Zumal hatte ich eine bessere Idee. Ich kombiniere das Prinzip der Walzenspieluhr mit dem der Plattenspieluhr. Mein Motor dreht ein großes Zahnrad, auf welches perfekt eine meiner Hartpapprollen draufpasst.

Rotor.jpg

Bild 6: Papprolle auf Zahnrad.


Ich muss hinzufügen, dass ich zwei Drucker zerlegt habe und somit zwei Stative für die Papprolle habe. Dadurch kann ich die Papprolle von zwei Seiten einspannen. Zusätzlich zu der Papprolle (Walze), platziere ich um die Papprolle eine oder mehrere Scheiben (Platten-Spieluhr) aus hartem Papier, in die ich meine Informationen schneiden kann.

Bild 7.jpg

Bild 7: Scheibe auf Zahnrad.


Um zu wissen wie ich die Schnitte machen muss, damit am Ende eine Melodie entsteht, habe ich eine kurze Berechnung aufgestellt die es ermöglicht schnell und Kostengünstig eine Schablone zu erstellen. Für jeden Ton den ich Spielen möchte stelle ich eine Spur auf. Ich habe 5 Tonhöhen, die ich spielen möchte. Damit ich alles Korrekt berechnen kann, muss ich wissen wie viele Takte auf dieser Scheibe gespielt werden und um welche Taktart es sich handelt. Auf meiner Scheibe werden 4 Takte mit einem vierviertel-Takt gespielt. Vier Schläge pro Takt mal 4 Takte, macht 16 Schläge. Ein Schlag entspricht einer viertel Note. Für jede Note definiere ich Länge, einen Anfang und ein Ende wann (oder eher wo) die Note gespielt wird und wandle Anfang und Ende zusätzlich in einen Winkel um. Die Länge eines Tones berechnet sich durch: Taktanteil · ((2·π·360°)/4) · 0,75 Die 0,75 sind 75% der Tonlänge. Dies ist nötig, damit zwei aufeinander folgende Töne nicht verschmelzen. Der prozentuale Teil ist aber flexibel, solange der Abstand zwischen den Tönen nicht zu klein wird. Der Start eines Tons ist die Tatsächliche Länge (100%), des letzten Tones auf den Start, des letzten Tons addiert. Das Ende eines Tones ist lediglich die Addition von Start und prozentualer Länge, des aktuellen Tons. Damit die Töne auf die Scheibe passen, müssen dessen Anfang und Ende in einen Winkel umgewandelt werden. Dieser berechnet sich durch: Winkel = Radius / ( 2·π·360°) · Anfang (oder Ende) Zufälligerweise entspricht der maximale Radius, der auf ein A4 Blatt passt, 360 Pixel. Damit ergibt sich: Winkel = Anfang (oder Ende)/(2·π) Zusätzlich muss noch die Höhe jeder Spur berechnet werden. Diese Berechnet sich durch:

Höhe Lücke.png

Die Berechnungen finden sich im Ordner „disc“ in der disc.xlsx wieder. Damit diese berechneten Daten visualisiert, gedruckt und geschnitten werden können, verwende ich svg zum Zeichnen von geometrischen Formen. Ich zeichne den Außenund Innenkreis, einen Mittelpunkt und ein schmales rotes Rechteck für den Anfang und ein Gelbes für das Ende eines Tones. Die Rechtecke werden pro Spur auf derselben Stelle platziert und anschließend um den zugehörigen Winkel auf die richtige Position rotiert. Das Resultat sieht folgendermaßen aus:

Bild 8.png

Bild 8: Berechnete Schablone für die Scheibe.


Diese Schablone kann auf A4 Papier gedruckt werden. Zum Sparen von Druckertinte sollte der Kreis nicht ausgefüllt werden. Vorzugsweise mit einem Kreisschneider oder einem Modellier- oder Teppichmesser kann mit der Schablone aus dem Hartpapier die fertige Scheibe geschnitten werden und auf dem Rotor befestigt werden. Diese Schablone mit nur vier Takten wirkt recht kurz. Der Grund dafür ist folgender: Zu Lasten der Wirtschaftlichkeit, kann ich mit mehreren Scheiben verschiedene Passagen eines Titels abdecken. Das hat den Vorteil, dass die Genauigkeit stark erhöht und die Bruchgefahr des Mediums gemindert wird. Ich habe den Titel „Korobeiniki“ (Tetris Thema) gewählt. Dieser Titel besitzt 32 Takte. Allein 8 Takte treten 3 Mal auf. 2 weitere Takte tauchen doppelt auf. Es gibt nur 2 Takte, welche nur einmalig gespielt werden. Durch diese Überschneidungen kann man die tatsächliche Liedlänge auf den Schablonen auf 12 Takte reduzieren.

Sensor

Beim Zerlegen des Druckers fand ich einige Gabellichtschranken, welche ich nun als Sensoren verwende. Die Gabellichtschranke besteht aus einer Infrarotlicht-emittierenden Leuchtdiode und einem Fototransistor, welcher auf das Infrarotlicht der Diode reagiert. Trifft das Infrarotlicht den Fototransistor, so wird dieser durchlässig und hat einen niedrigen Widerstand. Wird der Fototransistor jedoch durch ein Hindernis verdeckt, so schließt der Transistor und hat einen sehr hohen Widerstand.

Bild 9.jpg

Bild 9: Gabellichtschranke.


Ich habe einen Draht von beiden Seiten so gebogen, dass die Scheibe in der Lücke, der Gabellichtschranke geführt wird. Die Infrarot-LED wird typischerweise mit 1,2 V betrieben.

Bild 10 weiß.PNG

Bild 10: Simulation der Lichtschranke.


Ich habe den Widerstand nach dem Fototransistor so gewählt, dass am Ausgang, beim Öffnen des Transistors eine möglichst hohe Spannung (ca. 5V) anliegt (über den Fototransistor fällt wenig Spannung und über den Widerstand fällt viel Spannung ab) und beim Sperren eine möglichst geringe Spannung (ca. 0,3V). Somit kann ich digitalRead() verwenden und bin nicht auf die wenigen Analogpins angewiesen. Zusätzlich zu den Gabellichtschranken habe ich mir noch ein paar einzelne Infrarot-LEDs und Fototransistoren besorgt, damit ich auf den inneren Spuren der Scheibe auch Informationen erfassen kann. Datenblätter der Sensoren liegen im Ordner „parts“ bereit. Für die Messung an der Lichtschranke habe ich das Kurze Programm „opto.ino“ in dem „opto“-Ordner.


Code Sensor

bool opto = false;                      //Variable für die Reaktion des Fototransistors auf Infrarotes Licht. 1 = Infraroticht erreicht den Fototransistor; 2 = kein Infrarotlicht
//float opto = 0; 
int opto_pin = 50;
int analog_opto_pin = 0;
int sound_pin = 51;

void setup() {
  Serial.begin(9600);
  pinMode(opto_pin, INPUT);
  pinMode(sound_pin, OUTPUT);
}

void loop() {
  opto = digitalRead(opto_pin);
  //opto = analogRead(analog_opto_pin);
  //opto = 5*opto/1023;       
  Serial.println(opto);                 //Ausgabe
  if(opto == 1)                         //Infrarotlicht erreicht den Fototransistor
  {
    tone(sound_pin, 432);               //Spiele Ton auf Pin 52 mit 440 Hz.
  }
  else
  {
    noTone(sound_pin);                  //Beende den Ton
  }
}


Klangerzeugung

Squarewave

Um einen Ton zu erzeugen, bietet Arduino die Funktion tone(), die Mithilfe eines Rechtecksignals eine Hörbare oder auch sichtbare Frequenz erzeugt. Dabei wird mit einem duty cycle von 50% auf einem Ausgabe-Pin lediglich zwischen 0V und 5V gewechselt. Die Anzahl an Perioden pro Sekunde entspricht der Frequenz des ausgegebenen Signals.

Direct Digital Syntesis [1]

Mittels der Pulsweitenmodulation und dem timer interrupt des Arduino können wir sehr präzise und mit hoher Geschwindigkeit Sinus- oder jegliche Form von Welle oder ein beliebiges Signal approximieren. Für die auszugebenden Signale bedient man sich oft einer Wertetabelle, in der die Samples des Signals gespeichert sind. Hier ist auf den limitierten Speicher zu achten. Die Auflösung eines Samples spielt hier eine sehr große Rolle. Da die meisten Arduino Typen eine Taktfrequenz von 16MHz (Nano 12 MHz, Due 84 MHz,)[2,3] gewährleisten, lässt sich mühelos ein hoher Sinus-Ton erzeugen. Bei 8 Bit pro Sekunde und einer Taktfrequenz von 16MHz sind 62500 Samples möglich (abzüglich des loop-overhead). Bei 16 Bit Auflösung bleiben weniger als 245 Samples pro Sekunde, was deutlich zu wenig ist. Jedoch kann man bei geringerer Sampling-Rate, mittels eines Tief-Pass-Filters die Oberwellen entfernen, welcher unser Signal von der Approximation näher an die Sinus-Welle heranführt. Leider ist der Code für den timer interrupt nicht sehr trivial und bedarf intensiverer Einarbeitungszeit. Dies brachte mich dazu mich gegen das DDS Verfahren zu entscheiden.

Digital-to-Analog-Converter (R_2R-Ledder) [4]

Um ein analoges Signal mit noch höherer Frequenz generieren zu können, haben wir die Möglichkeit, kostengünstig, einen Digital-Analog-Wandler zu bauen. Dieser besteht lediglich aus zwei Größen von Widerständen. Der erste Widerstand entspricht dem Doppelten oder der Hälfte des zweiten Widerstandes. Für x Bit Sampling- Rate werden x · R - R und x · 2R + 2R (oder zusammen 3x · R + R) Widerstände und ein Digital-Pin benötigt. Damit wir die kritischen 40 mA des Arduino nicht überschreiten, sollte die Strecke mit dem kleinsten Widerstand zwischen Input und Output nicht weniger als 5 V / 0,04 A = 125 Ohm aufweisen. Bei uns ist diese kritische Strecke, die vom highest significant Bit zum Output (ganz links im Bild 11).

Bild 11 weiß.PNG

Bild 11: Simulation der R_2R-Leiter.


Dieses aufgebaute Konstrukt nennt man Widerstandsleiter (genauer R_2R-Netzwerk). Für die 2R Widerstände habe ich 130 Ohm gewählt und für die 1R Widerstände habe ich zwei 130 Ohm Widerstände parallel geschaltet, was 65 Ohm entspricht. Mit jedem weiteren Bit in dem R_2R-Netzwerk steigt die Genauigkeit des Ausgabesignals um genau ein Bit. Der Nachteil daran ist, dass der immer größer werdende Widerstand das Ausgabesignal sehr stark dämpft. Nach wenigen Bit benötigen wir bereits einen Operationsverstärker, um das Ausgabesignal hörbarer zu machen. Auch ein Transistor oder eine Darlington-Schaltung käme dafür in Frage, jedoch schneidet der Transistor die unteren ca. 0,7V ab.

Bild 12.jpg

Bild 12: Erste Umsetzung der R_2R-Leiter.


Bild 13.jpg

Bild 13: Gelötete Version der R_2R-Leiter. Von linksnach rechts, unten LSB bis HSB, oben OUTP und GND


Überprüft man das Ausgabesignal an einem Oszilloskop und verbindet nur vereinzelt Bits mit dem Mikrocontroller, so kann man sehr deutlich sehen, wie mit jedem weiteren verbundenen Bit am Mikrokontroller, die Genauigkeit der Kurve ansteigt.

Bild 14.BMP

Bild 14: R_2R Leiter mit einem verbundenen Bit


Bild 15.BMP

Bild 15: R_2R Leiter mit zwei verbundenen Bit


Bild 16.BMP

Bild 16: R_2R Leiter mit vier verbundenen Bit


Bild 17.BMP

Bild 17: R_2R Leiter mit acht verbundenen Bit


Das Signal in Bild 17 ist von einer Sinuswelle fast nicht mehr zu unterscheiden. Die kleinen „Haken“ entstehen durch Rauschen, Toleranzen in den Widerstandsgrößen und unter Umständen auch wie im alten Aufbau - zu sehen in Bild 12 - durch ungewollte Kurzschlüsse. Beim Kurzschluss über niederwertigen Bitpositionen können sehr kleine „Haken“ entstehen. Wird über höherwertige Bitpositionen ein Kurzschluss gebildet, so entsteht im Signal ein „Haken“ wie im folgenden Bild zu sehen.

Bild 18.BMP

Bild 18: R_2R Leiter mit acht verbundenen Bit und Kurzschluss im höherwertigen Bitpositionsbereich


Bei einem Aufbau wie im Bild 13 sollte ein „schöneres“ Sinussignal zu betrachten sein. So toll und einfach diese Lösung sein mag, es gibt trotzdem noch ein Problem bei dieser Lösung. Wir müssen wie bei der direkten digitalen Synthese die Zeit mittels des timer interrupt berechnen, um eine gewünschte Frequenz berechnen zu können und dabei auch ausreichend präzise zu sein. Der Rechenaufwand dafür ist jedoch sehr gering, was eine sehr hohe Ausgabefrequenz ermöglicht, sodass wir weit über den hörbaren Bereich der Frequenzen hinauskommen können. Soweit ich den Code entwickeln konnte, ist dieser im Ordner „DACR_2R“ in der Datei „R_2R.ino“ zu finden.

Digital-Analog-Wandler zur Erfassung mehrerer Schalter mittels eines einzelnen Analog-Pins

Bevor ich mit dem ersten Aufbau begonnen und nach Ideen gesucht hatte, überlegte ich mir, die Spieluhr ähnlich wie bei einer Walzenspieluhr mit Stiften zu versehen, welche als Auslöser für einen Schalter fungieren. Um dann ein Signal zu erfassen, kann man für jeden Schalter einen Digital-Pin des Arduino verwenden. Leider sind die Pins immer begrenzt. Gerade bei kleineren Modellen macht sich das stark bemerkbar. Ich hatte die Idee mit einem Analog-Pin mehrere Schalter zu erfassen. Dies macht jedoch nur Sinn, wenn man genau bestimmen kann, welcher Schalter gerade betätigt wurde. Zusätzlich besteht die Möglichkeit, das mehrere oder sogar alle Schalter simultan betätigt werden. Um das zu lösen, können wir ebenfalls die R_2R Leiter verwenden. Bei einer Betriebsspannung von 5 V einer acht Bit R_2R Leiter steigt die Ausgangsspannung mit jedem Inkrement um ca. 20 mV. Ein Analog-Pin eines Arduino misst mit 10 Bit auf 1024 Abstufungen genau. Das entspricht bei einer Referenzspannung von 5 V etwa 4,9 mV. Das entspricht etwa einem Viertel unserer 20 mV. Legen wir nun eine Toleranz von 5 mV fest, so können keinerlei Überschneidungen zwischen Schaltern entstehen, denn zwischen zwei zu erfassenden Bereichen, wie zum Beispiel 20 mV (Toleranzbereich von 15 mV bis 25 mV) und 40 mV (Toleranzbereich von 35 mV bis 45 mV) bleiben immer noch weitere 35 mV – 25 mV = 10 mV Differenz. Das zeigt, dass wir in der Lage sind, mit einem einzigen Arduino-Analog-Pin ganze 8 Schalter gleichzeitig zu erfassen.

Ergebnis/Auswertung

Das Konzept ist zu großen Teilen ausgearbeitet und benötigt noch Verbesserungen, um reibungslos zu laufen und hochauflösende Töne spielen zu können. Nach der Zusammenführung aller Abschnitte hat sich der Gerät als funktionstüchtig bewiesen. Auch Ungenauigkeiten beim Ausschneiden der Tonscheibe und Platzieren der Sensoren erlauben eine deutlich erkennbare Melodie. In dem Ordner „paper & documentation/videos“ sind Testvideos des Motors und der Gabellichtschranke zu finden. Ein Programm, welches dafür sorgt, dass sich die Spieluhr selbstständig in die Startposition ausrichtet ist sehr wünschenswert und sollte nicht all zu aufwendig sein. Um die Spieluhr noch transportfreundlicher zu machen und zur Übersichtlichkeit sollten alle Schaltungen auf Lochrasterplatinen gelötet werden. Die Übertragung von Exel-Tabelle auf das svg Format geschieht noch per Hand und ist sehr aufwendig, jedoch kann dafür ein Programm geschrieben werden, welches in Zukunft sehr viel Zeit sparen wird. Nachdem mein Multimeter recht spät bei mir eingetroffen ist und ich endlich Messungen vornehmen konnte, fiel auf, dass die tatsächlichen Werte nicht mit der Simulation übereinstimmen. Widerstände müssen nun neu gewählt werden um die Schaltung zu optimieren, denn aus den Pins des Arduino fließen aktuell maximal 120 μA. Hier ist noch sehr viel Potential zur Verbesserung. Die darauffolgenden Schritte wären: ein Interface zur Modifikation der Abspielgeschwindigkeit, Auswahl von verschiedenen Instrumenten und Klirrfaktoren, etc.

Bild 19.jpg

Bild 19: Alle Schaltungen: Arduino Mega unten, R_2RNetzwerk links, Schrittmotor-Ansteuerung Mitte rechts, Messschaltung für die Lichtschranke in der Mitte


Zu guter Letzt stelle ich das Endresultat als Schaltbild vor. Der Code für das vollständige Projekt findet sich im Ordner „all_together“ in der „all_together.ino“.

Bild 20.png

Bild 20: Alle Schaltungen: Arduino Mega links, R_2R-Netzwerk oben, Schrittmotor-Ansteuerung unten, Messschaltung für die Lichtschranke verteilt Mitte links und rechts. Arduino [5], Zahnrad [6]

Danksagung

Ich möchte mich besonders bei Jonathan Siefert bedanken, weil er mir nicht zu selten mit Ideen und Ratschlägen zur Seite stand. Auch sein Arsenal an Elektronischen Geräten, wie Oszilloskop und Spannungsgenerator haben sehr bei der Entwicklung der Motorsteuerung geholfen. Zusätzlich möchte ich mich bei Martin Schied bedanken, da er mir mit Anregungen für Verbesserungen, Zeit und Bauteilen dienen konnte. Auch meine Freunde, welche am Korrekturlesen der Dokumentation beteiligt waren, möchte ich hier erwähnen. (Katharina, Norman, Maximilian, Christian und Alex) Für genauere Betrachtung bitte im Ordner “paper & documentation/pictures” die Datei “Bild 20.png” öffnen u/o drucken.


REFERENZEN

[1] Joe Marshall “Arduino music using Direct Digital Synthesis” Human computer interaction research software development and performance, Date un-known.

<-http://www.cs.nott.ac.uk/~pszjm2/?p=674->

[2] Arduino und mehr “Arduino – Vergleich Uno Nano Mega”, (21.12.201 ) <-http://www.robodino.de/2011/12/arduino-vergleich-uno-nano-mega.html->

[3] Philip Steffan, Heise online Make:, „Angetestet: Ar-duino Due“, (26.11.2012) <-http://www.heise.de/make/artikel/Angetestet-Ar-duino-Due-1756123.html->

[4] bitluni's lab, “DAC using R-2R resistor ladder,, Youtube (30.01.2014) <-https://www.youtube.com/watch?v=_tABS7AX8D8->

[5] Grafik Arduino Mega 2560 Pins <-https://arduino-info.wi-kispaces.com/file/view/Mega2-900.jpg/421499040/Mega2-900.jpg->

[6] Grafik Zahnrad <-https://pixabay.com/static/up-loads/photo/2014/09/30/15/15/gears-467261_960_720.png->