Go Down

Topic: Midi Daten mit Arduino live bearbeiten? (Read 3743 times) previous topic - next topic

stoni99

Gute Idee!

So mache ich das. Danke für den Tip!

stoni99

Hmm, geht leider nicht - zeigt bei allen Geschwindigkeiten nur Datenmüll an... :(

stoni99

Ist mir eben aufgefallen:

Ich muss ja die USB-Leitung vom Keyboard zum UNO galvanisch trennen da der USB Typ B Ausgang am Keyboard keine 5V USB-Spannung rausgibt und ich daher eine Fremdspannungsversorgung für den UNO vornehmen muss.

Kennt jemand einen FTDI232 mit eingebauter galvanischer Trennung?  :o

stoni99

Kann nichts Entkoppelndes finden.

Hat noch niemand so etwas gebaut?  :o

Wie sieht das mit dem Arduino USB Host Shield aus? Steht ja in der Beschreibung:

The following device classes are supported by the shield:
HID devices: keyboards, mice, joysticks, etc.
....

Aber eine galvanische Trennung kann ich im Schaltplan nicht finden.
Wird dort ein möglicher Crash von Spannungen aus verschiedenen Quellen ignoriert oder kennen die eine bessere Möglichkeit der Entkopplung?

ArduFE

Hallo,

The following device classes are supported by the shield:
HID devices: keyboards, mice, joysticks, etc.
....
Ich glaube da ist mit Keyboard eine normale USB-Tastatur gemeint. Ob das USB Host Shield Midi kann, konnte ich in der Doku nicht herausfinden. Von meinen ARM Boards können zwar einige als USB-Host arbeiten, aber keines davon kann Midi.

Statt in ein USB Host Shield würde ich eher in ein Board investieren, das selber USB Midi kann, also Leonardo, Micro oder Teensy.

Das Keyboard würde ich dann normal über USB an den Computer hängen, den Arduino auch. Dann müsste man nur noch eine PC Software dazu bringen die Midi Daten vom Keyboard an den Arduino zu senden. Der kann die empfangen, ändern und als seine eigene Midi Ausgabe zurücksenden.

Aber wie gesagt, ich bin kein Musiker. Nur in der Doku vom Teensy sieht das mit Midi nicht so kompliziert aus.
http://pjrc.com/teensy/td_midi.html

stoni99

...Statt in ein USB Host Shield würde ich eher in ein Board investieren, das selber USB Midi kann, also Leonardo, Micro oder Teensy....
Ja, hab ich auch schon überlegt --> dann habe ich aber immer noch nicht das Problem mit der galvanischen Trennung gelöst..



...Das Keyboard würde ich dann normal über USB an den Computer hängen, den Arduino auch. Dann müsste man nur noch eine PC Software dazu bringen die Midi Daten vom Keyboard an den Arduino zu senden. Der kann die empfangen, ändern und als seine eigene Midi Ausgabe zurücksenden....
Naja:
Grund meines Vorhabens ist ja den Velocity Wert meines Keyboards etwas anzuheben um den Klang zu verbessern.
Ich habe schon versucht nur mit PC Software das Problem intern zu lösen. Leider erhöhte sich die Latenzzeit dermaßen daß man es nicht mehr gebrauchen kann.
Daher kam meine Überlegung dies "inline" mit einem Arduino zu lösen.

ArduFE

Solange alles vom gleichen PC über USB versorgt wird, sehe ich da kein Problem der galvanischen Trennung.


Das mit der Latenz habe ich schon befürchtet, allerdings sehe ich für "inline" keine wirklich einfache Lösung. Als Arduinos, die man in die USB-Verbindung zwischenschaltet, die also dem Keyboard einen Host bieten und sich dem PC als Keyboard präsentieren kommen wohl nur der Zero, der Due und der Teensy 3.6 infrage.

Beim Teensy ist die USB-Host Library noch nicht fertig, beim Due ist sie wohl eine ungepflegte Dauerbaustelle und über den Zero weiß ich so gut wie gar nix.


Am einfachsten wäre möglicherweise eine reine PC Lösung, sprich in C++ selber was schreiben, falls man z.B. für diese RS232 Midi Bridges Quellcode findet, den man als Vorlage nehmen könnte.

stoni99

Solange alles vom gleichen PC über USB versorgt wird, sehe ich da kein Problem der galvanischen Trennung.
Mein Keyboard wird mit einem extra Netzteil stromversorgt. Mein PC auch wieder extra.

Und trotzdem sind beide durch ein USB-Kabel verbunden - ohne galvanische Trennung - wie mir scheint.
Ich kann auch mein Tablet (Batteriebetrieb) direkt an das Keyboard anschliessen - wieder ohne galvanische Trennung.

Lassen die es der Einfachheit halber weg oder kennen die Trick 17?

Tommy56

Da mit Sicherheit die 5V der einzelnen Geräte nicht verbunden werden, nur die GND sollte es keine Probleme genen. Die Potentialdifferenz der Quell-GND (der Geräte) dürfte so gering sein, dass keine nennenswerten Ausgleichsströme fließen.
Der Laptop hängt bei Akkubetrieb sowieso in der Luft und wird von der gemeinsamen GND-Verbindung auf gemeinsames Potential gelegt.

Da ist keine Potentialtrennung notwendig.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

stoni99

Will nicht funktionieren.  :)

Habe mal versucht die vom Keyboard gesendeten USB MIDI Daten im fremdspannungsversorgten UNO (USB-Buchse) einzulesen.
Egal welche Baudrate ich einstelle: Ich empfange nix.

Hat noch jemand einen Tip für mich?

Code: [Select]

#include <Wire.h>
#include "Adafruit_MCP23008.h"

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>



#define TFT_CS     10
#define TFT_RST    9  // you can also connect this to the Arduino reset
                      // in which case, set this #define pin to 0!
#define TFT_DC     8
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);

#define BUTTON_NONE 0
#define BUTTON_DOWN 1
#define BUTTON_RIGHT 2
#define BUTTON_SELECT 3
#define BUTTON_UP 4
#define BUTTON_LEFT 5

// Option 2: use any pins but a little slower!
#define TFT_SCLK 13   // set these to be whatever pins you like!
#define TFT_MOSI 11   // set these to be whatever pins you like!





// Basic pin reading and pullup test for the MCP23008 I/O expander
// public domain!

// Connect pin #1 of the expander to Analog 5 (i2c clock)
// Connect pin #2 of the expander to Analog 4 (i2c data)
// Connect pins #3, 4 and 5 of the expander to ground (address selection)
// Connect pin #6 and 18 of the expander to 5V (power and reset disable)
// Connect pin #9 of the expander to ground (common ground)

// Input #0 is on pin 10 so connect a button or switch from there to ground

Adafruit_MCP23008 mcp;

bool S_state;
bool G_state;
bool R_state;
bool S_laststate;



byte noteOn = 144;

byte noteToCheck = 60;



 
void setup() { 
Serial.begin(115200);

   
  tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
  tft.fillScreen(ST7735_BLACK);     //Display löschen
  tft.setRotation(-1);              //Displayrichtung einstellen
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(1);
  tft.println("Erkennen Mididaten USB");
  delay(1500);
  tft.fillScreen(ST7735_BLACK);     //Display löschen
   
}




void loop(){
  checkForNote();
  delay(10);
}





void checkForNote(){
  while (Serial.available()){//while there is serial data availble
   
    byte incomingByte = Serial.read();//read first byte
    tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
    tft.fillScreen(ST7735_BLACK);     //Display löschen
    tft.setRotation(-1);              //Displayrichtung einstellen
    tft.setTextColor(ST7735_WHITE);
    tft.setTextSize(1);
    tft.println(incomingByte);
    //delay(500);
    tft.fillScreen(ST7735_BLACK);     //Display löschen
    if (incomingByte>127){//if a command byte
   
      if (incomingByte == noteOn){//if note on message
     
        byte noteByte = Serial.read();//read next byte
        byte velocityByte = Serial.read();//read final byte


        if (noteByte == noteToCheck && velocityByte > 0){//note on
          tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
          tft.fillScreen(ST7735_BLACK);     //Display löschen
          tft.setRotation(-1);              //Displayrichtung einstellen
          tft.setTextColor(ST7735_WHITE);
          tft.setTextSize(1);
          tft.println("Note erkannt:");
          tft.println(noteByte);
          tft.println(velocityByte);
          delay(1500);
          tft.fillScreen(ST7735_BLACK);     //Display löschen
        }

     
      }
    }
  }
}



ArduFE

Ähem,

Code: [Select]
 
while (Serial.available()){//while there is serial data availble
   
    byte incomingByte = Serial.read();//read first byte
    tft.initR(INITR_BLACKTAB);   // initialize a ST7735S chip, black tab
    tft.fillScreen(ST7735_BLACK);     //Display löschen


bei jedem Byte, das reinkommt, das Display neu initialisieren ? Das meinst du sicher anders ...

stoni99

Ja, das ist nur ein Test-Code von einem anderen Projekt kopiert und etwas angepasst.

Trotzdem müsste ja was ankommendes angezeigt werden...

ArduFE

#42
Dec 28, 2016, 02:02 pm Last Edit: Dec 28, 2016, 02:33 pm by ArduFE
Dann probier mal, ob etwas angezeigt wird, wenn du mit dem seriellen Monitor der Arduino IDE etwas sendest.

Ansonsten wird der Uno natürlich nur serielle Daten empfangen. Es muss also dieses Midi Bridge Programm auf dem PC die Daten umwandeln und an die richtige serielle Schnittstelle schicken.


Edit:
Habe gerade mal das Beispiel aus der Arduino IDE unter
Datei | Beispiele | Teensy | USB_Midi | PrintIncoming
geladen, dann unter Werkzeuge | USB Type: | "Serial + Midi"
eingestellt und mit angeschlossenem Teensy 3.2 übersetzt.

Es kommt auch gleich der "Gerät wird installiert" Dialog von Windows, danach steht im Gerätemanager unter "Audio, Video und Gamecontroller" der Eintrag "Teensy Midi".

Das würde also schon mal gehen ...

Übrigens ganz schön fett, so ein USB-Midi, die IDE schreibt
Quote
Der Sketch verwendet 19.212 Bytes (7%) des Programmspeicherplatzes. Das Maximum sind 262.144 Bytes.
Globale Variablen verwenden 6.204 Bytes (9%) des dynamischen Speichers, 59.332 Bytes für lokale Variablen verbleiben. Das Maximum sind 65.536 Bytes.

gregorss

#43
Dec 28, 2016, 02:44 pm Last Edit: Dec 28, 2016, 02:45 pm by gregorss
Trotzdem müsste ja was ankommendes angezeigt werden...
Ich habe mal in alten Programmen gewühlt und einen uralten Testcode ausgegraben:

Code: [Select]
// MIDI

// Anschluss (DIN-Buchse von der Lötseite/hinten gesehen):
// - Der mittlere Anschluss ist mit der Abschirmung verbunden
//   und geht an GND
// - Der rechte Anschluss geht über einen 220-Ohm-Widerstand
//   an +5V
// - Der linke Anschluss geht an TX bzw. RX

byte blinkpin=13;
byte anaus=1;
byte cmd, note, velocity;

void setup()
{
  Serial.begin(31250);
  pinMode(blinkpin, OUTPUT);
}

void loop()
{
//      cmd=
  for(note=0x1e; note < 0x5a; note++)
  {
      cmd=0x90;
      velocity=127;

      midi_send(cmd, note, velocity);
      flash();
      delay(100);

      midi_send(cmd, note, 0);
  }
 
  delay(1);
}


und

Code: [Select]
void midi_send(int cmd, int pitch, int velocity)
{
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}


und

Code: [Select]
void flash()
{
  digitalWrite(blinkpin, HIGH);
  delay(10);
  digitalWrite(blinkpin, LOW);
}


HTH

Gregor
Mir wird übel. (Uwe)

stoni99

#44
Dec 28, 2016, 04:47 pm Last Edit: Dec 28, 2016, 04:56 pm by stoni99
Wenn ich mit der Arduino IDE über den ser. Monitor sende zeigt mir den UNO dies auch an.

Erst über eine Bridge senden geht nicht - der Ono soll ja die Keyboard-Daten abfangen und modifiziert weitersenden.

Der Teensy hat wohl schon von Hause aus USB-Midi drin?!
Evtl. klappt es mit dem besser? Hab aber momentan keinen...

Teensy 2.0 oder ++2.0 oder 32bit ?

Go Up