Lichteffekte zum Bass

Hallo zusammen,

ich möchte für ein Goa Open Air einen Hut mit EL Wire darum leuchten lassen, allerdings nicht dauerhaft, sondern pulsierend mit dem Bass. Jetzt ist meine Frage wie ich am ehesten im Hut feststelle, dass Bass ist. Also würdet ihr da mit einem Mikrofon am Analogeingang nur auf die Lautstärke losgehen, und wenn sehr laut, dann Bass, oder wie stellt man ehesten Bass fest? Vorallem muss ich das ganze dann auch noch irgendwie von außen mit der Umgebungslautstärke "abgleichen" können, also entweder an einem zweiten AI einen Poti, oder den Poti als Widerstand am Mikrofon.
Wie würdet ihr da vorgehen?

Grüße,

Sven

Du bräuchtest noch einen Frequenzfilter. Das kann man zwar auch in Software mit einer Fourier Analyse machen (die Lib gibt es fertig), aber einfacher wäre wohl ein RC-Tiefpass.

Habe mir die Fourier Geschichte mal angeschaut. Die Grundlagen sind mathematisch außerhalb meiner Liga, sind aber prinzipiell wie viele Hinweise von Dir erstmal interessant für spätere Projekte. Für nur den Bass darstellen wird das zu komplex. Die von Dir favorisierte Methode mit RC Glied führt auch über meine Limits hinaus, das bekomme ich nie berechnet. Und vorallem, kann man sowas auch nach der Verstärkung des Mikrofons auf den 5V Pegel anbringen, oder muss das davor stattfinden?

Grüße,

Sven

Wie gesagt gibt es das fertig:
http://wiki.openmusiclabs.com/wiki/ArduinoFFT
http://wiki.openmusiclabs.com/wiki/ArduinoFHT

Das muss man nicht unbedingt verstehen. Da bekommst du dann die Amplitude von 16-256 Frequenzen

Code gibt es fertig:
http://wiki.openmusiclabs.com/wiki/Example
http://wiki.openmusiclabs.com/wiki/FHTExample

Ein Tiefpass ist ganz einfach:

Die Grenzfrequenz (bei der die Spannung auf 70,7% abgefallenen ist) ist 1 / (2 * Pi * R * C)

Wenn man mal für den Bass den Bereich unter 150Hz annimmt (?) hat R * C den Wert 1 / (2 * Pi * 150) = 1 / 942,5

Da kann man sich dann eine Kombination aus RC auswählen, die diesen Wert hat. z.B. 100nF und 10,6k Ohm. Die Werte müssen auch nicht genau passen, da die Übertragungsfunktion eines Tiefpasses 1. Ordnung sowieso ziemlich flach ist.

Es gibt auch fertige Rechner dafür:

http://www.elektrotechnik-fachwissen.de/wechselstrom/rctp.php
Letzter Link zeigt dir auch gleich den Frequenzgang an

Für einen digitalen Tiefpass braucht man keine FFT. Eine einfache Mittelwertbildung tut's auch. Oder ein exponentieller Filter weil der einfacher zu implementieren ist: Exponentielle Glättung – Wikipedia

Danke Euch beiden. Die Links von Serenifly habe ich schon so gelesen vor Deiner Antwort, und sehe den FFt wirklich als Overkill für einfach den Bass abtrennen. Und ich glaube, dass es auch einiges an Denkaufwand erfordert, bis man versteht was die Library macht, nichtmal wie sie das tut. Da ich das ganze evtl wieder mit einem ATTiny aufziehen will, und die Library explizit für die ATMega geschrieben ist. So wie Du den Tiefpass erklärst verstehe ich die Mathematik zwar immer noch nicht, aber ich kann es berechnen. Danke!
Die expotentielle Glättung verwende ich gerne um Analogeingänge zu glätten. Wie kann man damit oder einer Mittelwertbildung jetzt von einem Analogeingang Frequenzen heraus filtern? Das verstehe ich nicht.

Grüße,

Sven

Es ging doch darum einen Tiefpass zu etablieren. Das ist nichts anderes als Glätten.

Wenn Du mehr als eine Frequenz suchst aber nicht sehr viele, dann ist statt einer FFT oft der Goertzel Algorithmus besser: Goertzel algorithm - Wikipedia.

sven222:
Und ich glaube, dass es auch einiges an Denkaufwand erfordert, bis man versteht was die Library macht

Frequenzspektrum dürfte dir aber schon ein Begriff sein, oder?

Das gibt dir die Amplitude der Frequenzbestandteile eines Signals an. Eine reine Sinuswelle hat nur eine Frequenz. Entsprechend hat man in solchen Diagrammen da nur einen Peak. Komplexere Signale sind aber aus verschiedenen Frequenzen zusammengesetzt. Und deren Amplitude kann man einzeln berechnen.

Aber lassen wird das :slight_smile:

Wegen dem Tiefpass. Kondensatoren sind Frequenzabhängige Widerstände und der Kondensator verursacht eine Phasenverschiebung der Spannung. Statt da mit komplexen Zahlen zu rechnen, kann man das einfach an einem rechtwinkligen Dreieck betrachten:

Daher kommt dieser Ausdruck Z = sqrt(Xc² + R²). Einfacher Pythagoras.

Es ist ein Spannungsteiler, also ist Ua = Ue * Xc / Z. Wobei Xc der kapazitive Blindwiderstand ist und Z der Scheinwiderstand aus R und C. Das ist analog zu Teilspannung = Gesamtspannung * Teilwiderstand / Gesamtwiderstand bei reinen ohmschen Widerständen.
Der Scheinwiderstand Z ist praktisch der Gesamtwiderstand aus R und C, aber durch die Phasenverschiebung kann man den eben nicht einfach addieren, sondern muss den Pythagoras anwenden.
Dann ersetzt man Xc durch 1 / (2 * Pi * f * C), fasst das zusammen und fertig. 2 * Pi ist der Umfang eines Einheitskreises. Daher heißt 2 * Pi * f auch Kreisfrequenz.

Serenifly:

sven222:
Und ich glaube, dass es auch einiges an Denkaufwand erfordert, bis man versteht was die Library macht

Frequenzspektrum dürfte dir aber schon ein Begriff sein, oder?
Frequenzspektrum – Wikipedia

Das gibt dir die Amplitude der Frequenzbestandteile eines Signals an. Eine reine Sinuswelle hat nur eine Frequenz. Entsprechend hat man in solchen Diagrammen da nur einen Peak. Komplexere Signale sind aber aus verschiedenen Frequenzen zusammengesetzt. Und deren Amplitude kann man einzeln berechnen.

Aber lassen wird das :slight_smile:

Na prima. So wars nicht gedacht. :wink: Meine Aussage war eher darauf bezogen wie man die library behandeln muss, also wie man wo was im Code einbindet, und was welche Auswirkungen hat. Da geht ganz schnell ein Tag weg, bis man so eine Library verstanden hat.
Zum Rest von Deinem Beitrag kann ich wie immer nur danke sagen. Mit etwas googlen an einigen Stellen werde ich da heute abend wieder weniger dumm als gestern ins Bett gehen. Und auch mit Udos Link zum Görtzel Algorithmus habe ich noch einiges zum lesen und lernen. Ihr glaubt gar nicht wie ich mich ärgere, dass meine Mathelehererin, die ich von der 10ten bis zum Abi hatte, und ich nicht miteinander klar kamen, und ich mich deshalb komplett verweigert habe. Es ist einfach blöd, wenn einem die Grundlagen komplett fehlen.
Ich werde jetzt wohl einen Tiefpassfilter bauen aus 100nF und irgendwas zwischen 10 und 20kOhm, und dann mal schauen ob das schon ausreicht. Da bei solchen Veranstaltungen der Bass meist so betont und so tieffrequent ist wird das hoffentlich reichen. Mikrofon im Hut untergracht führt nochmal zu einer Dämpfung. Falls vor Ort dann doch noch irgendwas umgelötet oder programmiert werden muss ist das nicht so schlimm, da auf dem Festival ein Arduino für Einsteiger Workshop sein wird, da kann man sich dann schnell einen Lötkolben borgen.

Grüße und Danke Euch beiden,

Sven

Hi,

ich habe mich mit dem Thema Beaterkennung länger und mit verschiedenen Ansätzen befasst. U.a. oben genannte. Ergebnis: für mich alles Mist weil aufwändig/anfällig/komplex/langsam.

Benutze jetzt einen MSGEQ7 für alles, was mit "Audio triggert Ereignis" zu tun hat.

Tutorial hier: http://tronixstuff.com/2013/01/31/tutorial-arduino-and-the-msgeq7-spectrum-analyzer/

Auch als Shield verfügbar: http://www.watterott.com/de/Spectrum-Shield

Mache damit gerade sowas (auf einem ATmega2560):

Beste Grüße

Helmuth

edit: Gottfried Mayer hat einen Partyhut mit MSGEQ7 gebaut. Sign in - Google Accounts

Oh ha, der MSGEQ7 sieht interessant aus. Vorallem für die zweite Hutidee die ich habe, ein Hut mit WS2812, gibt es zwar schon, wie man Deinem Link entnehmen kann, aber egal. Lernt man zwar nicht so viel bei, aber es könnte einfach und sauber funktionieren. Danke! Und feine Dinge, die Du da mit den LEDs nd den Tönen tust.

Grüße,

Sven

Eine FRage habe ich da noch zu dem MSGEQ7. Reicht der 63Hz Peak zum Bass erkennen, oder sollte man besser die 160Hz noch mit dazu verwenden?

Grüße,

Sven

Das hängt vollständig von der Signalquelle (dein Mikro+Verstärker+Verkabelung) und dem Audiomaterial selbst ab. Das 160 Hz Band reagiert auf jeden Fall schneller (steilere Flanke).

Die interessantere Frage ist: WO im Pegel von einem Frequenzband legt man den Schwellwert (und wie regelt man ihn dynamisch nach)?

Das auf dem Tisch aufzubauen und das Eingangssignal von Hand zu regeln, bis es halt passt, ist eine andere Nummer, als auf einer Party ständig wechselnde Schalldrücke geschickt ausregeln zu lassen.

Beste Grüße

Helmuth

Ja, das wird bestimmt noch spannend. Ich will auf alle Fälle einen Poti dranmachen, dass man zumindest von Hand nachregeln kann.
Und Laptop kommt auch mit, dann kann man nachjustieren unter realen Bedingungen.
In dem von dir geposteten Tutorial (http://tronixstuff.com/2013/01/31/tutorial-arduino-and-the-msgeq7-spectrum-analyzer/)
ist entweder ein Fehler drin, oder ich bin total daneben. In zwei verschiedenen for Schleifen wird jeweils dieselbe globale Variable verwendet und hochgezählt. Zeile 21 und 34 im ersten Codelisting. Das kann so nicht passen. Aber die Grundidee wird klar wie es gehen soll. Das sollte man hinbekommen. Vieleicht mache ich ja endlich mal eine Library, der MSGEQ7 wäre da vieleicht das rchtige Opfer dafür.

Grüße,

Sven

Ich hab's nicht gepostet, nur verlinkt.

Einmal wird in der Funktion readMSGEQ7() die globale Variable band hochgezählt, um den MSGEQ7 auszulesen, das andere Mal wird die Variable band hochgezählt, um zwecks Ausgabe der gespeicherten Wert aus left[band] und right [band] auszulesen. Nacheinander.

Kein Problem.

edit: Die lib gibts schon https://github.com/fuse314/gmaLightMusicHat/blob/master/MSGEQ7Mgt.cpp, ist aber (unnötig) langsam.

Ja, ich habe gerade etwas Neues über for() Schleifen gelernt, nämlich dass sie wirklich Schleifen sind. Ging von einer anderen Funktionsweise dieser aus. Ich habe mir bisher an vielen Stellen das Leben unnötig verkompliziert, und einige Fehler in der Vergangenheit erklären sich nach einigem am rumgoogeln gerade.

Da ich leider meine Bastelkiste nicht da habe weil ich in einem Hotel in der Türkei sitze kann ich Sachen nicht einfach ausprobieren, deshalb meine Nachfragen hier ständig.
Helmuth hat weiter vorne was angesprochen, von wegen wo man den Schwellenwert setzt und wie man ihn dynamisch nachregelt. Und Udo hat die expotentielle Glättung eingebracht, wenn auch nicht dafür. Jetzt meine Frage: Könnte es funktionieren, dass ich den "Mittelwert" des Basslevels mit der expotentiellen Glättung mit sehr kleinem Alpha berechne, und dann einfach den Bassausschlag mit x% über diesem Mittelwert festlege? Oder sollte man da besser eine "richtige" Mittelwertbildung verwenden?

Grüße,

Sven

Hallo zusammen,

ich habe jetzt zur Bass-Erkennung dieses Mikrofon (
http://www.watterott.com/de/Breakout-Board-mit-Kondensatormikrofon) mit einem Tiefpassfilter (100kOhm und 100nF) am Start. Die Basserkennung läuft in der Software damit, dass ich den analogeingang expotentielle Glätte mit einem sehr niedrigen Faktor (0.11), und sobald der Eingangswert 15% darüber liegt wird es als "Bassschlag" erkannt, und eine LED blinkt. In einem gewissen Rahmen funktioniert das auch. Leider ist das Mirkrofon sehr schnell am Vollauschlag, und liefert dann sehr kleine Werte. Also nach 1024 dann plötzlich 36. Das haut dann natürlich alles zusamen. Kann man das Mikrofon dazu bringen etwas weniger empfindlich zu sein?
Das zweite Problem ist, dass die 15% Mittelwertüberschreitung auch nicht wirklich die Ideallösung sind. Bei sehr leiser Musik wären 10% besser, bei sehr lauter 20%. Wie kann ich das am ehesten dynamisch nachziehen? Code habe ich unten mal angehängt.

Danke schon einmal für etwaige Antworten,

Sven

int led = 13;
double ExpSensVal = 500;
double ExpSensVal2 = 500;
double glaetten();
long previousMillis = 0;        // will store last time LED was updated
// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);  
  Serial.begin(9600);  
}

// the loop routine runs over and over again forever

void loop() {
  int SensVal = analogRead(A0);
  ExpSensVal = glaetten(SensVal, ExpSensVal, 0.11);
  ExpSensVal2 = glaetten(SensVal, ExpSensVal2, 0.99);
  double BassVal = ExpSensVal * 1.15;
  if (ExpSensVal2 > BassVal){
    digitalWrite(led, HIGH); 
  }
  else{
    digitalWrite(led, LOW);
  };
}
int glaetten(double wertaktuell, double wertalt, double faktor){
  double tmp = wertaktuell * faktor;
  tmp = (tmp +( wertalt * (1 - faktor) ) );   
  return tmp;
}

Schau dir den Schaltplan an:

Du könntest R5 durch ein Poti + 1k ersetzen (oder z.B. 10k für eine Mindestverstärkung von 10). Dann kannst du die Verstärkung einstellen.

Man kann vielleicht eine Art Durchschnitt der letzten x Messungen bilden um so festzustellen wie etwa das Niveau der Amplitude im Moment ist.