electronic hand drum

  • hallo liebe gemeinde. :)


    ich bin student und arbeite seit geraumer zeit an einem projekt. ich hab ein elektronisches drum pad entwickelt, was im gegensatz zu existierenden geräten nicht fest irgendwo verortet ist (wie auf einem tisch oder einem ständer), sondern ganz mobil vom drummer getragen wird. und zwar liegt das instrument in der einen hand und wird mit den fingern der anderen hand bespielt. das ganze funktioniert mit hilfe eines kleinen mikrokontrollers names ardunio. es wandelt die signale in midi-noten um und schickt sie vie usb zum rechner, wo sie dann wieder mit einem program (ich hab abelton) interpretiert und verarbeitet werden. die schläge werden an 5 pads anschlagdynamisch über piezo-elemente aufgenommen. das ganze funktioniert bereits schon ganz gut. aber ein paar probleme hab ich da doch noch:


    (1) es gibt keine polyphonie. d.h. ich kann nicht zwei oder mehr pads gleichzeitig anschlagen.


    (2) die pads nehmen die schläge nicht sauber genug auf. wenn ich einmal draufhaue, dann werden 2 sounds gespielt. das liegt vermutlich daran, dass die piezo-elemente einmal beim "draufhauen" und einmal beim "runternehmen" einen sound abgeben. also wahrscheinlich immer, wenn die spannungswerte sich ändern. aber bei einem elektronischen schlagzeug werden doch auch keine anderen sensoren verwendet, oder?


    ich glaube, die fehler liegen zum großen teil in der programmierung. deshalb hier der code:


    _________________________________________________________________________
    unsigned char PadNote[5] = {30, 32, 34, 36, 38}; // definiert die midi-noten
    #define NumPads 5 //definiert die anzahl der pads
    int val = 0; // variable to store the value read from the sensor pin
    int THRESHOLD = 100; // ist ein mindestwert, der erreicht werden muss (skala von 0 bis 1024)
    boolean obpause = true;


    void setup()
    {
    Serial.begin(115200); // use the serial port
    }


    void loop()
    {


    for(int pin=0; pin < NumPads; pin++) { //dieser loop geht alle pads durch


    val = analogRead(pin); // liest den sensor und gibt der variable val der gelesenen wert


    if ((val >= THRESHOLD)&&(obpause == true))
    {
    obpause = false;


    int tmp = 0; //folgende zeilen sind lesen 7, kurz hintereinander empfangene werte aus und bilden daraus den mittelwert
    int tmp_reading = 0;
    for(int i=0; i<7; i++)
    {
    tmp_reading = analogRead(pin);
    tmp += tmp_reading;
    }


    tmp = tmp / 7;
    val = tmp;
    val = map(val, THRESHOLD, 1023, 50, 127);


    midi_note_on(0, PadNote[pin], val); //befehl zum senden des begins der midi-note
    delay(100); //dieses delay sorgt dafür, dass das pad nicht so schnell hintereinander ausgelesen wird
    midi_note_off(0, PadNote[pin], 127); //befehl zum senden des endes der midi-note
    }


    if((val<3)&&(obpause == false))
    {
    obpause = true;
    }
    }
    }


    ///////////////////////////// funktionen zum senden der midi-noten


    void midi_note_off(byte channel, byte key, byte velocity)
    {
    midi_command(0x80, channel, key, velocity);
    }


    void midi_note_on(byte channel, byte key, byte velocity)
    {
    midi_command(0x90, channel, key, velocity);
    }


    void midi_command(byte command, byte channel, byte param1, byte param2)
    {
    Serial.write(command | (channel & 0x0F));
    Serial.write(param1 & 0x7F);
    Serial.write(param2 & 0x7F);
    }
    ___________________________________________________________________________________



    aber vielleicht sind auch einfach die piezoelemente nicht optimal für so ein instrument? kennt sich da jemand aus? für hilfe wäre ich sehr, sehr dankbar!! :)


    bestens, christof

  • Hi, zu

    (1) es gibt keine polyphonie. d.h. ich kann nicht zwei oder mehr pads gleichzeitig anschlagen.

    Was heisst das genau? Es funktioniert nur ein Kanal/Piezo? Oder kommt ein anderer "leicht" verzögert?
    Also Du bist dir schon bewusst das Du am Ende der Kanalabtastung eine 100ms-Verzögerung eingebaut hast?
    Kann natürlich auch sein das ich mich verschaut habe, da der Code ohne Tabs schwer lesbar ist.


    zu

    (2) die pads nehmen die schläge nicht sauber genug auf.

    Ist das nur wenn Du auf deiner Box rumklimperst oder auch wenn die Piezos freiluft sind? Wenn es nur bei der Box ist, dann handelt es sich um Übersprechen der Kanäle aka crosstalk. D.h. wenn Du auf einen Piezo schlägst, überträgt sich das auch auf andere. Die Teile sind echt empfindlich. Schnorchel doch einfach mal die MIDI-Signale mit. Ansonsten hilft nur Loggen über Serielle/USB oder Infos anzeigen über LCD. Ein Mehrkanal-Oskar wäre auch hilfreich.


    Alternativ: Mach deine 100ms-Verzögerung mal kleiner. Wenn es jetzt sogar mehr Sounds werden, ist es definitv ein Ansprechen auf mehreren Kanälen.


    Ach so: Hier noch ein paar nette Infos (Jaja, die interne Suche saugt ...)
    ... ein Best Of ... als Linkliste Triggerbau, Kessel umrüsten, Midi und mehr


    Grüße
    Nao


    PS: Was studierst Du eigentlich?


    Achso: Edith meint sich erinnern zu können das für velocity/Anschlagstärke nicht die Höhe [V] sondern die Dauer des Signals oberhalb des Schwellwertes ausgewertet wird. Edith kann sich aber auch irren.

    4 Mal editiert, zuletzt von Nao () aus folgendem Grund: Verdammte Rechtschreibschwäche ab 23h00

  • besten dank für die schnelle antwort und den hinweis auf die links! :thumbup:


    Zitat

    Was heisst das genau?


    beim gleichzeitigen anschlagen funktioniert nur ein kanal/ piezo. und ja, ich bin mir im klaren über das delay von 100ms. wenn ich das nicht dirn hätte, würden gleich mehre sounds von einem piezo kurz hintereinander gespielt werden. gibts da eine bessere lösung für? vielleicht mit zeitmessung (millis)?


    Zitat


    Zitat von »krstf«


    Ist das nur wenn Du auf deiner Box rumklimperst oder auch wenn die Piezos freiluft sind? Wenn es nur bei der Box ist, dann handelt es sich um Übersprechen der Kanäle aka crosstalk. D.h. wenn Du auf einen Piezo schlägst, überträgt sich das auch auf andere.


    nein. wenn ich auf ein piezo schlage, überträgt sich das nicht auf andere, denn von den anderen empfange ich keine signale (oder zu vlt schwache?). es ist eher so, dass ich von ein und demselben pad oft 2 und mehr sounds bekomme, obwohl ich nur einmal draufhaue; ein sound bei "finger drauf" und einen bei "finger runter". besonders schlimm ist es an den rändern der scheiben. und weiter noch: die sensor reagieren auf die anschlagstärke. oft ist es so, dass wenn ich sanft draufschlage, ein lauter sound gespielt wird. und andersrum. ...gibts da ne lösung?


    ich studier produkdesign im 6. semester und bin in wirklichkeit fanatischer auf-allen-dingen-mit-meinen-fingern-rumtrommler. ;)


    grüß mal die edith von mir und sag ihr, dass das program die anschlagstärke ausliest, und nicht die dauer des signals oberhalb des schwellenwertes. ;)


    bestens, christof

    ///

  • Hi Christof,


    ich glaube ich weiss wo das Problem liegt. Für das erste muss die 100ms-Verzögerung raus und bei dem 2ten muss eine "Sperre" nach dem ersten Ton rein. Ich muss zugeben das es aber recht theoretisch ist. Zudem steht Punkt 1 und 2 ein wenig im Widerspruch.


    Erklärung zu 1)
    Du schlägst alle gleichzeitig an und das Signal der Piezos würde für 100ms anliegen. Wenn die Routine mit dem ersten Durchlauf fertig ist, sind die Signale der anderen Piezo schon wieder weg.


    Erklärung zu 2)
    Nachdem ein Signal auf einem Kanal erfasst/gemessen wurde, muss der Kanal erstmal "ignoriert" werden. a) für eine bestimmte Zeit oder b) wenn das Signal wieder unter dem Schwellwert liegt.


    So, was Du brauchst ist eine state-machine:
    Für jeden Kanal muss ein Struktur oder, wie bei der Midi-Note, ein Array bereit stehen
    Struktur: Schritt, Midi-Note, Zähler, Velocity(gemessen)


    Programm (grundlegend)
    for(int pin=0; pin < NumPads; pin++) { //dieser loop geht alle pads durch


    case Schritt = 1
    Werte der Struktur initalisieren; Schritt +1


    case Schritt = 2
    Wert vom Kanal > Treshhold?
    J -> Schritt +1 und Zähler = 7 ; PS: Konstanten verwenden!


    case Schritt 3
    Zähler <= 0 ?
    J = Velocity berechnen und Schritt +1
    N = Zähler -1 und Velocity aufsummieren


    Case Schritt 4 ; Kann man auch in Schritt 3 machen, aber ist ein wenig übersichtlicher
    Midi-Note Ein
    Midi-Note Aus ; Wenn das nicht direkt geht, dann einen zusätzlichen Schritt wie den folgenden einbauen
    Zähler = Verzögerung in Durchläufen
    Schritt +1


    case Schritt 5
    Zähler <= 0 ?
    J = Schritt +1
    N = Zähler -1


    case Schritt 6
    Signal vom Kanal unter Treshhold ?
    J = Schritt = 1 ; Und es beginnt wieder von vorne



    Ich hoffe ich habe mich halbwegs verständlich ausgedrückt, aber es ist schon spät ... :sleeping:


    Grüße
    Oliver


    PS: Edith fühlt sich missverstanden. Sie wollte darauf hinweisen das EVTL. (sie hat keine Lust mehr zu googeln) der Wert für die Schlagstärke sich nicht aus der Höhe des Signals bildet (da es evtl. immer auf Max ist) sondern aus seiner Länge des anliegenden Signals bildet. Aber wie schon gesagt: Es ist schon spät :rolleyes:

  • zu erklärung 1) und 2): ja, du hast vollkommen recht.


    ich habe heute noch ein wenig an diesem delay gearbeitet. nun läuft es mit "millis". ich muss nun für jedes einzelne pad/ piezo folgenden code haben: (hier für piezo "A")


    //////////////////////////////////////////////


    valA = analogRead(pinA);

    if ((valA >= THRESHOLD)&&(obpauseA == true)&&(diffA>zeit))
    {
    obpauseA = false;

    int tmp = 0;
    int tmp_reading = 0;
    for(int i=0; i<7; i++)
    {
    tmp_reading = analogRead(pinA);
    tmp += tmp_reading;
    }

    tmp = tmp / 7;
    valA = tmp;
    valA = map(valA, THRESHOLD, 1023, 120, 127);

    midi_note_on(0, 30, valA);
    midi_note_off(0, 30, 127); //note OFF
    timeA1 = millis();
    }


    if((valA<3)&&(obpauseA == false))
    {
    obpauseA = true;
    }

    timeA2 = millis();
    diffA = timeA2 - timeA1;


    //////////////////////////////////////////////


    und so klappt das auch bisher ganz gut.


    außerdem hau ich nun nicht mehr diekt auf die piezos, sondern auf eine kleine metallscheibe, die direkt an dem piezo klebt. damit verteilt sich der druck besser und die anschläge werden konstanter.


    dank dir, oliver, dass du da so ein kontrikt beschieben hast. hab es zwar nicht 1 zu 1 übernommen, aber hab die logik dahinter verstanden. :thumbup:


    aber hast du noch einen guten rat, wie ich das "crosstalk" verhindern kann. oder zumindest vorbeugen kann? sollte ich jedes kabelpärchen mit einem schrumpfschlauch verkleiden?



    bestens, christof

    ///

  • Ohne den Code aufgedroeselt zu haben:


    Wie hast Du die Piezos an den Arduino angeschlossen?


    Gibt es da noch einen Pufferverstaerker, Parallelwiderstaende, Spannungsteiler o.ae.?


    So ein Piezo erzeugt u.U. schonmal Leerlaufpannungen von 30 Volt.
    Der A/D ist bei 5 Volt bereits Full-Scale ausgesteuert. Und natuerlich
    erzeugt so ein Piezo Wechselspannung, d.h. der Arduino bekommt auch
    die -30 Volt auf seinen Port.


    Erstmal muss man natuerlich der Hardware vertrauen, bevor man die
    Software debugged und irgendwelche Delays aus dem Geratewohl
    hinzufuegt.


    Die Pads sollten evtl. interruptgesteuert abgefragt werden.
    Wenn Du in die Schleife 100 ms Delay einfuehrst ist das Polling der anderen Pads
    auch fuer >100 ms blockiert. Dann klappts evtl auch mit der (Quasi-) Polyphonie.



    - Juergen -

    Gaffatape und Chewing Gum kleben die halbe Welt zusamm'

  • jetzt wo ich das problem der polyphonie in den griff bekommen hab, gibts bei meinen pads nun wahrscheinlich crosstalk. (es werden 2 unterschiedliche signale gesendet, während ich nur ein pad anschlage) wie kann ich das vermeiden?



    //

    Zitat

    Wie hast Du die Piezos an den Arduino angeschlossen?


    ein piezo ist mit der innenliegenden schicht mit 5V verbundenen. von der grundplatte geht ein kabel in einen pin des arduinos und eines parallel dazu durch einen widerstand in den ground des arduinos. ansonsten hängt da nichts dran.


    was bedeutet, die pads sollten interruptgesteuert abgefragt werden?

    ///

    2 Mal editiert, zuletzt von krstf ()

  • Wenn Du tatsaechlich eine relativ hohe Eingangsspannung der Piezos direkt an den Eingaengen nutzt kann es natuerlich zu Crosstalk kommen, da der uebersprechende Teil der
    Spannung immer noch gross genug ist um am Nachbarkanal den Thresholdlevel zu uebersteigen. Ursache kann hierbei auch die Kabelfuehrung sein, hier hast Du die groesste kapazitive
    Kopplung zwischen den Kanaelen. Wie lang sind die Kabel? Ich wuerde hier abgeschirmte Leitung verwenden. Mikrofonkabel oder RG174.
    Am besten testest Du das mal mit ausgebauten Piezos damit Du mechanischen und elektrischen Crosstalk trennst.


    Du koenntest die Spannung am EIngang mal mit einem hochohmigen Spannungsteiler (z.B. 470 kOhm Poti) verkleinern.


    Hast Du Zugang zu einem Oszilloskop?


    Ansonsten erstmal in kleinen Programmierschritten die Hoehe und Dauer der Impulse rausfinden. Das Datenblatt des Piezos gibt sicher auch das eine oder andere her.
    Macht es denn ueberhaupt einen Unterschied ob Du sanft auf die Piezos schlaegst oder kraeftig?



    Interruptgestuert bedeutet, dass ein laufendes Programm oder eine Routine unmittelbar unterbrochen wird, wenn ein Ereignis eintritt. Z.B. wenn sich der Pegel an einem
    Eingang aendert. Das muss beim Arduino AFAIK durch das Kommando "attachInterrupt()" aktiviert werden und funktioniert auch nicht mit allen Pins. Ich habe das ehrlich
    gesagt noch nie benutzt. Ohnehin habe ich noch nicht sehr viel mit dem Arduino gemacht. Da muesste ich mich erst einfuchsen. Beispiele gibt es aber sicher genug im
    Netz. Das Gegenteil von Interruptsteuerung ist "Polling", dabei werden die Eingaenge zyklisch abgefragt und dabei kann u.U. schonmal ein Event durch die Lappen gehen
    wenn der Prozessor gerade mit etwas Unwichtigem (delay(100)) beschaeftigt ist.



    Interessantes Projekt ueberigens.


    Ich habe mal einer Performance des Kuenstlers Andreas Hirsch beigewohnt, der hat eine sog. "Palmonica" gebaut. Einen mit Piezos elektrifizierten Palmzweig.
    Vielleicht interessiert es Dich ja; oder jemand anders, der den Thread bis hier geschafft hat ;) : http://vimeo.com/12865196, http://vimeo.com/45360991

    Gaffatape und Chewing Gum kleben die halbe Welt zusamm'

  • nein, ein ossziloskop habe ich nicht und ich komme auch an keines heran.
    crosstalk?! d.h., dass die elektrischen signale überspringen, ja? von einem kabel zum benachbarten. oder so ähnlich? leider habe ist im inneren kein platz, um solch dicke kabel wie mikrofonkabel oder diese "RG174" zu verwenden. tut es auch ein schrumpfschlauch? :huh:

    ///

  • crosstalk?! d.h., dass die elektrischen signale überspringen, ja? von einem kabel zum benachbarten. oder so ähnlich?


    So aehnlich. Einfach ausgedrueckt: um einen Leiterdraht wird ein elektrisches Feld aufgebaut und ein parallel laufender Draht wirkt wie eine Empfangsantenne.


    Schrumpfschlauch hat keine abschirmende Wirkung.


    Wie gesagt: KANN eine Ursache sein.

    Gaffatape und Chewing Gum kleben die halbe Welt zusamm'

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!