Gymnasium Himmelsthür

P6-Lärmampel

Der Sound-Sensor hat neben der Spannungsversorgung mit +5 Volt und Masse (GND/Ground) noch einen Digital(D0)- und einen Analogausgang(A0) für eine mit der Lautstärke zunehmende Spannung.

Auf dem blauen Gehäuse ist eine Schraube, die über einen Potentiometer die Empfindlichkeit regelt. Mit einem kleinen Schraubendreher kann die Empfindlichkeit angepasst werden.

Digitalausgang

Schaltung

Programm

| laerm1.ino
int sensor = 2;                       //Der Digitalausgang D0 des Sensors wird hier angeschlossen.
int LED = 12;                         //Die LED wird hier angeschlossen.
boolean noise  = false;               //Die Variable speichert den Wert für die Lautstärke (false / true)
                                      //Das ist ein digitaler Wert. Der Vergleichswert wird mit der Schraube
                                      //eingestellt.
void setup() {
 
  Serial.begin(9600);
  pinMode(sensor, INPUT);
  pinMode(LED, OUTPUT);
 
}
 
void loop() {
 
  noise = digitalRead(sensor);        //Lies den Lautstärkewert (0 oder 1) ein.
 
  if (noise == true){                 //Schalte abhängig vom Lautstärkewert die LED ein/aus.
    Serial.println("LÄRM");
    digitalWrite(LED, HIGH);
  }
  else{
    Serial.println("stille");
    digitalWrite(LED, LOW);
  }
}

Passe mit dem Schraubendreher an der Schraube den Wert so an, das die LED gerade noch aus ist. Durch Klatschen sollte die LED kurzzeitig an sein.

Analogausgang

Am Analogausgang wird ein der Lautstärke entsprechender Zahlenwert ausgegeben. Dieser Wert kann durch drehen an der Schraube ebenfalls angepasst werden.

Schaltung

Jetzt wird der Ausgang A0 des Soundsensors mit dem Eingang A0 des Arduino verbunden.

Programm

|laerm_analog.ino
int analog = A0;                      //Der Analogausgang A0 des Sensors wird hier angeschlossen.
int LED = 12;                         //Die LED wird hier angeschlossen.
float lautstaerke = 0;                //Die Variable speichert den Spannungswert für die Lautstärke.
 
void setup() {
 
  Serial.begin(9600);
  pinMode(analog, INPUT);
  pinMode(LED, OUTPUT);
 
}
 
void loop() {
 
  lautstaerke = analogRead(analog);   //Lies den Spannungswert 0..1023 für die Lautstärke ein.
 
  if(lautstaerke > 200){
    Serial.println("LÄRM");
    digitalWrite(LED, HIGH);
  }
  else{
    Serial.println("stille");
    digitalWrite(LED, LOW);
  }
 
  lautstaerke = lautstaerke * 5.0 / 1023.0; //Der Zahlenwert wird in einen Spannungswert konvertiert.
  Serial.print("Lautstärke: ");
  Serial.print(lautstaerke);
  Serial.println(" V");
  delay(200);
}

Lärmampel

Schaltung

Hier wird wieder der Analogausgang A0 des Sound-Sensors verwendet. Außerdem werden 6 Ausgänge des Arduino verwendet. Zeichne eine Schaltskizze und baue die Schaltung so auf, dass das folgende Programm richtig läuft und die Ampel abhängig von der Umgebungslautstärke von grün über die Gelb-Stufen bis rot wechselt.

Programm

| laermampel.ino
// Lärmampel für Breadboard - Basisprogramm
// Alexander Pusch -2018
 
 
 
const int mikrofonPin = A0;         // Pin des Mikrofons am analogen Eingang definieren
 
const int led_rot     = 2;          // PINs an Digital-Ausgängen für die LEDs definieren
const int led_gelb2   = 3;         
const int led_gelb1   = 4;         
const int led_gruen3  = 5;        
const int led_gruen2  = 6;        
const int led_gruen1  = 7;         
 
const float grenze_rot =    3.0;    // Grenzen für Pegelanzeigen mit LEDs festlegen - je kleiner die Abstände, desto sensibler die Anzeige
const float grenze_gelb2 =  2.5;         
const float grenze_gelb1 =  2.0;         
const float grenze_gruen3 = 1.5;        
const float grenze_gruen2 = 1.0;         
 
const float fallrate_pegel = 0.2;   // Wert für den Abfall des Pegels festlegen. Je kleiner, desto langsamer fällt der Pegel
 
float anzeigepegel = 0;             // Erstellen einer Variable für angezeigten Pegelwert der durch die LEDs angezeigt wird
float offset;                       // Erstellen einer Variable für den Offset des Grundsignals am Eingang. Dieser wird vom Programm bestimmt. Alternativ hier z.B. "const float = 330" setzen
float mittelwert;                   // Erstellen einer Variable für den Mittelwert aus den Messungen
float korr_mittelwert = 0;          // Erstellen einer Variable für den um den Offset korrigierter Mittelwert
float ohne_last;                    // Erstellen einer Variable zur Speicherung des Mittelwerts bei Kalibrierung OHNE Last
float mit_last;                     // Erstellen einer Variable zur Speicherung des Mittelwerts bei Kalibrierung MIT Last
 
int w1;                             // Erstellen von Variablen für die "zu-Fuß-Berechnung" des Mittelwertes
int w2;       
int w3;       
int w4;      
int w5;       
 
 
void setup()                              // Diese Befehle werden einmal zu Beginn ausgeführt
{
  Serial.begin(9600);                     // Baudrate für Kommunikation mit serieller Schnittstelle einstellen
 
  ausgaenge_definieren();                 // Funktion zur Definition der PINs der LEDs als Ausgänge aufrufen
 
  offset_kalibrierung_durchfueren();      // Funktion zur Kalibrierung des Sensors aufrufen --> Variable *offset* wird kalibriert
 
  ampelstufen_anzeigen();                 // Status der Grenzen der LEDs auf seriellem Monitor anzeigen
}
 
void loop()                               // Diese Befehle werden als Schleife ausgeführt
{
  schallpegel_messen();                   // Messung des Schallpegels starten und arithmetisch den *mittelwert* sowie um *offset* korrigiertem Mittelwert *korr_mittelwert* bestimmen 
 
  pegelanzeiger_einstellen();             // Pegel für Anzeige der LEDs in Variable *anzeigepegel* anhand *korr_mittelwert* einstellen
 
  aktuellen_status_anzeigen();            // aktuellen Status auf seriellem Monitor ausgeben
 
  pegel_ausgeben();                       // LED-Anzeige ansteuern in Abhängigkeit von der Variable *anzeigepegel*
}
 
 
void mittelwert_bestimmen()               // Bestimmung des arithmeitschen Mittels als Variable *mittelwert* aus 20 Messungen
{ 
  w1 = analogRead(mikrofonPin);           // Analogen Eingang *mikrofonPin* auslesen und in Variable w1 bzw. w2 usw. schreiben
  delay(5);                               // Delay zwischen Messvorgängen für bessere Stabilität  
  w2 = analogRead(mikrofonPin);
  delay(5);     
  w3 = analogRead(mikrofonPin);
  delay(5);       
  w4 = analogRead(mikrofonPin);
  delay(5);       
  w5 = analogRead(mikrofonPin);
 
  mittelwert = (w1 + w2 + w3 + w4 + w5 )/5;                   // arithmetisches Mittel berechnen und in Variable *mittelwert* speichern      
}
 
 
void mittelwert_korrigieren()                                 // Variable *mittelwert* um *offset* zu *korr_mittelwert* ändern
{
  if ( (mittelwert - offset) <= 0) {korr_mittelwert = 0;}     // wenn *mittelwert* minus *offset* kleiner null wäre, wird *korr_mittelwert*gleich 0 gesetz (dadurch wird *korr_mittelwert* nie kleiner 0)
  else {korr_mittelwert = (mittelwert - offset);}             // *korr_mittelwert* nimmt Wert von *mittelwert* minus*offset* an
}
 
 
void schallpegel_messen()                                     // Schallmessung an *mikrofonPin* durch Aufruf der Funktionen mittelwert_bestimmen() und mittelwert_korrigieren();
{
  mittelwert_bestimmen();
  mittelwert_korrigieren();
}
 
 
 
void pegelanzeiger_einstellen()                                                             // Variable *anzeigepegel* in Abhängigkeit von Variable *korr_mittelwert* einstellen bzw. Wert für *fallrate_pegel* vom *anzeigepegel* abziehen
{                                               
  if (korr_mittelwert >= anzeigepegel) { anzeigepegel = korr_mittelwert;}                   // wenn *korr_mittelwert* größer gleich als *anzeigepegel* den *anzeigepegel* anpassen --> *anzeigepegel* steigt
  if (anzeigepegel > fallrate_pegel) {anzeigepegel = anzeigepegel - fallrate_pegel;}        // solange *anzeigepegel* größer als *fallrate_pegel* ist, wird er um *fallrate_pegel* verringert --> wird nie negativ    
  if (anzeigepegel > grenze_rot + fallrate_pegel) {anzeigepegel = grenze_rot;}              // Pegel nach oben hin begrenzen, sonst ist je nach *fallrate_pegel* zu lange rot.
}
 
void pegel_ausgeben()                           // Die LEDs werden in Abhängigkeit von der Variable *anzeigepegel* angesteuert
{                          
  if (anzeigepegel>=grenze_rot) {               // Bei Erreichen von *grenze_rot* 
    Serial.println("LED-Anzeige: *Rot*");     // Meldung ausgeben
    digitalWrite(led_gruen1, HIGH);             // Grün1 anschalten
    digitalWrite(led_gruen2, HIGH);             // Grün2 anschalten
    digitalWrite(led_gruen3, HIGH);             // Grün3 anschalten
    digitalWrite(led_gelb1, HIGH);              // Gelb1 anschalten
    digitalWrite(led_gelb2, HIGH);              // Gelb2 anschalten
    digitalWrite(led_rot, HIGH);                // Rot anschalten
  }
  else if (anzeigepegel>grenze_gelb2){          //Bei Erreichen von *grenze_gelb2* 
    Serial.println("LED-Anzeige: *Gelb2*");           
    digitalWrite(led_gruen1, HIGH);      
    digitalWrite(led_gruen2, HIGH);       
    digitalWrite(led_gruen3, HIGH);       
    digitalWrite(led_gelb1, HIGH);          
    digitalWrite(led_gelb2, HIGH);       
    digitalWrite(led_rot, LOW);                 //Rot ausschalten --> kann jeweils auskommentiert werden, wenn einmal erreichtes rotes Signal nicht mehr erlöschen soll
  }
  else if (anzeigepegel>grenze_gelb1){          //Bei Erreichen von *grenze_gelb1* 
    Serial.println("LED-Anzeige: *Gelb1*");       
    digitalWrite(led_gruen1, HIGH);         
    digitalWrite(led_gruen2, HIGH);        
    digitalWrite(led_gruen3, HIGH);       
    digitalWrite(led_gelb1, HIGH);         
    digitalWrite(led_gelb2, LOW);          
    digitalWrite(led_rot, LOW);            
  }
  else if (anzeigepegel>grenze_gruen3){          //Bei Erreichen von *grenze_grün3* 
    Serial.println("LED-Anzeige: *Grün3*");       
    digitalWrite(led_gruen1, HIGH);        
    digitalWrite(led_gruen2, HIGH);       
    digitalWrite(led_gruen3, HIGH);        
    digitalWrite(led_gelb1, LOW);       
    digitalWrite(led_gelb2, LOW);          
    digitalWrite(led_rot, LOW);           
  }
  else if (anzeigepegel>grenze_gruen2){          //Bei Erreichen von *grenze_grün2* 
    Serial.println("LED-Anzeige: *Grün2*");           
    digitalWrite(led_gruen1, HIGH);        
    digitalWrite(led_gruen2, HIGH);         
    digitalWrite(led_gruen3, LOW);         
    digitalWrite(led_gelb1, LOW);         
    digitalWrite(led_gelb2, LOW);         
    digitalWrite(led_rot, LOW);            
  }
  else {                                         //Bei Erreichen von *grenze_grün1* 
    Serial.println("LED-Anzeige: *Grün1*");            
    digitalWrite(led_gruen1, HIGH);       
    digitalWrite(led_gruen2, LOW);        
    digitalWrite(led_gruen3, LOW);         
    digitalWrite(led_gelb1, LOW);          
    digitalWrite(led_gelb2, LOW);          
    digitalWrite(led_rot, LOW);           
  }
    Serial.println("  ");
    Serial.println("  ");
}
 
void aktuellen_status_anzeigen(){               // Kontrollausgabe der aktuellen Messwerte auf seriellem Monitor
  Serial.print("mittelwert: ");
  Serial.println(mittelwert);
  Serial.print("korr_mittelwert: ");
  Serial.println(korr_mittelwert);
  Serial.print("anzeigepegel: ");
  Serial.println(anzeigepegel);
}
 
void offset_kalibrierung_durchfueren()         // Kalibrierung der Variable *offset*
{         
  Serial.println(" ");
  Serial.print("Beginn der Kalibrierung. Ermittle Kalibrierungswert OHNE Last... ");
  delay (100);
 
  mittelwert_bestimmen();
  ohne_last = mittelwert;                        // Die Mittelwerte können sich unter Last von denen ohne Last unterscheiden. Auf dem seriellen Monitor können diese Kontrolliert werden. Sie sollten sich - wenn - nur um wenige Counts unterscheiden. 
 
  Serial.print("( ");
  Serial.print(ohne_last); 
  Serial.println(" )");
  delay (100);
  Serial.print("Alle LEDs anschalten um Kalibrierungswert UNTER Last zu ermitteln... "); 
  delay (100);
  digitalWrite(led_gruen1, HIGH);
  delay (150);         
  digitalWrite(led_gruen2, HIGH);        
  delay (150);         
  digitalWrite(led_gruen3, HIGH);        
  delay (150);         
  digitalWrite(led_gelb1, HIGH);       
  delay (150);         
  digitalWrite(led_gelb2, HIGH);         
  delay (150);         
  digitalWrite(led_rot, HIGH);         
  delay (2000);
 
  mittelwert_bestimmen();
  mit_last = mittelwert;
 
  Serial.print("( ");
  Serial.print(mit_last); 
  Serial.println(" )");
  digitalWrite(led_rot, LOW); 
  delay (150); 
  digitalWrite(led_gelb2, LOW);    
  delay (150); 
  digitalWrite(led_gelb1, LOW);
  delay (150);   
  digitalWrite(led_gruen3, LOW);
  delay (150);       
  digitalWrite(led_gruen2, LOW);     
  delay (150); 
  digitalWrite(led_gruen1, LOW);
 
  offset = (mit_last + ohne_last)/2;                          // Der *offset* stellt einen "Kompromiss" aus den Mittelwerten mit und ohne Last dar. Idealerweise sollten sich diese nicht unterscheiden
 
  Serial.print("Kalibrierungswert für *offset* ( ");
  Serial.print(offset); 
  Serial.println(" )"); 
  Serial.print("LEDs ausschalten. Kalibrierung beendet.");
  Serial.println(" "); 
  Serial.println(" "); 
}
 
void ampelstufen_anzeigen(){                                  // Mit dieser Funktion können Grenzwerte der Ampelstufen angezeigt werden
  Serial.println("  ");  
  Serial.println("  ");
  Serial.print("grenze_rot: ");
  Serial.println(grenze_rot);
  Serial.print("grenze_gelb2: ");
  Serial.println(grenze_gelb2);
  Serial.print("grenze_gelb1: ");
  Serial.println(grenze_gelb1);
  Serial.print("grenze_gruen3: ");
  Serial.println(grenze_gruen3);
  Serial.print("grenze_gruen2: ");
  Serial.println(grenze_gruen2);
  Serial.println("  ");  
  Serial.println("  ");
  delay (150);
}
 
void ausgaenge_definieren(){           //Hier werden die PINs als Ausgang definiert
  pinMode(led_rot, OUTPUT);      
  pinMode(led_gelb2, OUTPUT);     
  pinMode(led_gelb1, OUTPUT);    
  pinMode(led_gruen3, OUTPUT);   
  pinMode(led_gruen2, OUTPUT);    
  pinMode(led_gruen1, OUTPUT);
}
Anmelden