Pages: [1] 2   Go Down
Author Topic: Melodien Soundsequenzen mit dem arduino wieder geben  (Read 2205 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo
Vorweg ich bin ein Neuling auf dem gebiet der Microcontrollern
ich möchte mit dem Arduino Einen soundgenerator machen um ein LKW Dieselgeräusch zu erzeugen und in der Drehzahl zu regeln
Ist das Möglich ?

Danke im Voraus
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ist hier Niemand der mir helfen will oder kann ?
Logged

Offline Offline
Full Member
***
Karma: 5
Posts: 193
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du kannst Melodien abspielen, wenn du die Frequenzen des LKW kennst.
Wenn ich mich nicht irre heiß die Funktion tone().

Addi
Logged

  / \    _|  _| o
 /--\ (_| (_| |

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 263
Posts: 21601
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du kannst Melodien abspielen, wenn du die Frequenzen des LKW kennst.
Wenn ich mich nicht irre heiß die Funktion tone().
Addi
Das klingt dann aber gar nicht nach einem Dieselmotor.
DennisD hast Du dich mal bei Modellbaubedarf informiert oder auf solche Seiten über Modellbauprojekte.

Du kannst auf einer SD-Karte ein Musikfile aufzeichnen und dieses mit einem Shield, von Arduino gesteuert abspielen.

Grüße Uwe
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Doch, das geht. Zuerst brauchst du eine Originalaufnahme. Die bearbeitest du am PC mit einem Soundeditor (z.B. Audacity) so, dass eine "nahtlose" Soundschleife von ca. 1 Sekunde Länge entsteht. Mit "nahtlos" meine ich, dass beim ständig wiederholten Abspielen kein Knacksen  beim Übergang Ende zu Anfang zu hören ist. Da musst du mit dem grafischen Wellenbild etwas experimentieren ...

Der nächste Schritt ist das Abspeichern als unkomprimiertes WAVE-File, mono, 8 Bit, Samplingrate ca. 6..8 kHz. Du kannst den Klang dann schon mal am PC testen, indem du auch den zukünftig zu verwendenden Lautsprecher anschliesst (wahtscheinlich irgend einen Mini-Speaker?). Je geringer die Samplingrate ist, mit der du dich zufrieden gibst, um so besser - desto gringer die Datenmenge. Erwarte kein Hifi, guter "Telefonsound" ist aber durchaus zu ereichen.

Als nächstes musst du mit einem Hex-Editor die Haeder-Daten vom Wave-File abschneiden. Wie lang der Haeder ist, steht z.B. bei Wikipedia. Würdest du diese Daten vom Arduino mit abspielen lassen, kämen die als Knacken und Kratzen 'rüber. Der übriggebliebene Datenblock kommt als Byte-Array mit in den Programmtext oder auf die SD-Karte (falls du öfters mal tauschen willst).

Zum Abspielen liest du im Arduino-Programm Byte für Byte und schiebst das per PWM aus einem Ausgangs-Pin, wo dann der Lautspecher oder ein Verstärker angeschlossen ist. Dazu musst du noch die Frequenz der PWM auf 32 kHz erhöhen (steht u.a. hier: http://arduino.cc/forum/index.php/topic,45094.0.html), damit die sicher aus dem Bereich der hörbaren Frequenzen raus ist. Das hat noch Nichts mit der Abspielgeschwindigkeit zu tun, die bestimmst du damit, wie schnell du jeweils ein neues Byte aus den Sunddaten "nachlädtst". Das sollten so 5000 ... 8000 pro Sekunde sein - Nichts, was den Arduino wirklich ins Schwitzen bringt, es ist also noch genügend Kapazität für irgend eine Empfangsroutine (seriell, Ethernet) oder das Auslesen des AD-Wandlers zur Beeinflussung der Abspielgeschwindigkeit ...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

vielen dank für die antworten setzte mich gleich hin und versuche es mal
 das einzige was ich nicht verstanden habe ist das mit dem hochsetzten des PWM Signals wie hoch ist dieses den normalerweise ?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

so hab jetzt schon mal die daten geschnitten und umgewandelt.
Macht es was aus ob die byts hex oder ascii sind?

und verstehe immer noch nicht (weil mein englisch anscheinend dafür zu schlecht ist) wie ich die PWM Frequenz auf 32KHz bekomme
das programm siet bis jetzt so aus:

int Speaker = 10;

int myArray[]={
00,00,0x93,0x7b,0x72,0x76,0x67,0x94,0x85,...............................};

void setup ()
{  pinMode(Speaker,OUTPUT);  }

void loop ()
{
for (int i=0; i<2280; i++){
  analogWrite(Speaker,myArray);
}
}
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wie die Bytes notiert sind, ist unerheblich, das wandelt die IDE beim Compilieren sowieso in binär um.
Wie du die Frequenz hoch bekommst steht hier:

http://books.google.de/books?id=YSsj2b2h37kC&pg=PA253&lpg=PA253&dq=arduino+audio+pwm&source=bl&ots=bsOKLhzR_p&sig=OCDKMQCYwm0tVHuVOlPPLyr2zZE&hl=de&sa=X&ei=S4DhUKjyFI_Nsgb0-oGwBQ&ved=0CDEQ6AEwAA#v=onepage&q=arduino%20audio%20pwm&f=false

DIe PWM ist quasi die "Trägerfrequenz" für das Ausgangssignal und muss mindestens um den Faktor 2..3 höher sein als das höchste "getragene" Signal (lt. Abtasttheorem) und ausserdem natürlich (bei Audio) selber nicht mehr im Hörbereich (>20kHz). In deine Ausgabeschleife musst du ausserdem noch ein DelayMicroseconds einbauen und so dimensionieren, dass zunächst bei der Ausgabegeschwindigkeit wieder die ursprüngliche Samplingrate rauskommt. Verkürzt du das Delay, dann wird der Sound höher, verlängerst du es, tiefer ...

Code:
for (int i=0; i<2280; i++)
{
  analogWrite(Speaker,myArray[i]);
  DelayMicroseconds(125); //so ungefähr bei 6k Sampling, genauen Wert ausprobieren
}

Hörst du denn schon irgendwas?
« Last Edit: December 31, 2012, 07:26:56 am by qualidat » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Der verweis was schon mal sehr hilfreich danke nur auch trotz des hochsetztens omt bei meinem programm kein ton raus daher würde iches gern auf basis des im verweis verwendeten programmes versuchen :

int Speaker = 9;

void writeAudio(uint8_t val) {
  OCR1A = (val);
}

void setup ()
{
 
  pinMode(Speaker,OUTPUT);
  TCCR1A = _BV(WGM10) | _BV(COM1A1);
  TCCR1B = _BV(CS10)| _BV(WGM12);
}

void loop ()
{
  int inc =20;
  for ( int j=0; j<1024; j++){
  writeAudio(j/4);
  delayMicroseconds(10);
  }

}

welche variabele muss ich nun zu meinem myArray ändern damit die daten wiedergegeben werden ?
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Also Eines ist schon mal klar - Arrays, deren Inhalt im Programmtext definiert wird - so wie du das gemacht hast (und ich zur Überprüfung auch), haben eine Begrenzung in der Größe. Den genauen Wert habe ich noch nicht gefunden, Tests haben ergeben, dass bei ca. 1750 Werten Schluss ist. Danach macht der Arduino nur noch Unsinn ...

Das ist bestimmt auch ein Grund, warum du Nichts hörst, das Programm läuft nicht richtig, auch wenn es in Ordnung ist. Ich teste das morgen mal weiter ...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok danke schon mal für die info ich kurze es mal noch mehr und versuche es dann auch nochmal
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Also Eines ist schon mal klar - Arrays, deren Inhalt im Programmtext definiert wird - so wie du das gemacht hast (und ich zur Überprüfung auch), haben eine Begrenzung in der Größe. Den genauen Wert habe ich noch nicht gefunden, Tests haben ergeben, dass bei ca. 1750 Werten Schluss ist. Danach macht der Arduino nur noch Unsinn ...
Das liegt daran, das eine Variable immer Speicher im SRAM belegt und davon hat der Uno gerade mal 2kB. Mit einem char-Array (oder Byte-Array) mit 1750 Werten verbräts Du schon mal 85% der verfügbaren Speichers. Verwendest Du nun zusätzlich noch die Serial-Ausgabe, braucht die noch RAM für Ihren Puffer. Dazu kommen sämtliche andere Variablen die Dein Programm so benötigt. Der µC verwendet auch noch das untere Ende vom RAM als Stack, der gegen den Anfang des Speichers wächst, z.B. bei Funktionsaufrufen.
Mario.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Das liegt daran, das eine Variable immer Speicher im SRAM belegt und davon hat der Uno gerade mal 2kB. Mit einem char-Array (oder Byte-Array) mit 1750 Werten verbräts Du schon mal 85% der verfügbaren Speichers. Verwendest Du nun zusätzlich noch die Serial-Ausgabe, braucht die noch RAM für Ihren Puffer. Dazu kommen sämtliche andere Variablen die Dein Programm so benötigt. Der µC verwendet auch noch das untere Ende vom RAM als Stack, der gegen den Anfang des Speichers wächst, z.B. bei Funktionsaufrufen.
Mario.

Ja, das klingt logisch. Die Lösung steht hier, habe ich aber selber noch nicht gemacht, muss ich erstmal ausprobieren:

http://arduino.cc/en/Reference/PROGMEM

Hier noch ein Beispiel:

http://stackoverflow.com/questions/12169374/arduino-progmem-byte-array
« Last Edit: January 01, 2013, 03:54:05 pm by qualidat » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

so hab jetzt die daten menge auf die hälfte reduziert uns es kommt auch was aus dem Lautsprecher zwar verzerrt und leicht unsauber aber es kommt schon mal was
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich habe nochmal in meinen Verzeichnissen gewühlt und ein Beispiel wiedegefunden. Mit dem folgenden Code habe ich Musik (8k Samplingrate) per serieller Schnittstelle an den Arduino gesendet und per Lautsprecher in erstaunlich guter Qualität ausgegeben. Du musst nur noch das Problem mit der Datenmenge lösen (PROGMEM). Im Programmspeicher ist so viel Platz, da könntest du durchaus besser gesampelte oder gar verschiedene Sounds hinterlegen. In diesem Beispiel bestimmt das Tempo der Seriellen die Ausgabegeschwindgkeit - bei Dir ist es das Delay in der For-Schleife ...

Code:
//------------------------ DEFINE --------------------------
#define PWM_Pin 11
byte buf;
//------------------------- SETUP --------------------------
void setup()
{
  Serial.begin(57600);
  int pwm_freq=1;
  TCCR2B = (TCCR2B & 0xF8) | pwm_freq;
  pinMode(PWM_Pin, OUTPUT);
}
//------------------------ LOOP -----------------------------
void loop()
{
    //...................... serial input .....................
  if (Serial.available() > 0)
    {
      buf = Serial.read();
    }  
    analogWrite(PWMPin,buf); 
}
« Last Edit: January 01, 2013, 09:29:52 pm by qualidat » Logged

Pages: [1] 2   Go Up
Jump to: