In der Schaltung „Mini Piano mit Arduino“ wurden sieben Berührungssensoren direkt mit I/O-Pins des Arduino verbunden. Wenn man
bedenkt, dass
Arduino Nano nur über wenige Pins verfügt, ist eine solche Lösung nicht besonders günstig. Eine Erweiterung um weitere Taster ist kaum
möglich. Auch Benutzung der Anschlüsse für andere Zwecke ist sehr stark eingeschränkt.
In der folgenden Schaltung kommen Logik-Gatter zum Einsatz, wodurch die Anzahl der notwendigen Pins stark reduziert wird. Für sieben
Ton-Taster werden drei Eingänge des Arduino benötigt. Bei einer Erweiterung auf 14 Taster wäre nur eine zusätzliche Leitung notwendig.
Die Logik-Gatter ermöglichen uns, die Taster-Nummerierung zu codieren. Die Codierung der sieben Taster, die in dem Versuch aufgebaut werden,
sieht wie folgt aus:
Taster Codierung
In dem Versuch kommen zwei ICs mit Bezeichnung SN74HCT00N zum Einsatz. Es handelt sich hier um Logik-Bausteine, die jeweils
vier Nand-Gatter beinhalten. Jedes Gatter verfügt wiederum über zwei Eingänge. Anschließend wird der Logikbaustein SN74LS32N in die
Schaltung eingepflegt. Er stellt vier OR-Gatter zur Verfügung. Für unsere Zwecke werden insgesamt neun Gatter verwendet.
Die Berührungssensoren sind jeweils aus zwei NPN-Transistoren aufgebaut. Zusammen bilden sie eine Darlington-Schaltung.
Die Berührungsfläche besteht aus zwei blanken Drähten. Die
Verschaltung der beiden Transistoren, hier kommen die Transistoren BC172C zum Einsatz, zusammen mit zwei Widerständen ist auf dem Bild
oben dargestellt. Die Signale, die die Berührungssensoren liefern, werden nicht direkt zum Arduino geführt, sondern zu den Gattern. Hier
wird entschieden, ob und wann ein Signal durchgeschaltet wird. Laut der oben aufgestellten Tabelle (Taster Codierung) bekommt der Eingang
Nr. 1 des Arduino (hier D2) ein Signal erst dann, wenn Taster 1, Taster 3, Taster 5 oder Taster 7 betätigt wird. Die dazugehörige Schaltung mit
Gattern sieht wie folgt aus:
Beispiel 4 Taster + 2 NAND + OR
Werden die Berührungssensoren nicht berührt (Fingerkontakte offen), bleiben die Transistoren in Ruhezustand. Die Punkte A1 … A4
stehen unter Spannung von 5V (HIGH). Sie sind mit Eingängen der NAND-Gatter verbunden. Folglich stehen die Punkte B1 – B2 auf LOW. Sie
sind mit den Eingängen des OR-Gatters verbunden. OR-Gatter liefert in diesem Zustand am Ausgang ebenfalls LOW-Signal. Damit steht der
betreffende Arduino Eingang auf LOW. Wird ein der Sensoren (z.B. Taster 1) berührt (Fingerkontakte kurzgeschlossen), werden die Transistoren leitend und
der Punkt A1 mit Masse verbunden. Er steht jetzt auf LOW. Folglich wird das NAND-Gatter aktiv und schaltet seinen Ausgang und damit auch
das Potenzial am Punkt C auf HIGH. Das OR-Gatter reagiert entsprechend und schaltet seinen Ausgang auf HIGH. Diese Zustandsänderung kann
man mit Arduino-Programm abfangen und passend reagieren. Analog verhält sich die Schaltung, wenn Taster 3, 5 oder Taster 7 betätigt
wird.
Die Schaltung wurde um einen Potenziometer (und Kondensator), einen Schalter und eine 7-Segmentanzeige erweitert. Mit dem Poti kann die
Lautstärke eingestellt werden. Auf der 7-Segmentanzeige werden die aktuell gespielten Frequenzen angezeigt. Mit dem Schalter wird auf andere
Tonlage umgeschaltet.
Auch in diesem Fall ist die Aufgabe, die das Programm grundsätzlich zu bewältigen hat, nicht besonders kompliziert.
Aus der Situation an den drei Eingängen wird die Nummer des Tasters, der gerade betätigt wurde, decodiert und der Lautsprecher mit der
diesem Taster zugeordneten Frequenz zum Schwingen gebracht.
Das war das Grundsätzliche. Testet man die Schaltung, werden gleich zwei Probleme sichtbar. Die Signale, die von den Tastern stammen,
werden beim Berühren der blanken Drähte gelegentlich kurz unterbrochen. Das Phänomen tritt auf, wenn die Haut zu trocken ist oder der Druck
auf die Drähte zu leicht ausfällt. Eine Abhilfe hierzu wären z.B. Transistoren, die besonders hohe Verstärkung haben. Das Problem wird
im Programm dadurch abgefangen, dass jedes Signal „zeitlich“ verlängert wird. Erfolgt in der Zeit eine kurze Unterbrechung, wird sie
somit überbrückt.
Des Weiteren stellte sich heraus, dass die Signale von den Gattern nicht gleichzeitig die Arduino-Eingänge erreichen. Wenn sich
jedoch ein Signal verspätet, kommt es vor, dass das Programm eine andere Taster-Nummer erkennt und damit falsche Töne ausgibt. Um das
Problem zu beseitigen, wird im Programm eine Start-Zeit eingeführt. Sobald das Programm die erste positive Flanke an irgendeinem Eingang
erkennt, wird diese Zeit gestartet. Erst nach Ablauf dieser Zeit wird die decodierte Tasternummer akzeptiert. Hier gehen wir einfach davon
aus, dass in der Zeit alle Gatter durchschalten und das Programm die relevanten Taster richtig erkennen kann.
// **************************************************************************************
// Mini - Piano mit Logikgattern
// Finger-Schalter mit Darlington Schaltung
// NAND und OR Gatter
// Arduino Nano, IDE 1.8.13
// **************************************************************************************
#include<TM1637Display.h>#define CLK 10 // Display Pin CLK
#define DIO 11 // Display Pin DIO
// Frequenzen der Noten
int Note [] = { 27, 31,
33, 37, 41, 44, 49, 55, 62,
65, 73, 82, 87, 98, 110, 123,
131, 147, 165, 175, 196, 220, 247,
262, 294, 330, 349, 392, 440, 494,
523, 587, 659, 698, 784, 880, 988,
1047, 1175, 1319, 1397, 1568, 1760, 1976,
2093, 2349, 2637, 2794, 3136, 3520, 3951,
4186, 4699 };
TM1637Display display(CLK, DIO);
int Um_Schalter = 5;
int Schalter_Bit_1 = 2;
int Schalter_Bit_2 = 3;
int Schalter_Bit_3 = 4;
int Lautsprecher = 12;
String Ausgabe;
int Frequenz;
int Schalter_Nr, Note_Nr;
bool Schalter_Status [] = { 2,3,4,5 };
int Wartezeit_Start = 5;
int Wartezeit_Unterbrechung = 20;
unsigned long Millis_Aktuell;
unsigned long Millis_Start;
unsigned long Millis_Unterbrechung;
bool Flanke_Start = false;
byte Nr = B00000000;
bool Verzoegerung;
void setup() {
display.setBrightness(10); // Anzeige Helligkeit
display.clear(); // Displa löschen
pinMode (Um_Schalter, INPUT_PULLUP);
pinMode (Schalter_Bit_1, INPUT_PULLUP);
pinMode (Schalter_Bit_2, INPUT_PULLUP);
pinMode (Schalter_Bit_3, INPUT_PULLUP);
pinMode (Lautsprecher, OUTPUT);
}
void loop() {
Schalter_Status [0] = digitalRead(Schalter_Bit_1);
Schalter_Status [1] = digitalRead(Schalter_Bit_2);
Schalter_Status [2] = digitalRead(Schalter_Bit_3);
Schalter_Status [3] = digitalRead(Um_Schalter);
Millis_Aktuell = millis();
// **************************************************************************************
// Die Eingangssituation wird untersucht
int Eingangssumme = 0;
for (int i=0; i<3; i++) {
if (Schalter_Status[i] == HIGH) {
Eingangssumme++;
bitSet (Nr, i);
Millis_Unterbrechung = millis(); } }
Schalter_Nr = Nr;
// **************************************************************************************
// Innerhalb der "Wartezeit_Unterbrechung"
// wurden keine Signale erkannt.
// ==> Keine Signale = Musik AUS
if ((Eingangssumme == 0) && (Millis_Aktuell > (Millis_Unterbrechung + Wartezeit_Unterbrechung))) {
noTone (Lautsprecher); // Lautsprecher AUS
Flanke_Start = false;
Nr = B00000000; }
// **************************************************************************************
// Die erste Flanke von igendeinem Eingang
// erkannt
if ((not Flanke_Start) && (Eingangssumme > 0) && (not Verzoegerung)) {
Millis_Start = millis();
Verzoegerung = true; }
// **************************************************************************************
// Flanke Start aktivieren
if (Verzoegerung && (Millis_Aktuell > (Millis_Start + Wartezeit_Start))) {
Flanke_Start = true;
Verzoegerung = false; }
// **************************************************************************************
// Ein Ton kann generiert werden
if ((Schalter_Nr > 0) && Flanke_Start) {
Note_Nr = 22 + Schalter_Nr;
if (Schalter_Status [3] == LOW) { Note_Nr = Note_Nr + 7; } // Umschalter An?
Frequenz = Note [Note_Nr]; // Frequenz auslesen
Ausgabe = String (Frequenz);
display.showNumberDecEx(Ausgabe.toInt(), 0b00000000, false, 4, 4); // Ausgabe Display
tone (Lautsprecher, Frequenz); // Ton erzeugen
}
}
// ******************************************************************************************