Impressum | Datenschutz | Shop | DIY | TT @ Twitter | TT-Cabs
Anzeigen der neuesten Beiträge

Entwicklung eines Midi-Switching-Systems auf Arduino-Basis

  • 145 Antworten
  • 77483 Aufrufe

0 Mitglieder und 1 Gast betrachten dieses Thema.

*

Offline kugelblitz

  • YaBB God
  • *****
  • 1.724
  • be seeing you...
Hab kurz mitgesnifft :)

scheinbar werden alle aktivierten, CC Nachrichten beim Wechsel am Out rausgeschrieben (für mich heißt das ATM alles was man per Midi konfigurieren kann :) ). Danke für den Tip... Jetzt weiß ich auch warum es mir nicht aufgefallen ist, er macht es nur wenn eine CC Nummer definiert ist, sonst schreibt er nichts raus. Als ich das letzte mal mitgesnifft hab war noch nichts konfiguriert :( BTW er sendet jeden Midi-steuerbaren/konfigurierten Tastendruck.

Wird Zeit daß ich ein Midi-In nachrüste, bzw meinen noch einmal überarbeite. Leider wirds etwas warten müssen, aber das eröffnet dann noch ganz andere Möglichkeiten.

Cool und danke noch einmal,
Sepp

Addon: Am Out kommen nur die Befehle vom Bedienpanel an aber nicht die per Midi gesendeten. Trotzdem nice, Du solltest so eigentlich ein TC electronic Teil auch zur Konfiguration Deines Controllers nutzen koennen, zumindest für Teile.

Addon2: Mods werden nicht versandt, zB in meinem Fall global in level... Am Gmaj2 funktioniert zumindest in meiner Konfig:

* Stati aller 6 Blöcke
* NoiseGate
* Bank
* Preset
* Mute
* Bypass
* Relay ring/tip

Was nicht funktioniert:
* EQ Status
* Modifier
« Letzte Änderung: 29.08.2013 00:19 von kugelblitz »

*

Offline Nils H.

  • YaBB God
  • *****
  • 3.067
Moin,

im folgenden mal der aktuelle Stand meiner Dokumentation für den Controller. Wie immer übernehme ich keine Garantie dafür, dass die Pläne und Layouts einhundertprozentig mit dem übereinstimmen, was ich gebaut habe.

Gruß, Nils

*

Online carlitz

  • YaBB God
  • *****
  • 1.727
  • never give up
Hallo Nils,

Danke für die Pläne.

Du hast ja noch viele Anschlüsse am Controller frei.

Ist es nicht einfacher das LCD direkt anzuschliessen und kein I2C zu nutzen ?

Gruß
If you don't know how to fix it, stop breaking it!

*

Offline Nils H.

  • YaBB God
  • *****
  • 3.067
Hallo Nils,

Danke für die Pläne.

Du hast ja noch viele Anschlüsse am Controller frei.

Ist es nicht einfacher das LCD direkt anzuschliessen und kein I2C zu nutzen ?

Gruß

Klar wäre das gegangen. Es gab irgend einen Grund, warum ich's über I²C gemacht habe, an den ich micht nicht erinnere - möglicherweise war's auch nur der übliche "weil's geht"-Grund  ;D , zusammen mit der Tatsache, dass eh alles über den Bus läuft. Nachdem die Busebene programmiertechnisch abstrahiert war, machte das, glaube ich, ehe keinen Unterschied mehr.

Geschwindigkeit ist kein Problem. Der Bus läuft mit 100 kHz (mehr machen die PFC nicht), aber das verwendete LCD ist eh um mehrere Größenordnungen langsamer, von daher ist's egal (wenn man das LCD zu schnell beschreibt, sieht man nix mehr, weil die Kristalle zu träge sind).

Gruß, Nils

*

Offline Nils H.

  • YaBB God
  • *****
  • 3.067
Moin,

in Plan und Layout hat sich ein Fehler eingeschlichen. Das Ausgangssignal des 6N139 liegt an Pin 6 an, nicht an 7. Dementsprechend gehören die eingezeichneten Verbindungen um einen Pin nach unten verschoben.

Gruß, Nils

*

Offline Markus H.

  • Starter
  • *
  • 7
Hallo!

Nachdem ich Nils H. angeschrieben hatte, weil ich extrem angetan von seinem Midi Controller Projekt bin und eine kleine Gruppe derzeit ebenfalls an einem ähnlichen projekt arbeitet, meinte Nils, es wäre doch nett, wenn ich darauf hier kurz verlinken würde, vielleicht interessiert es ja einige. Dem will ich jetzt hiermit nachkommen:

Wir bauen derzeit auf Arduino Basis einen Midi Controller. Wobei ich gleich sagen muss: Das Zugpferd, was die technische Programmierung angeht bin nicht ich, sondern der OSon aus dem axefx.de Forum.
Anyhow: Wer vielleicht genauso ein "Greenhorn" in Sachen Elektrotechnik und Software-Programmierung ist, wie ich, aber trotzdem vielleicht Interesse an einer solchen Eigenkonstruktion hätte, der kann ja gerne mal bei "uns" vorbeischauen, denn ich denke, das Projekt ist auch für absolute Einsteiger zumindest Nachbaubar ...

Hier zu den Infos:

Diskussion im axefx.de Forum: http://www.axefx.de/showthread.php/1040-DYI-MIDI-Fu%C3%9Fleiste-selber-bauen-!

Software auf github.com: https://github.com/oson/midi_board_ONE
(Nochmals größten Dank an den "Konstrukteur" OSon!!!

Video-Dokumentation auf youtube: http://www.youtube.com/watch?v=dIs-Xt1zd-U&list=PLT2sYJRe7JGzRZjYknhBgOrFEbOZDuBH5

Liebe Grüße
Markus

*

Offline Nils H.

  • YaBB God
  • *****
  • 3.067
Moin,

es gibt neues zu vermelden. Das Floorpedal verrichtet jetzt ja schon 'ne Weile seinen Dienst im Proberaum (Steuerung eines G-Major 2), über den Weihnachtsurlaub hatte ich jetzt mal Zeit, mich dem Racklooper zu widmen. Die Hardware ist heute (fast - siehe unten) fertig geworden, jetzt muss ich "nur noch" die Firmware schreiben.

Das sollte aber recht schnell gehen, denn ich werde die Software sehr "dumm" halten - Empfang auf MIDI-Kanal 1, 18 CCs für 18 Relais - fertig. Presets oder anderen Firlefanz brauche ich nicht, und ich will bis Sonntag fertig sein  ;D .

Zur Hardware: Ich habe meinen alten TB-Relaislooper geschlachtet und neue Platinen eingebaut. Daher bleibt es bei der alten Ausstattung - 3 Chains zu je 4 Loops, dazu 6 potentialfreie Schaltkontakte. Zu jedem Relais gibt es eine Status-LED, die sind hartverdrahtet parallel zu den Relaisspulen, also nicht programmierbar. Vorne gibt es ein Pedal In mit Phantompower, hinten MIDI-Through und -Out (im Moment nicht bestückt, weil auch nix gesendet wird). Die I/O-Platine ist so vorbereichtet, dass bis zu 32 Schaltsignale verarbeitet werden können, genutzt werden aber wie gesagt jetzt erst mal nur 18.

Was noch fehlt: Einschaltverzögerung für die Relais, Grund: Habe ich total vergessen  :devil: . Ich hatte das früher schon mal angesprochen, die Portexpander schalten beim Hochfahren einmal die Masse durch und alle Relais ziehen an. Ich habe auf dem AVR erst mal nur die Initialisierung des I²C-Busses programmiert; das Initialisieren des Controllers und des I²C-Busses dauert dann doch 2(!) Sekunden, d.h. für 2 Sekunden ziehen alle Relais an. Das ist natürlich doof.

Frage: Warum ist das so, dass das so lange dauert? Das Programm macht wirklich nichts außer den Bus zu initialisieren und in alle Expander eine 0 zu schreiben. Braucht der AVR wirklich so lange? (unabhängig davon braucht's natürlich trotzdem eine Einschaltverzögerung).

Anbei mal zwei Bilder, wie das Ding gerade neben mir steht, wie man sieht, hat das Chassis schon arg gelitten. Die LED-Leitungen muss ich noch strapsen und verlegen.

Gruß, Nils

*

Offline Dirk

  • Dirk M.
  • Administrator
  • YaBB God
  • *****
  • 12.963
  • 2T or not 2T
Hi,

wann wird denn der I2C initialisiert und kannst Du nicht auf die Portexpander verzichten ? 18 Ports gehen auf alle Fälle über den Atmega, oder müssen es am Ende wirklich 32 Ports sein ?

Ich habe mal eben bei mir getestet mit einem Programm, dass per I2C auf einen 24C... zugreift und eines ohne I2C Bus und in beiden Fällen ist der Atmega gleich ansprechbar ohne irgendwelchen Müll auf dem I2C zu produzieren. Zumindest konnte ich nichts feststellen.

Programmfehler ? Taktrate erhöhen oder Bus-Zugriff anders umsetzen ?

Gruß, Dirk
Für Support und Produktanfragen bitte das offizielle Kontaktformular im Shop verwenden. PMs werden nicht beantwortet.

*

Offline Nils H.

  • YaBB God
  • *****
  • 3.067
Moin Dirk,

18 Digitale Pins wird mit einem ATMEGA im DIL-Gehäuse aber eng... theoretisch hat er 23. Praktisch bleiben weniger über: zwei weg für serielle Schnittstelle, zwei für externen Oszillator, einen für Reset, dann ist man bei 18. Und dann ist keiner mehr frei für Status-LED oder so was. Finde ich doof.

Darüber hinaus war die Zielvorgabe, als ich die Platinen gebaut habe, mal: 16 Loops und 8 Schalter, da reicht ein ATMEGA eh nicht mehr aus. Ich hab das dann etwas runterskaliert, weil ich mein vorhandenes Material weiter nutzen wollte.

Jedenfalls: Wenn, dann kann ich auch eh gleich vier Expander verbauen, da kommt's dann eh nicht drauf an  ;D . Und: Weil's geht  ;) .

Das Programm führt im Moment nur die i2c_init()-Routine aus - Zwei Register beschreiben und alle PFC low setzen. Ich vermute, dass die PCF8574 so lange brauchen bis sie das erste Mal auf ein Telegramm vom AVR reagieren - lese gerade noch mal das Datenblatt. Der Bus läuft mit dem Maximum (vorgegeben durch die PCF) von 100 kHz.

Die Initialisierung kommt im Prinzip ausm Atmel-Datenblatt, sollte also korrekt sein. Ich hab wie gesagt die PCF8574 im Verdacht. Das alles ändert aber eh nix dran, dass erst mal alle Relais kurz anziehen, also Verzögerung muss eh sein.

Gruß, Nils

*

Offline Dirk

  • Dirk M.
  • Administrator
  • YaBB God
  • *****
  • 12.963
  • 2T or not 2T
Hi,

zum PCF8574 kann ich nichts weiter sagen. Ich habe auch leider keinen hier um mal selbst auszuprobieren. Hatte zwar auch mal an eine Porterweiterung gedacht, aber verworfen und zwischenzeitlich angefangen mir ein "Mainboard" für einen Mega128 zu entwerfen.

Keinen Atmega16 in der Schublade liegen ;-)

Du programmierst in C ?
Stelle doch mal das Programm hier ein.

Gruß, Dirk


Für Support und Produktanfragen bitte das offizielle Kontaktformular im Shop verwenden. PMs werden nicht beantwortet.

*

Offline Dirk

  • Dirk M.
  • Administrator
  • YaBB God
  • *****
  • 12.963
  • 2T or not 2T
und ganz vergessen: versuch mal Hans direkt zu kontaktieren. Der macht einiges mit den µC und kann vielleicht etwas dazu sagen - falls er nicht hier mit liest.

Gruß, Dirk

PS: da fällt mir noch ein konntest Du das Dumpen der Bank/Preset-Daten vom und zum µC realisieren ?
Für Support und Produktanfragen bitte das offizielle Kontaktformular im Shop verwenden. PMs werden nicht beantwortet.

*

Offline Nils H.

  • YaBB God
  • *****
  • 3.067
Du programmierst in C ?
Stelle doch mal das Programm hier ein.

Kein Problem. Ist überschaubar  ;D . Ich denke, an der markierten Stelle ("HIER HÄNGT'S") entstehen die 2 sekunden, hab's aber noch nicht genauer ausgeforscht. Mache ich aber noch. Mein Verdacht ist wie gesagt, dass der µC auf die erste Antwort des ersten Expanders wartet. Danach läuft alles wie Atze, will sagen: Für menschliche Wahrnehmung gehen dann alle Relais und LEDs gleichzeigig aus  ;D .

main.c:


#include "i2c.h" // Routinen für I²C-Bus einbinden

int main( void )
{
    i2c_init(); // I2C-Bus initialisieren
    return 0;
}

i2c.c:

void i2c_init (void)
{
    /* Bus Geschwindigkeit einstellen
     * Formel: F_CPU/(16+2*TWBR*Prescaler)
     * Prescaler Default: 1
     * TWBR = 0x48 = 73 ergibt 100 kHz bei 16 MHz CPU-Frequenz
     */
    TWSR=(0<<TWPS1)|(0<<TWPS0);
    TWBR = ((F_CPU/SCL_CLOCK)-16)/2;

    // Port Expander initialisieren
    // ***** HIER HÄNGT'S? ***** //
    PCF8574_set_outputs(0,0x00);
    PCF8574_set_outputs(1,0x00);
    PCF8574_set_outputs(2,0x00);
}

/*
 * START senden, Adresse senden, RW senden
 * Rückgabewert: 1 = gescheitert, 0 = ok
 */
uint8_t i2c_start (uint8_t typ, uint8_t adresse, uint8_t rw)
{
    uint8_t twst;
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // START Condition senden
    while (!(TWCR & (1<<TWINT)));

    twst = TW_STATUS & 0xF8; // Statusregister überprüfen
    if ( (twst != TW_START) && (twst != TW_REP_START)) return 1; // Slave reagiert nicht

    uint8_t adressByte = 0;
    adressByte = adresse << 1;
    adressByte |= rw; // R/W-Bit setzen

   
    /* Basisadresse ergänzen
     *
     * PCF8574A:    0 1 1 1 A2 A1 A0 RW = 0x70
     * EEPROM:     1 0 1 0 A2 A1 A0 RW = 0xA0
     *
     */
    switch (typ)
    {
        case IOEXPANDER:
        {
            adressByte |= 0x70;
            break;
        }
        case EEPROM:
        {
            adressByte |= 0xA0;
            break;
        }
    }

    // Slave-Adresse senden
    TWDR =adressByte; // Slave-Adresse senden
    TWCR = (1<<TWINT) | (1<<TWEN);
   
    // warten bis Übertragung beendet
    while(!(TWCR & (1<<TWINT)));
   
    // Statusregister überprüfen
    twst = TW_STATUS & 0xF8;
    if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

    return 0;
}


/*
 * START senden, Adresse senden, RW senden
 * Wenn Slave beschäftigt, warten bis frei
 */
void i2c_start_wait( uint8_t typ, uint8_t adresse, uint8_t rw)
{
    uint8_t twst;

    while ( 1 )
    {
        TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // START Condition senden
        while(!(TWCR & (1<<TWINT))); // warten bis Übertragung beendet

        twst = TW_STATUS & 0xF8; // Statusregister prüfen
        if ( (twst != TW_START) && (twst != TW_REP_START)) continue;

        uint8_t adressByte = 0;
        adressByte = adresse << 1;
        adressByte |= rw; // R/W-Bit setzen

        /* Basisadresse ergänzen
         *
         * PCF8574A:    0 1 1 1 A2 A1 A0 RW = 0x70
         * EEPROM:     1 0 1 0 A2 A1 A0 RW = 0xA0
         *
         */
        switch (typ)
        {
            case IOEXPANDER:
            {
                adressByte |= 0x70;
                break;
            }
            case EEPROM:
            {
                adressByte |= 0xA0;
                break;
            }
        }


        // Slave-Adresse senden
        TWDR =adressByte;
        TWCR = (1<<TWINT) | (1<<TWEN);
       
        // warten bis Übertragung beendet
        while(!(TWCR & (1<<TWINT)));

        // Statusregister überprüfen
        twst = TW_STATUS & 0xF8;
        if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) ) // Slave beschäftigt, STOP senden
        {
            TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
            while(TWCR & (1<<TWSTO)); // warten bis Bus frei
            continue;
        }
        break;
     }
}


/*
 * STOP senden
 */
void i2c_send_stop (void)
{
    /*
         * STOP Condition senden:
         *
         * TWINT durch setzen von 1 löschen
         * TWSTA = TWI STOP Condition Bit
         * TWEN = TWI Enable Bit
         *
         */
    TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
    while(!(TWCR & (1<<TWSTO))); // warten bis STOP gesendet
}



/*
 * Datenbyte senden
 * Rückgabewert: 1 = gescheitert, 0 = Byte übertragen
 */
uint8_t i2c_send_byte (uint8_t byte)
{
    uint8_t twst;
    TWDR = byte; // Datenbyte in TWI Datenregister schreiben
    TWCR = (1<<TWINT) | (1<<TWEN); // Inhalt des Datenregisters senden

    while (!(TWCR & (1<<TWINT))); // warten bis gesendet

    twst = TW_STATUS & 0xF8; // Statusregister prüfen
    if( twst != TW_MT_DATA_ACK) return 1;
    return 0;
}


void PCF8574_set_outputs (uint8_t adresse, uint8_t byte)
{
    i2c_start(IOEXPANDER,adresse,0);
    i2c_send_byte (byte);
    i2c_send_stop ();

}


*

Offline Thisamplifierisloud

  • YaBB God
  • *****
  • 754
Hossa,

warte mal 200-300ms, bevor Du den I2C-Bus und den PCF8574 initialisiert.
Der PCF8574 ist manchmal etwas ... störrisch.

Grüßle

Bernhard
Der den Argumentenverstärker trägt.

*

Offline Nils H.

  • YaBB God
  • *****
  • 3.067
und ganz vergessen: versuch mal Hans direkt zu kontaktieren. Der macht einiges mit den µC und kann vielleicht etwas dazu sagen - falls er nicht hier mit liest.

Gruß, Dirk

PS: da fällt mir noch ein konntest Du das Dumpen der Bank/Preset-Daten vom und zum µC realisieren ?

Wenn mir das richtig Sorge bereitet, mache ich das. Das prinzipielle Problem bleibt, die Expander sind nach demStartup High und somit schalten die ULN2803 durch, was die Relais anziehen lässt. Auch für 'ne halbe, viertel Sekunde oder weniger ist das doof, deswegen löte ich gerade eine kleine Einschaltverzügerung für die Relaisspannung zusammen.

Mit dem Thema EEPROM-Dumping hab ich mich beim Controller erst mal noch nicht weiter beschäftigt. Der grobe Fahrplan scheint zu sein, das mit geeigneter Software (MIDIOX oder selbst geschrieben) per Sysex zu machen. Umgesetzt habe ich da aber noch nix.

*

Offline Nils H.

  • YaBB God
  • *****
  • 3.067
Hossa,

warte mal 200-300ms, bevor Du den I2C-Bus und den PCF8574 initialisiert.
Der PCF8574 ist manchmal etwas ... störrisch.

Grüßle

Bernhard

Danke für den Hinweis. Das Grundproblem bleibt aber, die sind nach dem Einschalten erst mal High. Ob das dann 300ms oder 2s dauert ist latte, ich darf die Relaisspannung erst nach dem initialisieren freischalten.