GET Fachpraktikum 2021 Stimmgerät

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen

Autoren: Orience Charnelle Mefenya, Jan Henrik Steltenkamp
Betreuer: Prof. Mirek Göbel

Projektplakat

Einleitung

Dieser Artikel beschreibt den Aufbau eines Prototyps für ein Stimmgerät. Dieses wird von Musikern verwendet, um ihr Instrument korrekt einzustellen bzw. zu stimmen. Dabei wird die Frequenz im Raum durch das Gerät gemessen und an einer Skala angezeigt. Sollte das Instrument nicht korrekt gestimmt sein, wird dies auf der Skala deutlich und ermöglicht so das Justieren des Musikinstrumentes. Solche Geräte sind günstig im Handel verfügbar. Allerdings ist es nicht üblich, dass solche Geräte auch die Lautstärke im Raum angeben können. Diese Funktion soll zusätzlich durch das Gerät abgedeckt werden.

Verschiedene Musikinstrumente erzeugen unterschiedlich hohe Tonfrequenzen, welche in Herz gemessen werden. Das Stimmgerät ist darauf ausgelegt, die Frequenzen einer Gitarre analysieren zu können. Bei einer Gitarre werden unterschiedlich lange und unterschiedlich dicke Saiten angeschlagen. Über die Beschaffenheit der einzelnen Saiten ergibt sich so eine gezielt hervorgerufene Schwingung mit klar definierter Frequenz. Über die insgesamt 6 Saiten können so 6 Grundtöne erzeugt werden.

Zuordnung der Frequenzen zu den verschiedenen Grundtönen wird in Tabelle 1 dargestellt.

Tabelle 1: Frequenzverteilung der Grundtöne
Saite Nr. Grundton Frequenz
1 E 329.63 Hz
2 H 246.94 Hz
3 G 196.00 Hz
4 D 146.83 Hz
5 A 110.00 Hz
6 E 82.41 Hz

Projektplan

Abb. 1: Projektplan


Anforderungen

Tabelle 2 zeigt die funktionalen Anforderungen, die zu Beginn an das Projekt gestellt wurden.

Tabelle 2: Anforderungen
ID Inhalt Ersteller Datum
01 Das Gerät muss einen Schallsensor besitzen Jan Henrik Steltenkamp, Orience Charnelle Mefenya 02.10.2021
02 Der Schallsensor muss die Schwingungen bzw. den Schall im Raum messen. Jan Henrik Steltenkamp, Orience Charnelle Mefenya 02.10.2021
03 Das Signal des Sensors muss auf die Frequenzen und die Amplituden aufgeteilt werden. Jan Henrik Steltenkamp, Orience Charnelle Mefenya 02.10.2021
04 Die Frequenz mit dem größten Anteil an den Schwingungen muss ermittelt werden. Jan Henrik Steltenkamp, Orience Charnelle Mefenya 02.10.2021
05 Die größte gemessene Lautstärke muss ermittelt werden. Jan Henrik Steltenkamp, Orience Charnelle Mefenya 06.01.2021
06 Die im Raum vorherrschende Frequenz und die Lautstärke muss auf dem Bildschirm angezeigt werden. Jan Henrik Steltenkamp, Orience Charnelle Mefenya 02.10.2021
07 Sollte die Frequenz zu niedrig oder zu hoch liegen, muss dies per LED angezeigt werden. Jan Henrik Steltenkamp, Orience Charnelle Mefenya 02.10.2021
08 Sollte die Lautstärke für das menschliche Gehöhr schädlich sein, muss dies per LED angezeigt werden. Jan Henrik Steltenkamp, Orience Charnelle Mefenya 16.12.2021
09 Das Gerät muss in einem tragbaren Gehäuse verbaut werden. Jan Henrik Steltenkamp, Orience Charnelle Mefenya 16.12.2021
10 Das Gerät muss über eine mobile Stromversorgung verfügen. Jan Henrik Steltenkamp, Orience Charnelle Mefenya 16.12.2021

Systementwurf

Die folgende Abbildung zeigt die grundsätzlichen Funktionen, welche durch das Gerät abgedeckt werden sollen. Der Grundsatz ist nach dem Prinzip Eingabe, Verarbeitung, Ausgabe (EVA) konzipiert.

Abb. 2: Systementwurf [1]


Komponentenspezifikation

Tabelle 3: Komponentenspezifikation
ID Komponente Eingänge Ausgänge Aufgabe Art der Komponente
01 Mikroprozessor Signale des Sensors und des Tasters Signale für LCD Display und Leuchten Auswertung der Eingangssignale und Herausgabe der Signale zur Anzeige Hardware
02 Sensor Spannungsversorgung Messsignal der anliegenden Schallwellen Aufnahme der Informationen über die Schallfrequenz und Lautstärke Hardware
03 Taster Spannungsversorgung Hohes oder niedriges Spannungsniveau Ermöglichung des Umschaltens zwischen den Programmen Hardware
04 Display Anzeigesignal des Arduino, Spannungsversorgung Zeichenblöcke auf dem Bildschirm Anzeige der ermittelten Kennwerte Hardware
05 Leuchten Anzeigesignal des Arduino, Spannungsversorgung Leuchtsignal zum Visualisieren von Informationen unterstützende Anzeige der ermittelten Kennwerte Hardware
06 Frequenzmessung Eingangssignal des Sensors aktuelle Schallfrequenz Analyse des Eingangssignals und Ermittlung der Schallfrequenz Software
07 Lautstärkemessung Eingangssignal des Sensors aktuelle Schallfrequenz Analyse des Eingangssignals und Ermittlung der Lautstärke Software

Programmierung

Die Programmierung des Stimmgerätes mit seinen zwei Hauptfunktionen Frequenzmessung und Lautstärkemessung basiert auf einem Zustandsautomat. Diese Vorgehensweise ermöglicht, dass für das Umschalten zwischen den beiden Hauptprogrammen lediglich ein Tastersignal ausgelesen werden muss. Die Aufgabe des in dem Systementwurf eingeplanten Höher/ Tiefer-Buttons konnte in der Software implementiert werden. Daher war es im späteren Verlauf nicht nötig, diesen in dem Aufbau des Gerätes zu berücksichtigen.

Versuch der Umsetzung mit Matlab Simulink

Zunächst wurde versucht das Projekt in Matlab Simulink umzusetzen. Um den Arduino mittels Simulink ansprechen zu können, wird zunächst das Simulink Support Package for Arduino Hardware [2] benötigt. Um die Schallfrequenz aus dem Sensorsignal berechnen zu können, war geplant, die Fourier-Transformation in Form der FFT zu benutzen. Um dies in Simulink zu realisieren, müssen zusätzlich noch die DSP System Toolbox [3] und die Signal Processing Toolbox [4] installiert werden. Nachdem diese Schritte unternommen wurden, konnte mit der Erstellung des Simulink Programms begonnen werden, welches in der folgenden Abbildung dargestellt ist.

Abb. 3: Simulink FFT Programm


In dem Programm wurde zunächst ein "Analog Input" Block verwendet, um das Sensorsignal des Arduinos einzulesen. Dieses wurde dann mit "Zero-Order-Hold" für die weitere Berechnung diskreditiert. Ein darauf folgender "Buffer" speichert anschließend eine Reihe von Werten in einem Array, welche dann an den "FFT" Block weiter gegeben werden. Nach der FFT wird der Betrag der errechneten Werte mit einem "Abs" Block gebildet, was dem Realteil der Werte entspricht. Dieser Realteil ist dann jeweils die ausgegebene Frequenz des vom Sensor übergebenen Signal. Dieser Programmablauf sollte für unser Projekt verwendet werden. Allerdings hat das Abspielen des Programms zu folgender Fehlermeldung geführt:

Abb. 4: Simulink FFT Programm Fehlermeldung


Der ausgegebene Fehler zeigt auf, dass bei der Umwandlung der komplexen Zahlen aus dem "FFT" Block mit dem "Abs" Block ein Fehler unterläuft. Dieser Fehler im Programm konnte im Rahmen des Projektes nicht beseitigt werden, weshalb es nicht möglich war, das Simulink Programm erfolgreich auf dem Arduino zu implementieren.

Aus diesem Grund wurde im nächsten Ansatz die Umsetzung des Programms in der Arduino IDE Umgebung getestet. Nach einigem ausprobieren konnte der Code dort erfolgreich auf dem Arduino angewendet werden. Daher wurde bei dem Projekt im weiteren Verlauf die Arduino IDE Umgebung genutzt, um das Projekt umzusetzen.

Programmablauf

Die folgende Abbildung zeigt den Programmablaufplan des Stimmgerätes in der Arduino IDE Umgebung. Der Programmablauf ist unter folgendem Link in SVN verfügbar.

Abb. 5: Programmablaufplan


Programmcode

Die Programmierung des Stimmgerätes wurde mit der Arduino IDE Software erstellt. Der Programmcode des Stimmgerätes ist in dem nachfolgenden Fenster zu sehen.

Um die Frequenzmessung mittels Fourier Transformation realisieren zu können, wurde ein verfügbares Arduino IDE Skript als Grundlage verwendet[5].

Der darauf aufbauende Programmcode übernimmt die Lautstärkemessung, sowie die Verarbeitung und Ausgabe der zyklisch ermittelten Schallfrequenz und Lautstärke-Werte. Der Wechsel von verwendetem Skript zu selbst erstellten Programmcode ist mit Platzhaltern (//) im Programmcode markiert. Die Arduino IDE Datei ist unter folgendem Link im SVN verfügbar.

Initialisierung

Initialisierung: Stand 03.01.2021
////////////////////////////////////////////////////////////////
//                    Hochschule Hamm-Lippstadt               //
////////////////////////////////////////////////////////////////
//                                                            //
// Fach             : Angewandte Elektrotechnik               //
//                                                            //
// Autoren          : Jan Henrik Steltenkamp                  //
//                    Orience Charnelle Mefenya               //
//                                                            //
// Beschreibung     : Dieses Programm nutzt ein Mikrofon,     //
//                    um aus dem Umgebungsgeräusch wahlweise  //
//                    die Tonhöhe in Hz und die Lautstärke    //
//                    zu ermitteln und diese via LEDs und     //
//                    auf einem LCD Display auszugeben        //
//                                                            //
// Letzte Änderung  : 03.01.2021                              //
//                                                            //
////////////////////////////////////////////////////////////////


#include <Wire.h>                         // Bibliothek für Display
#include <LiquidCrystal_I2C.h>            // Bibliothek für Display
LiquidCrystal_I2C lcd(0x27, 16, 2);       // Verwendetes Display: 16 Zeichen, 2 Zeilen, Hex Adresse 27

#define STATE1 1    // Zustand 1 angelegt
#define STATE2 2    // Zustand 2 angelegt
#define STATE3 3    // Zustand 3 angelegt
#define STATE4 4    // Zustand 4 angelegt

int taster = 7;         // Variable für den Taster am Pin 7
int tasterstatus = 0;   // initial wird Taster nicht gedrückt
char state = STATE1;    // STATE1 als Startzustand festgelegt

int Ton_aus_Skala;        // Variable für den jeweiligen Skalenton angelegt
signed int tondifferenz;  // Variable für die differenz zwischen Messung und Skalenton angelegt
int frequenz;             // Variable für schlussendliche Tonfrequenz

int ls_messwert;        // hier werden die Lautstärke Messwerte gespeichert
int ls_differenz;       // Differenz zum Referenzwert 200 gebildet
int counter = 0;        // Counter für Arraybefüllung
int ls_wertearray[100]; // Array mit Indizes von 0 bis 99 erstellt
int ls_maximalwert = 0; // maximaler Lautstärkewert des Arrays

double doublemaximum;       // maximaler Lautstärkewert in als double
double ls_dbwert;           // auf dezibel umgerechneter Wert
double ls_dbwert_korrektur; // Anpassung der Werte gemäß Kalibrierung
int dezibel;                // Variable für schlussendliche Lautstärke

#include "arduinoFFT.h"           // Hier wird die FFT Bibliothek eingebunden
#define SAMPLES 128               // SAMPLES-pt FFT. Muss eine Zahl aus dem Dualsystem sein. Für Arduino Uno maximal 128
#define SAMPLING_FREQUENCY 2048   // Basierend auf der Nyquist Frequenz muss der Wert mindestens 2 mal so hoch sein, wie die gemessenen Frequenzen
arduinoFFT FFT = arduinoFFT();    // Aufruf der FFT Funktion
unsigned int samplingPeriod;      // Periodendauer der Messungen

Setup

Setup: Stand 03.01.2021
void setup() 
void setup() 
{
    Serial.begin(115200);                                     //Datenübertragungsrate für den seriellen Monitor
    samplingPeriod = round(1000000*(1.0/SAMPLING_FREQUENCY)); //Periodendauer der Messungen in Mikrosekunden
    
    pinMode(taster, INPUT); // Der Pin7 mit dem Taster als Eingang festgelegt

    pinMode(8,OUTPUT);      // Pin 8: rote LED zu tief
    pinMode(9,OUTPUT);      // Pin 9: gelbe LED zu tief
    pinMode(10,OUTPUT);     // Pin 10: grüne LED
    pinMode(11,OUTPUT);     // Pin 11: gelbe LED zu hoch
    pinMode(12,OUTPUT);     // Pin 12: rote LED zu hoch

    lcd.init();             // LCD wird gestartet
    lcd.backlight();        // Hintergrundbeleuchtung wird eingeschaltet    
}

zyklische Werteermittlung von Frequenz und Lautstärke

zyklische Werteermittlung von Frequenz und Lautstärke: Stand 03.01.2021
void loop() 
{  

tasterstatus = digitalRead(taster); // Pin7 wird ausgelesen und als "HIGH" für 5V oder "LOW" für 0V gespeichert

////////////////// Beginn der Frequenzmessung
 if (state == STATE1) // nur ausführen, wenn State 1 aktiv ist
{

unsigned long microSeconds;
double vReal[SAMPLES]; // Vektor der Größe 128 für reelle Werte erstellt
double vImag[SAMPLES]; // Vektor der Größe 128 für imaginäre Werte erstellt
      
      /*Sample SAMPLES times*/
      for(int i=0; i<SAMPLES; i++)    // Schleife über 128 Werte
      {
          microSeconds = micros();    // Ausgabe der Mikrosekunden 
          
          vReal[i] = analogRead(0);   // Pin 0 wird ausgelesen und der Wert als reeller Wert im Array gespeichert
          vImag[i] = 0;               // imaginärer Wert wird als 0 abgespeichert
          
          /*remaining wait time between samples if necessary*/
          while(micros() < (microSeconds + samplingPeriod)) // Warten, bis Zeitpunkt für neuen Wert erreicht ist
          {
            //do nothing
          }
      }
      
      /*Perform FFT on samples*/
      FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);  // Ausführung der FFT
      FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);                  // Ausführung der FFT
      FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);                    // Ausführung der FFT
      
      /*dominanteste Frequenz ermitteln*/
      double frequenzspitze = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);        // Frequenz ermitteln

      double frequenzkorrektur = frequenzspitze - (0.02578 * frequenzspitze - 1.28939); // Korrektur des Messwertes gemäß Kalibrierung
      frequenz = round(frequenzkorrektur);   // Frequenzwert gerundet
}
////////////////// Ende der Frequenzmessung

////////////////// Beginn der Lautstärkemessung
 if (state == STATE3) // nur ausführen, wenn State 3 aktiv ist
  {
  ls_messwert = analogRead(0);            // Analog Eingang Pin 0 ausgelesen, Referenzwert ist 200 bei Stille
  ls_differenz = abs(ls_messwert - 200);  // vorzeichenlose Differenz zu dem Referenzwert gebildet

  ls_wertearray[counter] = ls_differenz;  // an die aktuelle Stelle im Array neuen Wert eintragen
  
  counter ++;                   // Counter hoch setzen
  
    if (counter == 100)         // Wenn das Array voll läuft...
      {
      counter = 0;              // Setze den Counter wieder auf null
      ls_maximalwert = 0;       // setze den Maximalwert wieder auf null
      for (int i=0; i<99; i++)  // gehe durch das gesamte 100er Array, von Stelle 0 bis 99
        {
        ls_maximalwert = max(ls_wertearray[i],ls_maximalwert); // ermittle den neuen Maximalwert des Lautstärkemesswertes
        }

      doublemaximum = (double)ls_maximalwert;         // Maximalwert in Double umgewandelt
      ls_dbwert = 14.4545*log(12.6859*doublemaximum); // Maximalwert in Dezibel Wert umgerechnet
   
      ls_dbwert_korrektur = ls_dbwert - (0.02110 * ls_dbwert * ls_dbwert - 3.39901 * ls_dbwert + 135.777); // Korrektur des Messwertes gemäß Kalibrierung
      dezibel = round(ls_dbwert_korrektur);           //dezibelwert gerundet
      }   
 }
////////////////// Ende der Lautstärkemessung    

Zustandsautomat zur Verwaltung der Ausgaben

Zustandsautomat zur Verwaltung der Ausgaben: Stand 03.01.2021
   switch(state) //Zustandsautomat, Zustand 1 = Stimmerät, Zustand 3 = Lautstärkemesser
    {
      case STATE1:    //Zustand 1: Stimmgerät     
        if(frequenz < 96)                           // Ton E2, 82Hz
        {
        Ton_aus_Skala = 82;                         // Referenzton hat 82Hz
        tondifferenz = Ton_aus_Skala - frequenz;    // berechne Abweichung    
          if(tondifferenz < -15)                                  // wenn Frequenz viel zu hoch
            {
            digitalWrite(12, HIGH);                               // schalte rote LED an
            }
          else if((tondifferenz >= -15) & (tondifferenz < -8))    // wenn Frequenz ein bischen zu hoch
            {
            digitalWrite(11, HIGH);                               // schalte gelbe LED an
            }
          else if((tondifferenz >= -8) & (tondifferenz <= 8))     // wenn Frequenz passend
            {
            digitalWrite(10, HIGH);                               // schalte grüne LED an
            }
          else if ((tondifferenz > 8) & (tondifferenz <= 15))     // wenn Frequenz ein bischen zu tief
            {
            digitalWrite(9, HIGH);                                // schalte gelbe LED an
            } 
          else if (tondifferenz > 15)                             // wenn Frequenz viel zu tief
            {
            digitalWrite(8, HIGH);                                // schalte rote LED an
            }       
        lcd.setCursor(0, 0);            // Erste Zeile des LCD Displays ansprechen
        lcd.print("                ");  // vorherige Anzeige löschen
        lcd.setCursor(0, 0);            //zugeordneten Ton in 1. Zeile anzeigen
        lcd.print("Ton e =  82  Hz");   //zugeordneten Ton in 1. Zeile anzeigen
        }
        
        else if((frequenz > 97) & (frequenz < 128)) //Ton A2, 110Hz
        {
        Ton_aus_Skala = 110;                        //Referenzton hat 110Hz
        tondifferenz = Ton_aus_Skala - frequenz;    //berechne Abweichung
          if(tondifferenz < -15)                                  // wenn Frequenz viel zu hoch
            {
            digitalWrite(12, HIGH);                               // schalte rote LED an
            }
          else if((tondifferenz >= -15) & (tondifferenz < -8))    // wenn Frequenz ein bischen zu hoch
            {
            digitalWrite(11, HIGH);                               // schalte gelbe LED an
            }
          else if((tondifferenz >= -8) & (tondifferenz <= 8))     // wenn Frequenz passend
            {
            digitalWrite(10, HIGH);                               // schalte grüne LED an
            }
          else if ((tondifferenz > 8) & (tondifferenz <= 15))     // wenn Frequenz ein bischen zu tief
            {
            digitalWrite(9, HIGH);                                // schalte gelbe LED an
            } 
          else if (tondifferenz > 15)                             // wenn Frequenz viel zu tief
            {
            digitalWrite(8, HIGH);                                // schalte rote LED an
            }      
        lcd.setCursor(0, 0);            // Erste Zeile des LCD Displays ansprechen
        lcd.print("                ");  // vorherige Anzeige löschen
        lcd.setCursor(0, 0);            //zugeordneten Ton in 1. Zeile anzeigen
        lcd.print("Ton A =  110 Hz");    //zugeordneten Ton in 1. Zeile anzeigen
        }
        
        else if((frequenz > 128) & (frequenz < 171)) //Ton D3, 147Hz
        {
        Ton_aus_Skala = 147;                         //Referenzton hat 147Hz
        tondifferenz = Ton_aus_Skala - frequenz;  //berechne Abweichung
          if(tondifferenz < -15)                                  // wenn Frequenz viel zu hoch
            {
            digitalWrite(12, HIGH);                               // schalte rote LED an
            }
          else if((tondifferenz >= -15) & (tondifferenz < -8))    // wenn Frequenz ein bischen zu hoch
            {
            digitalWrite(11, HIGH);                               // schalte gelbe LED an
            }
          else if((tondifferenz >= -8) & (tondifferenz <= 8))     // wenn Frequenz passend
            {
            digitalWrite(10, HIGH);                               // schalte grüne LED an
            }
          else if ((tondifferenz > 8) & (tondifferenz <= 15))     // wenn Frequenz ein bischen zu tief
            {
            digitalWrite(9, HIGH);                                // schalte gelbe LED an
            } 
          else if (tondifferenz > 15)                             // wenn Frequenz viel zu tief
            {
            digitalWrite(8, HIGH);                                // schalte rote LED an
            }      
        lcd.setCursor(0, 0);            // Erste Zeile des LCD Displays ansprechen
        lcd.print("                ");  // vorherige Anzeige löschen
        lcd.setCursor(0, 0);            //zugeordneten Ton in 1. Zeile anzeigen
        lcd.print("Ton D =  147 Hz");    //zugeordneten Ton in 1. Zeile anzeigen
        }
        
        else if((frequenz > 171) & (frequenz < 221)) //Ton G3, 196Hz
        {
        Ton_aus_Skala = 196;                         //Referenzton hat 196Hz
        tondifferenz = Ton_aus_Skala - frequenz;   //berechne Abweichung
          if(tondifferenz < -15)                                  // wenn Frequenz viel zu hoch
            {
            digitalWrite(12, HIGH);                               // schalte rote LED an
            }
          else if((tondifferenz >= -15) & (tondifferenz < -8))    // wenn Frequenz ein bischen zu hoch
            {
            digitalWrite(11, HIGH);                               // schalte gelbe LED an
            }
          else if((tondifferenz >= -8) & (tondifferenz <= 8))     // wenn Frequenz passend
            {
            digitalWrite(10, HIGH);                               // schalte grüne LED an
            }
          else if ((tondifferenz > 8) & (tondifferenz <= 15))     // wenn Frequenz ein bischen zu tief
            {
            digitalWrite(9, HIGH);                                // schalte gelbe LED an
            } 
          else if (tondifferenz > 15)                             // wenn Frequenz viel zu tief
            {
            digitalWrite(8, HIGH);                                // schalte rote LED an
            }      
        lcd.setCursor(0, 0);            // Erste Zeile des LCD Displays ansprechen
        lcd.print("                ");  // vorherige Anzeige löschen
        lcd.setCursor(0, 0);            //zugeordneten Ton in 1. Zeile anzeigen
        lcd.print("Ton G =  196 Hz");    //zugeordneten Ton in 1. Zeile anzeigen
        }
        
        else if((frequenz > 221) & (frequenz < 288)) //Ton H3, 247Hz
        {
        Ton_aus_Skala = 247;                         //Referenzton hat 247Hz
        tondifferenz = Ton_aus_Skala - frequenz;  //berechne Abweichung
          if(tondifferenz < -15)                                  // wenn Frequenz viel zu hoch
            {
            digitalWrite(12, HIGH);                               // schalte rote LED an
            }
          else if((tondifferenz >= -15) & (tondifferenz < -8))    // wenn Frequenz ein bischen zu hoch
            {
            digitalWrite(11, HIGH);                               // schalte gelbe LED an
            }
          else if((tondifferenz >= -8) & (tondifferenz <= 8))     // wenn Frequenz passend
            {
            digitalWrite(10, HIGH);                               // schalte grüne LED an
            }
          else if ((tondifferenz > 8) & (tondifferenz <= 15))     // wenn Frequenz ein bischen zu tief
            {
            digitalWrite(9, HIGH);                                // schalte gelbe LED an
            } 
          else if (tondifferenz > 15)                             // wenn Frequenz viel zu tief
            {
            digitalWrite(8, HIGH);                                // schalte rote LED an
            }      
        lcd.setCursor(0, 0);            // Erste Zeile des LCD Displays ansprechen
        lcd.print("                ");  // vorherige Anzeige löschen
        lcd.setCursor(0, 0);            //zugeordneten Ton in 1. Zeile anzeigen
        lcd.print("Ton H =  247 Hz");    //zugeordneten Ton in 1. Zeile anzeigen
        }
        
        else if(frequenz > 288)                      //Ton E4, 330Hz
        {
        Ton_aus_Skala = 330;                         //Referenzton hat 330Hz
        tondifferenz = Ton_aus_Skala - frequenz;  //berechne Abweichung
          if(tondifferenz < -15)                                  // wenn Frequenz viel zu hoch
            {
            digitalWrite(12, HIGH);                               // schalte rote LED an
            }
          else if((tondifferenz >= -15) & (tondifferenz < -8))    // wenn Frequenz ein bischen zu hoch
            {
            digitalWrite(11, HIGH);                               // schalte gelbe LED an
            }
          else if((tondifferenz >= -8) & (tondifferenz <= 8))     // wenn Frequenz passend
            {
            digitalWrite(10, HIGH);                               // schalte grüne LED an
            }
          else if ((tondifferenz > 8) & (tondifferenz <= 15))     // wenn Frequenz ein bischen zu tief
            {
            digitalWrite(9, HIGH);                                // schalte gelbe LED an
            } 
          else if (tondifferenz > 15)                             // wenn Frequenz viel zu tief
            {
            digitalWrite(8, HIGH);                                // schalte rote LED an
            }      
        lcd.setCursor(0, 0);            // Erste Zeile des LCD Displays ansprechen
        lcd.print("                ");  // vorherige Anzeige löschen
        lcd.setCursor(0, 0);            //zugeordneten Ton in 1. Zeile anzeigen
        lcd.print("Ton E =  330 Hz");    //zugeordneten Ton in 1. Zeile anzeigen
        }
        
        lcd.setCursor(0, 1);            // Zweite Zeile des LCD Displays ansprechen
        lcd.print("                ");  // vorherige Anzeige löschen
        lcd.setCursor(0, 1);            // Zweite Zeile des LCD Displays ansprechen
        lcd.print("aktuell: ");         // Text anzeigen           
        lcd.setCursor(9, 1);            // Zweite Zeile des LCD Displays ansprechen
        lcd.print(frequenz);            // Gemessene Frequenz anzeigen
        lcd.setCursor(13, 1);           // Zweite Zeile des LCD Displays ansprechen
        lcd.print("Hz");                // Text anzeigen   
        delay(1000);                    // nächsten Wert nach 1 Sekunde holen und ausgeben
        digitalWrite(12, LOW);  //schalte LED aus
        digitalWrite(11, LOW);  //schalte LED aus
        digitalWrite(10, LOW);  //schalte LED aus
        digitalWrite(9, LOW);   //schalte LED aus        
        digitalWrite(8, LOW);   //schalte LED aus
   
      if(tasterstatus==HIGH)//Abfrage, ob Taster gerade gedrück wird
      {
      state = STATE2; //Wechsle in den Zustand 2
      }
      break;

      case STATE2:    //Zustand 2: Übergang von Stimmgerät zu Lautstärkemesser
      lcd.setCursor(0, 0);
      lcd.print("                ");              // Bildschirm leeren
      lcd.setCursor(0, 1);
      lcd.print("Lautstaerke                ");   // Umschaltvorgang anzeigen
      if(tasterstatus==LOW)//Abfrage, ob Taster gerade losgelassen wird
      {
      state = STATE3; //Wechsle in den Zustand 3
      }
      break;

      case STATE3:    //Zustand 3: Lautstärkemesser
        if (counter == 0) // Wenn die Lautstärkemessung einmal durchgelaufen ist...
          {   
          lcd.setCursor(0, 0);            // Erste Zeile des LCD Displays ansprechen
          lcd.print("                ");  // vorherige Anzeige löschen
          lcd.setCursor(0, 1);            // Zweite Zeile des LCD Displays ansprechen
          lcd.print("                ");  // vorherige Anzeige löschen
          lcd.setCursor(0, 0);            // Text ausgeben
          lcd.print("Schalldruck");       // Text ausgeben
          lcd.setCursor(12, 0);           // Lautstärke in db anzeigen
          lcd.print(dezibel);             // Lautstärke in db anzeigen
          lcd.setCursor(14, 0);           // Text ausgeben
          lcd.print("db");                // Text ausgeben
          lcd.setCursor(0, 1);            // Text ausgeben
          lcd.print("Gefahr: ");          // Text ausgeben
        
          if(dezibel < 70)                          // Wenn die Lautstärkebelastung gering ist
            {
            digitalWrite(10, HIGH);                 // schalte grüne LED an
            lcd.setCursor(8, 1);                    // Text ausgeben
            lcd.print("gering");                    // Text ausgeben
            }
          else if((dezibel >= 70) & (dezibel < 80)) // Wenn die Lautstärkebelastung mittel ist
            {
            digitalWrite(9, HIGH);                  // schalte beide gelben LEDs an
            digitalWrite(11, HIGH);                 // schalte beide gelben LEDs an
            lcd.setCursor(8, 1);                    // Text ausgeben
            lcd.print("mittel");                    // Text ausgeben
            }
          else if(dezibel >= 80)                    // Wenn die Lautstärkebelastung hoch ist
            {
            digitalWrite(8, HIGH);                  // schalte beide roten LEDs an
            digitalWrite(12, HIGH);                 // schalte beide roten LEDs an
            lcd.setCursor(8, 1);                    // Text ausgeben
            lcd.print("hoch");                      // Text ausgeben       
            } 
          delay(1000);            // nächsten Wert nach 1 Sekunde holen und ausgeben      
          digitalWrite(12, LOW);  //schalte LED aus
          digitalWrite(11, LOW);  //schalte LED aus
          digitalWrite(10, LOW);  //schalte LED aus
          digitalWrite(9, LOW);   //schalte LED aus        
          digitalWrite(8, LOW);   //schalte LED aus
    }

      if(tasterstatus==HIGH)//Abfrage, ob Taster gerade gedrück wird
      {
      state = STATE4; //Wechsle in den Zustand 4
      }
      break;

      case STATE4:    //Zustand 4: Übergang von Lautstärkemesser zu Stimmgerät
      lcd.setCursor(0, 0);
      lcd.print("                ");              // Bildschirm leeren
      lcd.setCursor(0, 1);
      lcd.print("Stimmgeraet                ");   // Umschaltvorgang anzeigen
      if(tasterstatus==LOW)//Abfrage, ob Taster gerade losgelassen wird
      {
      state = STATE1; //Wechsle in den Zustand 1
      }
      break;  
    }
}

Aufbau

Vorstellung des verwendeten Sensors

Die Umsetzung des Projektes basiert auf der Verwendung eines Sensors in Form eines Mikrofons. Das Mikrofon wandelt hierzu die im Raum anliegenden Schallwellen in ein elektrisches Signal um. Das Prinzip ist dabei genau umgekehrt zu einem Lautsprecher. Die Schallwellen führen zu einer Bewegung der Membran an dem Mikrofon. Diese Bewegung wird auf eine Relativbewegung von einer Spule und einem Permanentmagneten übertragen. Durch diese Bewegung ändert sich der Widerstand der Spule stetig, welcher in Form einer Spannung als Ausgangssignal ausgegeben wird. Die Messschaltung ist daher eine einfache Widerstandmessung des veränderbaren Widerstandes des Mikrofons. Der verwendete Sensor in in Abb. 6 dargestellt. Die Mebran des Mikrofons befindet sich im rechten Bereich des Sensors. Zusätzlich lässt sich der Arbeitspunkt des Sensors über ein Potentiometer (blau) mechanisch einstellen.

Abb. 6: verwendeter Sensor


Stückliste

In der Stückliste werden die für das Projekt verwendeten Teile aufgelistet. Einige Teile wurde dazu aus dem Funduino Starter Kit entnommen.

Tabelle 4: Stückliste
ID Anzahl Bezeichnung technische Informationen Kosten Link
01 1x Arduino Uno (Funduino Starter Kit) / 48,55€ https://www.funduinoshop.com/UHL
02 1x I^2C LCD Display (Funduino Starter Kit) / / /
03 1x Taster klein (Funduino Starter Kit) / / /
04 1x LED grün (Funduino Starter Kit) 3,7V Betriebsspannung / /
05 1x LED gelb (Funduino Starter Kit) 2,2V Betriebsspannung / /
06 1x LED rot (Funduino Starter Kit) 2,1V Betriebsspannung / /
07 1x Widerstand (Funduino Starter Kit) 100Ω / /
08 4x Widerstand (Funduino Starter Kit) 200Ω / /
09 1x Widerstand (Funduino Starter Kit) 1kΩ / /
10 1x Iduino ST1146 Geräusch-Sensor-Modul / 11,44€ https://www.conrad.de/de/p/iduino-1485297-mikrofon-schallsensor-1-st-1485297.html
11 1x Akozon Junction Box, Water-Resistant IP65 ABS Project Enclosure Case Wiring Junction Box 200 x 120 x 56mm 19,99€ https://www.amazon.de/gp/product/B07F9V2ZGG/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
12 1x 9V-Batteriehalter mit Schalter und Stecker / 19,43€ https://www.generationrobots.com/de/403639-9v-batteriehalter-mit-schalter-und-stecker-arduino-kompatibel.html

Verkabelungsplan

In der nächsten Abbildung (Abb. 7) wird der Verkabelungsplan dargestellt. Dieser Plan wurde mit der Software Fritzing erstellt. Zu sehen sind die verwendeten Bauelemente, der Schallsensor (Abbildung weicht von dem verwendeten Sensor ab) und das 2X16 LCD Display (Abbildung weicht von dem verwendeten Display ab). Die dargestellten Linien zeigen, welche Anschlüsse elektrisch miteinander verbunden wurden und um welche Art Verbindung es sich handelt. Die Anschlüsse zur Versorgungsspannung VCC werden rot dargestellt, Anschlüsse zu Ground sind blau eingezeichnet. Leitungen, die der Signalübertragung dienen, werden gelb dargestellt. Die Verkabelungsplan Datei ist unter folgendem Link im SVN verfügbar.


Abb. 7: Fritzing Verkabelungsplan


Schaltplan

Die folgende Abbildung zeigt den Schaltplan des Stimmgerätes, welcher mit dem Programm NI Multisim erstellt wurde. Es ist zu beachten, dass im Falle des Displays und des Mikrofones keine passenden Vorlagen vorhanden waren. Daher wurden an dieser Stelle die in dem Programm verfügbaren Elemente verwendet und mit den verfügbaren Anschlüssen verbunden. Die Schaltplan Datei ist unter folgendem Link im SVN verfügbar.


Abb. 8: Schaltplan


Gehäuse

Nachdem die grundsätzliche Funktionsweise und auch der Verkabelungsplan festgelegt wurde, ist mit dem Planen des Gehäuses des Stimmgerätes begonnen worden. Grundlage für das Gehäuse war, dass der Arduino Uno, das Breadboard, das Mikrofon und das LCD Display mitsamt Taster und LEDs in das Gehäuse integriert werden sollten.

Für diesen Zweck wurde ein Modell des Gehäuses bei SolidWorks erstellt, mit der Absicht, dieses später in der Projektwerkstatt der HSHL an einem 3D Drucker fertigen zu lassen. Das geplante Gehäuse besteht dabei aus einer einfachen Kiste, die mit einem Deckel verschlossen werden soll. Für das Display, die LEDs und den Taster wurden entsprechende Aussparungen eingeplant.

Die seitliche Öffnung an der Kiste, die für das runde Mikrofon vorhergesehen ist, sollte nach dem Drucken per Bohrprozess eingebracht werden, um eine ausreichende Rundheit der Bohrung zu gewährleisten. Das gleiche gilt für das Kabel der Stromversorgung, welches aus der Box heraus zu dem angebrachten Schalter führen soll, um das Stimmgerät von außen an- und ausschalten zu können. Die Gehäuse Datei ist unter folgendem Link im SVN verfügbar.


Die angefertigten SolidWorks Dateien werden im Folgenden dargestellt:

Abb. 9: Aufbau des Gehäuses


Einbau des Projektes

Die Rücksprache mit dem zuständigen wissenschaftlichen Mitarbeiter der HSHL hat ergeben, dass das Drucken des geplanten Gehäuses mit den verfügbaren Druckern nur schwierig und unter enormen Zeitaufwand umzusetzen sei. Daher wurde an dieser Stelle auf ein Universalgehäuse aus Kunststoff zurückgegriffen, in welches später die benötigten Öffnungen der einzelnen Komponenten des Stimmgerätes eingebracht wurden[6]. In der folgenden Abbildung ist die Innenansicht des fertig zusammengebauten Projektes zu sehen.

Abb. 10: Innenansicht des Stimmgerätes


Wie in der Abbildung dargestellt, wurden die für das Projekt verwendeten Komponenten in die nachträglich eingebrachten Öffnungen integriert. Diese wurden dann über das Breadboard und dem Arduino Uno angeschlossen. Die schlussendliche Außenansicht des Projektes wird in Abb. 11 gezeigt.

Abb. 11: Außenansicht des Stimmgerätes


Auf der Oberseite des Gehäuses befinden sich der Funktions-Taster, die Anzeige LEDs sowie das LCD Display zur Anzeige der Messwerte. Seitlich links wurde ein Batterie-Schalter angebracht, um das Gerät mobil einsetzen zu können. Seitlich rechts ist die Öffnung für das Mikrofon eingelassen, um die Frequenz- und Lautstärkemessungen zu ermöglichen.

Komponententest

Nach Fertigstellung der einzelnen Softwarekomponenten "Frequenzmessung" und "Lautstärkemessung" wurden diese auf ihre Funktion überprüft. Dieser Schritt wird in den nachfolgenden Abschnitten für die beiden Komponenten einzeln aufgeführt.

Frequenzmessung

Nachdem der Programmcode für die Softwarekomponente "Frequenzmessung" erstellt wurde und das Messgerät testweise auf einem Breadboard aufgebaut wurde (Siehe Fritzing Plan in Abb. 7), ist die Frequenzmessung überprüft worden. Dazu wurde zunächst ein Programm heruntergeladen, welches auf dem Mobiltelefon ermöglicht, Geräusche in Form von Sinuskurven mit definierter Schallfrequenz auszugeben. Die Überprüfung der vom Mobiltelefon ausgegebenen Schallfrequenz mit einem handelsüblichen Stimmgerät für Gitarren hat ergeben, dass keine relevante Abweichung der eingestellten Frequenzwerte von der ausgegebenen Schallfrequenz zu beobachten waren.

Somit wurde die anschließende Kalibrierung des selbst erstellten Stimmgerätes mit diesem Programm durchgeführt.

Dabei wurde, beginnend mit einer Frequenz von 400Hz, die entsprechende Schallfrequenz erzeugt über das Arduino Mikrofon eingelesen. Der auf dem Bildschirm ausgegebene Frequenzwert wurde dann notiert und die Frequenz um 10Hz verringert.

Dieser Versuch hat ergeben, dass bei dem bisherigen Programmcode eine systematische Messabweichung vorliegt, welche mit höher werdender Schallfrequenz entsprechend ansteigt. Die Messabweichung wurde linearisiert und anschließend in dem Programmcode von dem Messwerten abgezogen.

Die ursprüngliche Messgenauigkeit und die Messgenauigkeit nach der Anpassung des Programmcodes werden in folgender Abbildung dargestellt. Die zugrundeliegende Excel Datei ist unter folgendem Link im SVN verfügbar.


Abb. 12 : Kalibrierung der Frequenzmessung


Die rote Kurve zeigt die ursprünglichen Messwerte. Die Messwerte nach der Anpassung sind blau eingefärbt.

Wie zu sehen ist, konnte das "Abdriften" der Messwerte beseitigt werden. Die restliche Abweichungen bei dem Messen der Schallfrequenz ist für die Anwendung des Stimmgerätes von zu vernachlässigender Bedeutung.

Allerdings hat die Messung auch Grenzen der Messung aufgezeigt. In unteren Bereichen der Schallfrequenz, besonders ab ca. 60Hz abwärts, neigt das Stimmgerät zu starken Schwankungen bei der Ausgabe. Da der tiefste Ton, der erfolgreich gemessen werden soll, oberhalb von diesem Bereich liegt, ist die Schwankung bei besonders tiefen Frequenzen nicht kritisch für die Funktionalität des Stimmgerätes.

Die Frequenzmessung hat somit eine Genauigkeit erreicht, die für dieses Projekt als ausreichend zu bewertend ist.

Lautstärkemessung

Nach der Fertigstellung des Programmcodes der Softwarekomponente "Schallmessung" wurden die Messungen in ähnlicher Weise überprüft. Auch hier wurde als Referenz ein Programm auf einem Mobiltelefon verwendet. Dieses Programm zeigte die Lautstärke in Dezibel an. Also genau jene Funktion, die Ziel der Programmierung war. Die Genauigkeit der Messung des Mobiltelefons konnte an dieser Stelle nicht durch ein zusätzliches Gerät überprüft werden, da kein Referenzgerät zur Lautstärkemessung in Dezibel verfügbar war.

Die Messwerte des selbst erstellten Stimmgerätes wurden daher mit denen des Mobiltelefon Programms bei verschiedenen Lautstärken verglichen. Für die Messung der Lautstärke wurde ein konstanter Ton in unterschiedlich lauten Stufen abgespielt.

Begonnen wurde mit einer Lautstärke, die auf dem Mobiltelefon konstant 50db angezeigt hat. Der auf dem Bildschirm ausgegebene Lautstärkewert wurde notiert und anschließend wurde die Lautstärke um jeweils 5db erhöht.

Nach der Messung wurde versucht, die sich ergebene Messabweichung durch eine quadratische Funktion abzubilden und von den Messwerten abzuziehen. Dazu wurde wieder der Programmcode entsprechend angepasst.

Die ursprüngliche Messabweichung und die Messabweichung nach der Anpassung des Programmcodes werden in folgender Abbildung dargestellt. Die zugrundeliegende Excel Datei ist unter folgendem Link verfügbar.

Abb. 13 : Kalibrierung der Schallmessung


Die rote Kurve zeigt die ursprünglichen Messwerte. Die Messwerte nach der Anpassung sind blau eingefärbt.

Durch die Korrektur der Messabweichung konnte das Messergebnis in den unteren Messbereichen von 55db bis 65db verringert werden. In den oberen Bereichen hat sich die Messabweichung allerdings dadurch ein wenig erhöht.

Es hat sich durch diesen Komponententest allerdings auch gezeigt, dass eine Lautstärkemessung bei niedriger Lautstärke nicht sinnvoll ist, da das eingesetzte Mikrofon offensichtlich über eine zu geringe Sensitivität verfügt. Erst oberhalb von 55db stiegen die Messwerte konstant mit höher werdender Lautstärke an. Dementsprechend hoch ist die Messabweichung im unteren Dezibel-Bereich. Daher ist generell zu sagen, dass sich das Gerät eher zur Messung von größeren Lautstärken ab ca. 55db eignet.

Für Messungen bei besonders hohen Laustärken hat sich das Gerät aber als relativ zuverlässig rausgestellt, auch wenn eine gewisse Messabweichung vorliegt. Somit kann das Gerät genutzt werden, um den Anwender vor zu hohen Lautstärken zu warnen, die unter Umständen eine Beeinträchtigung des Hörvermögens hervorrufen würden.

Überprüfung der formulierten Anforderungen

Zur Kontrolle, ob die eingangs aufgestellten Anforderungen erreicht wurden, werden diese in der nachfolgenden Tabelle aufgeführt und auf Erfüllung überprüft.

Tabelle 5: Überprüfung der formulierten Anforderungen
ID Anforderung Anforderung erreicht? Details
01 Das Gerät muss ein Schallsensor besitzen. ja Bestellter Mikrofon Sensor ist in Stückliste aufgeführt.
02 Der Schallsensor muss die Schwingungen bzw. den Schall im Raum messen. ja Ausgabe des Messsignals von dem Sensor an den Arduino konnte umgesetzt werden.
03 Das Signal des Sensors muss auf die Frequenzen und die Amplituden aufgeteilt werden. ja Signal wird nicht konkret aufgeteilt, sondern es wird auf das abgespeicherte Signal für die beiden Softwarefunktionen zurückgegriffen.
04 Die Frequenz mit dem größten Anteil an den Schwingungen muss ermittelt werden. ja Die Frequenzermittlung konnte umgesetzt werden.
05 Die größte gesessene Lautstärke muss ermittelt werden. ja Die Laustärkeermittlung konnte umgesetzt werden.
06 Die im Raum vorherrschende Frequenz und die Lautstärke muss auf dem Bildschirm angezeigt werden. ja Die errechneten Frequenz- und Laustärkewerte werden zyklisch im Sekundentakt an das Display ausgegeben.
07 Sollte die Frequenz zu niedrig oder zu hoch liegen, muss dies per LED angezeigt werden. ja Der aktuelle Frequenzwert wird jeweils mit dem nächstgelegenen Referenzwert verglichen. Der Unterschied zwischen den beiden Werten wird über die Farbe der jeweils leuchtenden LED visualisiert.
08 Das Gerät muss in einem tragbaren Gehäuse verbaut werden. ja Der prototypenartige Aufbau konnte komplett in ein dafür angeschaffenes Universalgehäuse eingebaut werden, welches den mobilen Einsatz ermöglicht.
09 Das Gerät muss über eine mobile Stromversorgung verfügen. ja Der angeschaffte Batterieschalter ermöglicht die mobile Stromversorgung und das An- und Ausschalten des Gerätes.

Zusammenfassung

Insgesamt ist die Umsetzung des Projektes "Stimmgerät" mit seinen zwei Hauptfunktionen Frequenzmessung und Laustärkemessung gelungen. Allerdings konnte dabei keine modellbasierte Programmierung mit Matlab Simulink verwendet werden. Daher ist diese Aufgabenstellung nicht direkt auf andere Programmiersprachen übertragbar, da die Lösung mit C Code in der Arduino IDE Umgebung erstellt wurde.

Lessons Learned

Während des Verlaufs des Projektes wurde sich immer wieder auf die ursprünglichen Anforderungen bezogen. Gerade die Wichtigkeit der Anfangsphase eines solchen Projektes wird gerne unterschätzt. Die Bearbeitung des Projektes hat aber gezeigt, dass gerade die Anfangsphase einen großen Einfluss auf den Erfolg bzw. den Aufwand eines Projektes haben kann.

Die Herausforderung bei der Programmierung bestand insbesondere darin, eine funktionierende Software zu erstellen, welche die geforderten Funktionen auf dem Arduino umsetzt. Um das Gesamtproblem beherrschbar zu machen, wurden das Gesamtprogramm bei der Erstellung des Codes in mehrere Teilprogramme unterteilt (Einlesen des Mikrofons, Berechnung von Frequenz und Lautstärke, Einlesen des Taster etc.). Diese Vorgehensweise hat sich als hilfreich erwiesen, um die einzelnen Funktionen "Stück für Stück" zu erstellen und anschließend in das vorhandene Gesamtprogramm einzubauen.

Die konkrete Umsetzung der Softwarekomponente Lautstärkemessung zeigt im Vergleich zur Frequenzmessung relativ ungenaue Werte. Bei der Umsetzung wurde dabei derart vorgegangen, dass bei anliegender Stille das Mikrofon einen Spannungswert von 200 an den Arduino ausgibt. Dieser Wert kann durch das Drehen an dem Potentiometer eingestellt werden und verändert sich leicht über die Zeit. Der Einbau des Projektes in ein Gehäuse hat gezeigt, dass diese Lösung nicht optimal ist, da das Gehäuse geöffnet und das Potentiometer erneut eingestellt werden muss, bevor die Lautstärkemessung verwendet werden soll. Eine Softwarelösung, die nicht erfordert, das Potentiometer am Mikrofon nach einiger Zeit neu einzustellen, hätte vermutlich zu einem besserem Ergebnis geführt.

Youtube Video


Literaturverzeichnis



→ zurück zur Übersicht: WS 21/22: Angewandte Elektrotechnik (BSE)