50 Piezos für Audio einzeln mit einem Arduino steuern

Hallo zusammen

Ich habe folgendes Ziel: Ich möchte etwa 50 Piezos einzeln mit einem Arduino steuern. Es reicht mir, wenn die Klangsamples oder ähnliches eine "schlechte" Qualität haben. Mit einem Piezo funktioniert es wie ich möchte (dank den vielen tollen Tutorials dazu). Es müssen bei weitem nicht alle Piezos miteinander klingen (je nachdem wie kompliziert es wird reichen 1 - 5 Piezos gleichzeitig).

Nun die Fragen:

  1. Wie kann ich dies von der Hardwareseite her lösen? Die PWM-Ausgänge auf den Boards reichen offensichtlich nicht.
  2. Kann ich den Code weitgehend übernehmen von einer Piezoscheibe? Oder worauf muss ich achten?

Ich habe schon intensiv im Internet gesucht, aber leider nichts gefunden. Oder könnte ich etwas mit dem TLC5940 machen?

Gruss,
Thomas

Hallo Thomas,
klingt nach Schieberegistern (mit Tri-State Ausgang), die die einzelnen Piezos aus den 50 selektieren und dann über die PWM Ausgänge angesteuert werden.
Oder multiplexen, sollte auch gehen.

Aber wenn eh nur max 5 piepsen sollen, warum dann 50?

Grüße
Klaus

Hallo Klaus

Danke für die schnelle Antwort.

Da ich recht neu bin mit dem Arduino überfordert mich deine Antwort ein wenig. Könnest du es etwas genauer ausführen?

Es sollen nur 5 gleichzeitig piepsen (wenn alle gelichzeit möglich sind, umso besser). Ich möchte schon alle einzeln ansteuern können (ähnlich einem LED-Lauflicht).

Gruss,
Thomas

Letztlich brauchst du ja mehr Ausgänge, als der Arduino hat.

Das kann man mit Schieberegistern machen, das ist ein Baustein in den man seriell die Daten reinschiebt, der diese dann an seinen Pins ausgiebt. Man kann mehrere Schieberegister hintereinanderschalten (kaskadieren) um mehr Pins zu bekommen.

Schau mal hier: http://arduino.cc/en/tutorial/ShiftOut

ES gibt auch spezielle Port-Expander bausteine, wie den MCP23017, die über I2C angesteuert werden.

Und dann gab es noch den User Wulffi, der einen 64 bit Portexpander als Shield bauen wollte Sammelbestellung: 64 Port I2C-Expander als Arduino-Shield ich weiß aber nicht, wie weit er ist.

Nachtrag:
Und dann gibt es noch das Centipede Shield (64 I/O Ports) aus USA zu kaufen.

Kann ich mit so einem Shift-Register auch für die PWM-Ausgänge benutzen? Wenn ich das von dir angegebene Tutorial anschaue habe ich das Gefühl, die LED werden einfach nur an und aus geschaltet. Für die Piezos müsste ich doch modulieren.

Joghurt72:
Kann ich mit so einem Shift-Register auch für die PWM-Ausgänge benutzen? Wenn ich das von dir angegebene Tutorial anschaue habe ich das Gefühl, die LED werden einfach nur an und aus geschaltet. Für die Piezos müsste ich doch modulieren.

Wenn du unterschiedliche Tonhöhen haben willst, bringt dir der PWM-Ausgang recht wenig, da dieser standardmäßig mit 490Hz arbeitet. Bei der Nutzung von analogWrite() wird nur das An-Aus-Verhöltnis geändert, die Frequenz bleibt.

Wenn ich folgenden Artikel richtig verstanden habe, sollte es eigentlich klappen:

Wobei es hie rnur mit einem Lautsprecher gezeigt wird.

Wie man meinen Fragen ansieht, bin ich ordentlich am Schwimmen. Wie könnte ich es sonst machen?

Oder auch hier brauche ich für jeden Speaker einen PWM-Ausgang, oder?
http://playground.arduino.cc/Code/PCMAudio

ok, dann hatte ich das falsch verstanden. Ich hatte deine 50 "Piezos" als Piezo-Summer interpretiert. (AN, AUS mit Festfrequenz).

wenn ich das jetzt richtig verstehe, dann willst du 50 (Piezo-)Lautsprecher ansteuern?

Ohne mich in dieser Materie besonders gut auszukennen, vermute ich, dass der Arduino damit überfordert ist.

Eigentlich muss da gar nicht so viel rauskommen. Wenn es Klickgeräusche machen kann wäre das auch schon toll.

Ich habe mal herumgesucht und auf Vimeo etwas gefunden, was in diese Richtung geht (Soundbeispiele ab 1:45): sterntaler on Vimeo

Ich versuche mal meinen Wunsch etwas einzuschränken: 50 Piezosummer, welche alle unabhängig ein Klickgeräusch machen sollen, möglichst viele davon gleichzeitig.

Ich hoffe, das kriegt der Arduino (ev. der Mega?) hin.

Spendiere jedem Piezo doch einfach eine kleine Verstärkerschaltung - im einfachsten fall mit einem einzelnen Transistor. Diesem Transistor führst Du ein Tonsignal zu, das er soweit verstärkt, dass auf dem Piezo was vernünftiges raus kommt.

Und jetzt der Trick: dieses Tonsignal läßst Du über einen zweiten Transistor laufen, den Du per Arduino-Port schaltest. Da der Arduino selbst zu wenige Port dafür hat, kannst Du einfach auf Portexpander wie den PCF8574 zurückgreifen. Diese schalten dann denn Transistor mit dem Audio-Signal durch und leiten dieses auf den Verstärker.

Damit kannst Du Deine 50 Piezos praktisch zeitgleich ein und aus schalten. Die geringe Verzögerung durch die verwendung von 7 Portexpandern und der dabei erforderlichen Kommunikation solltest Du nicht hören können, so dass die Piezos scheinbar gleichzeitig an gehen.

Du kannst es auch tatsächlich gleichzeitig hinbekommen, wenn Du noch einen weiteren Transistor in die Signal-Kette schaltest und den über einen gemeinsamen PIN schaltest. Per Port-Expander kannst Du dann auswählen, welche Lautsprecher angehen sollen und mit diesem "Enable" Pin kannst Du sie dann synchron einschalten. Alternativ kannst Du mit einem Pin auch einfach den Tongenerator ein / aus schalten oder das Tonsignal per Arduino erzeugen. Per Portexpander legst Du dann wieder fest, an welche Verstärker das Audio-Signal angelegt werden soll und an welchen nicht. Das dürfte hardwaremäßig sogar die einfachste Lösung sein ... auch wenn dafür immer noch 100 Transistoren (50 zum Schalten udn 50 zum Verstärken) und 7 Portexpander notwendig sind :slight_smile:

Ich vermute mal, dass kurzes Einschalten ein Klickgeräusch produziert.

Dies geht mit den oben erwähnten Portexpandern bzw Schieberegistern.
Bevor du dich allerdings in den Aufbau stürzt, würde ich erstmal Experimente mit wenigen Exemplaren machen.
Vielleicht reicht ja ein Piezo Lautsprecher, den man kurz einschaltet.

Was auch möglich wäre, das man eine Signalquelle hat (eine Rechteckspannung deiner gewünschten Frequenz) die auf jeweils einen Pin der Piezolautsprecher geht, der andere wird über einen Transistor auf Masse geschaltet. Damit könntest du kurze Pulse einer festen Frequenz ausgeben.

Ich sage mal: 50 Verbraucher in bestimmten zeitlichen "Mustern" zu schalten, dass kann ein Arduino.
Welche Art von Ansteuerung den besten Effekt gibt, das mußt du ausprobieren.

Gleich mal vorweg: Danke dass ihr euch alle so viel Mühe gebt!

Ich habe in meiner Box einige (NPN) BC547. Kann ich die für das Anschalten der einzelnen Piezos verwenden? Und was nehme ich für einen Transistir für die Verstärkung des Audiosignals. Nach den verschiedenen Tutorials welche ich durchforstet habe müsste auch der BC547 (wo ist der Unterschied zum BC548?) gehen. Stimmt das soweit?

@mgcss: Verstehe ich dich richtig: Das Audiosignal kommt von einer externen Quelle? Oder vom Arduinoausgang. Das würde bedeuten, dass ich konstant ein Audiosignal habe, dieses aber auf verschiedene Piezoscheiben "verteilen" kann? Somit kann ich nicht gleichzeitig verschiedene Audiosignale auf verschiedenen Piezos laufen lassen?

Ich glaube, dann sollte ich es langsam selbst können... Hoffentlich!

BC547 und BC548 unterscheiden sich nur in der maximalen Spannung
UCE BC547 = 50V
UCE BC548= 30V

Du kannst also beide nehmen.

Ich habe dir mal eine Schaltung skizziert, mit der ein Test möglich sein sollte.
Mit den 390Ohm Vorwiderständen wird jeder Piezo mit ca 30mW angesteuert. Ich denke, das sollte reichen um zumindest ein laut vernehmliches Knacksen zu erzeugen.
Wo ich mir nicht sicher bin: Wie reagieren die Piezolautsprecher auf eine getacktete Gleichspannung?
Die Dioden brauchst du nur, wenn du nicht Piezo-Lautsprecher nimmst, sondern elektromagnetische.

Funktion:
an Pin6 erzeugst du eine symetrische Rechteckspannung "analogWrite(13,127);" Die hat dann 980Hz. (Du kannst 490 Hz nehmen, wenn du z.B. Pin 10 nimmst.) Dieses Signal liegt an allen drei Piezos an.
Mit den Pins 2,3,4 kannst du die einzelnen Piezos anschalten.

Das ist jetzt reine Theorie, sollte aber funktionieren. und du kannst mal rumexperimentieren.

Ansteuern könnte in etwa so funktionieren (quick and dirty)

const int PWM_Pin = 6;
const int Speaker1_Pin = 2;
const int Speaker2_Pin = 3;
const int Speaker3_Pin = 4;

int pulsetime = 100;
int pausetime = 200;

void setup() {
  Serial.begin(9600);
  pinMode(PWM_Pin, OUTPUT);
  pinMode(Speaker1_Pin, OUTPUT);
  pinMode(Speaker2_Pin, OUTPUT);
  pinMode(Speaker3_Pin, OUTPUT);
  analogWrite(PWM_Pin, 127);

}

void loop() {
  digitalWrite(Speaker1_Pin, HIGH);
  delay(pulsetime);  
  digitalWrite(Speaker1_Pin, LOW);
  delay(pausetime);  
  
  digitalWrite(Speaker2_Pin, HIGH);
  delay(pulsetime);  
  digitalWrite(Speaker2_Pin, LOW);
  delay(pausetime);  
  
  digitalWrite(Speaker3_Pin, HIGH);
  delay(pulsetime);  
  digitalWrite(Speaker3_Pin, LOW);
  delay(pausetime);  
  
  delay(1000);  
}

Wenn du mehr als diese 3 ansteuern willst, oder die Lautstärke nicht ausreicht, dann reicht der Strom aus dem PWM nicht mehr, dann müßte hier auf ein Transistor rein, aber dann ein PNP. Alternativ kann das auch extern erzeugt werden. Aber in dieser Schaltungstopologie immer nur in Form getakteter Gleichspannung.

Gunther was machst Du?

Du benutzt Transistoren um die Piezos anzusteuern, nimmst aber den Strom für alle Piezos von einem einzigen Pin von Arduino?

Grüße Uwe

uwefed:
Gunther was machst Du?
Du benutzt Transistoren um die Piezos anzusteuern, nimmst aber den Strom für alle Piezos von einem einzigen Pin von Arduino?

Richtig.

Es ging auch nur um eine schnelle Schaltung um den Effekt an sich zu testen.
Und die Widerstände sind so dimensioniert, dass selbst bei gleichzeitiger Ansteuerung aller drei Piezos der Ausgang nicht überlastet wird.

Wenn er mehr Strom braucht, muß er einen PNP Transistor kaufen gehen....

Und die Transistoren brauche ich, um "untere" Seite der Piezos hochohmig schalten zu können.

wenn ich es mir recht überlege, sollte es auch reichen die "unteren" Arduino Pins auf input zu stellen, ohne Transistoren.

hi,

welche stromstärke benötigen solche piezos eigentlich?

gruß stefan

Thomas redet hier von Piezolautsprechern, nicht von Piezosummern.
Die werden einfach immer lauter, je mehr Spannungshub man Ihnen gibt.

hi,

und was heißt das jetzt für einen nichtwissenden wie mich?
kann man einen piezoLAUTSPRECHER einfach an einen pin des arduino hängen und mit PWM zum tönen bringen?

gruß stefan

Ja, das geht.

Aber:

  1. Du mußt einen Vorwiderstand verwenden, um den Strom auf maximal 40mA zu begrenzen.
  2. Der Piezolautsprecher wird normalerweise mit Wechselspannung betrieben, hier aber mit gepulster Gleichspannung. Ich weiß, dass es funktioniert, kann aber keine Aussage darüber treffen , ob auf Dauer der Lautsprecher schaden nimmt.
  3. Der Ton, den du hörst, entspricht der Frequenz. Du kannst also mit PWM nicht die Tonhöhe verändern. dafür müßtest du dann tone() verwenden.

Nachtrag:
ich habe es gerade nochmal ausprobiert, sicherheitshalber:
einen billigen Piezo-hochtöner über einen 133Ohm Widerstand von Pin 6 auf Masse, und mit tone() ansteuern.
Es nicht gerade High-End, aber es reicht, um "alle meine Entchen quäcken zu lassen" XD

//  Spielt das Leid alle meine Entchen.
const int pin = 6;
const int ganzerton = 1500;
const int pause = 50;
const int c = 262, d=294, e=328, f=349, g=392, a=440, h=494; 
int lied[][2]={         {c, 4}, // ganzer ton = 16
                        {d, 4}, // halber ton = 8 ...
                        {e, 4},
                        {f, 4},
                        {g, 8},
                        {g, 8},
                        {a, 4},
                        {a, 4},
                        {a, 4},
                        {a, 4},
                        {g, 16},
                        {a, 4},
                        {a, 4},
                        {a, 4},
                        {a, 4},
                        {g, 16},
                        {f, 4},
                        {f, 4},
                        {f, 4},
                        {f, 4},
                        {e, 8},
                        {e, 8},
                        {g, 4},
                        {g, 4},
                        {g, 4},
                        {g, 4},
                        {c, 16}};
int lieddauer; 
                        
void setup(){ 
  lieddauer = sizeof(lied)/4;
  pinMode(pin, OUTPUT);
  for (int i=0; i<lieddauer; i++){
    tone(pin, lied[i][0],lied[i][1]*ganzerton/16);
    delay((lied[i][1]*ganzerton/16)+pause);
  }
}

void loop(){
}