Midi controller problema a 9v

Ciao a tutti.
Ho appena finito uno switch midi a due bottoni con solo midi out, però ho un problema. Quando la board è alimentata tramite usb, funziona tutto correttamente. Nel momento in cui alimento l'arduino a 9v esterno sia con batteria, sia con alimentatore (ho provato anche a 6v e a 5) tramite l'ingresso dc, il comando midi mi parte a raffica. Premetto che utilizzo un'interfaccia midi Usb una di quelle economiche da 10 euro alla quale collego questa pedaliera a due switch. Il problema da come ho capito nasce dal pin 5v del midi out. Qua logicamente, ci va una resistenza da 220ohm, ma se ne metto almeno 420 Ohm non mi fa più il problema e funziona correttamente. Però ovviamente con tale resistenza potrei avere problemi su un qualsiasi altro ricevitore midi (in) visto che i mA sono dimezzati. Come potrei ovviare a questo problema? Magari è il regolatore della scheda a dar problemi, visto che è un clone di Arduino Uno preso da Amazon? Ah, una cosa importante. Quando mi fa il comando midi a raffica non è il TX sulla scheda Arduino a lampeggiare ma bensì il led del ricevitore, come se ricevesse continuamente l'impulso.

Finisco dicendovi come ho collegato il tutto.
-TX con 220ohm al pin relativo del Midi out
-5V con 220ohm al suo pin relativo sempre del Midi out.
-Ground al pin centrale sempre ancora del midi out.
Per i bottoni invece
Da un lato, il 5v direttamente. E dall'altro il ground con resistenza da 10k per fare pull down, e un altro cavo direttamente collegato al suo pin di riferimento su arduino.

Grazie!

PS. ho caricato questo video su Google Drive in modo tale da farvi vedere meglio il problema. Questo è il link:
https://drive.google.com/file/d/1F6YniXI059zQe6IX0YRVBpsQGRyMeDyv/view?usp=drivesdk

Allora, intanto quando hai un problema devi sempre includere anche il codice per capire meglio e magari darti qualche spunto per aiutarti a capire, perché è l'insieme di circuito+codice che determina il funzionamento. Postalo racchiudendolo nei tag "code" mi raccomando.

Secondo, più che un video (che va anche bene, magari se lo fai in orizzontale si capisce un po' più facilmente ;)) è sempre meglio se disegni lo schema esatto dei collegamenti, anche solo su carta e fotografato, ma l'ideale è sempre prendere pratica con qualche tool per disegnare il circuito sia per potertelo salvare per usi futuri, sia per mostrarlo a noi in modo più comprensibile.
Prova ad esempio Tinkercad circuits, è gratuito e ti permette anche di simulare i circuiti (con alcune limitazioni ma è comunque utilissimo anche per "sperimentare).

Terzo, passiamo ai cablaggi che vedo nel video. Non è (probabilmente) questo il problema, ma devo darti qualche consiglio secondo me utile.

Quando realizzi un prototipo devi farlo in modo più gestibile, scusa se te lo dico (ovviamente lo faccio bonariamente ;)) ma non si possono vedere quei "pastrocchi" di cavetti (che sarebbero per prototipazione) saldati tra loro, piegati, e tenuti assieme con nastro carta! Tra l'altro con tutte quelle saldature fai anche fatica a cambiare eventualmente qualcosa, come la resistenza verso il connettore MIDI.
Se non ce l'hai ancora (e suppongo che tu non ce l'abbia altrimenti l'avresti già usata) acquista una qualsiasi breadboard, anche non grande, e usa quella, con cavetti "puliti", butta via quelli che hai saldato e magari acquista una matassina di filo elettrico per circuiti da usare "a misura"... Per il connettore MIDI potresti anche usare 3 cavetti Dupont nuovi (se vuoi mantieni le resistenze da 220 Ohm direttamente sul connettore, tanto è lo "standard") così dall'altra parte puoi innestarli direttamente sulla breadboard. Di fatto, tranne qualche caso dove non se ne può fare a meno, per i prototipi puoi (devi) evitare di usare il saldatore.

Poi una volta che il prototipo su breadboard funziona, la cosa a mio avviso più semplice e pulita che si possa fare è usare un qualsiasi "proto-shield" ad esempio come QUESTA (si, anche io acquisto da AZdelivery) ossia una shield (che si innesta sopra ad Arduino) che tra l'altro ti dà anche una mini breadboard per piccoli prototipi come il tuo (se hai solo 2 pulsanti). La protoshield come vedi ha anche le piazzole "millefori" (non solo) su cui puoi saldare i componenti, connettori, cavi, o altro. Ma evita tutti quei filacci saldati "volanti", nastro adesivo e quant'altro, impara a fare le cose "pulite" e vedrai che ti troverai molto meglio.

Ora facci vedere il codice, e se possibile disegnati il circuito su Tinkercad e postaci qui l'immagine del circuito così cerchiamo di aiutarti.

Grazie mille per il tuo intervento. Potevi dirmi senza problemi che il pastrocchio era na mezza schifezza, tanto fa schifo anche a me figurati ahahah . A parte gli scherzi, So benissimo tutto quello che mi hai scritto, anche se è solo un mese che utilizzo arduino: conosco bene che dovrei utilizzare una bredboard che sta per arrivarmi, conosco bene tinkercard ma che però non ho potuto utilizzare visto che non contiene il connettore midi out ed è per questo che ho scritto a penna le connessioni (che ti metterò sotto) , molto velocemente. Dovete scusarmi se tutto è fatto in modo molto abbozzato, ma durante questo periodo, in ospedale siamo senza sosta ed ho pochissimo tempo.
Ritornando al problema, questo è il codice che utilizzo che ho trovato su un blog denominato Notes and Volts: Problema midi 9v - Pastebin.com
Messe su pastebin perché troppo lungo

E queste sono le connessioni (scusate se le ho scritte così a penna, presumo che però sono capibili:

tonynapoli2309:
conosco bene che dovrei utilizzare una bredboard che sta per arrivarmi

Bene, comunque sia io ti consiglio caldamente di prendere anche una o due protoshield, magari proprio quelle di AZDelivery e che uso anche io stesso: una con la mini breadboard incollata sopra, per fare piccoli progetti, l'altra per poterla usare poi per il progetto "definitivo" evitandomi di fare

conosco bene tinkercard ma che però non ho potuto utilizzare visto che non contiene il connettore midi out ed è per questo che ho scritto a penna le connessioni (che ti metterò sotto) , molto velocemente.

Beh ma Tinkercad è comodo non solo per simulare, cosa che nel tuo caso non potevi fare ovviamente, ma anche per disegnare il circuito e tenerlo memorizzato. Inoltre anche se non puoi simulare esattamente il MIDI, in fondo è una scrittura su seriale per cui ti basta anche vedere cosa esce dal monitor seriale...

Messe su pastebin perché troppo lungo

Fai prima a metterlo qui come allegato (clicca sotto all'editor su "Attachments and other options").
In ogni caso ci manca anche il file "Controller.h", dove c'è il metodo che rileva la pressione dei pulsanti: metti entrambi come allegato così abbiamo tutti i dati.

E queste sono le connessioni (scusate se le ho scritte così a penna, presumo che però sono capibili:

Va benissimo anche così! :slight_smile:

Sì, mi ero dimenticato. Nello sketch ci sono altre due schede aperte

Una è **Controller.cpp **

#include "Controller.h"

//****************************************************************************************
Mux::Mux(byte outpin_, byte numPins_, bool analog_)
{
  outpin = outpin_;
  //enablepin = enablepin_;
  numPins = numPins_;
  analog = analog_;
  if (analog == false) pinMode(outpin, INPUT_PULLUP);
  //pinMode(enablepin, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  if (numPins > 8) pinMode(5, OUTPUT);
}
//****************************************************************************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
Button::Button(byte pin, byte command, byte value, byte channel, byte debounce)
{
  _pin = pin;
  pinMode(_pin, INPUT_PULLUP);
  _value = value;
  _command = command;
  _debounce = debounce;
  _time = 0;
  _busy = false;
  _status = 0b00000010;
  _last = 1;
  Bcommand = command;
  Bvalue = value;
  Bchannel = channel;
  Btoggle = 0;
}

Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce)
{
  _pin = mux.outpin;
  _numMuxPins = mux.numPins;
  _muxpin = muxpin;
  _value = value;
  _command = command;
  _debounce = debounce;
  _time = 0;
  _busy = false;
  _status = 0b00000010;
  _last = 1;
  Bcommand = command;
  Bvalue = value;
  Bchannel = channel;
  Btoggle = 0;
}

void Button::muxUpdate()
{
  byte temp = _muxpin;
  temp = temp << 2;
  if (_numMuxPins > 8) PORTD = PORTD & B11000011;
  else PORTD = PORTD & B11100011;
  PORTD = PORTD | temp;
}

byte Button::getValue()
{
  // If BUSY bit not set - read button
  if (bitRead(_status, 0) == false) { // If busy false
    if (digitalRead(_pin) == _last) return 2; // If same as last state - exit
  }

  // If NEW Bit set - Key just pressed, record time
  if (bitRead(_status, 1) == true) { // If new is true
    bitSet(_status, 0); // Set busy TRUE
    bitClear(_status, 1); // Set New FALSE
    _time = millis();
    return 255;
  }

  // Check if debounce time has passed - If no, exit
  if (millis() - _time < _debounce) return 255;

  // Debounce time has passed. Read pin to see if still set the same
  // If it has changed back - assume false alarm
  if (digitalRead(_pin) == _last) {
    bitClear(_status, 0); // Set busy false
    bitSet(_status, 1); // Set new true
    return 255;
  }

  // If this point is reached, event is valid. return event type
  else {
    bitClear(_status, 0); // Set busy false
    bitSet(_status, 1); // Set new true
    _last = ((~_last) & 0b00000001); // invert _last
    return _last;
  }
}

void Button::newValue(byte command, byte value, byte channel)
{
  Bvalue = value;
  Bcommand = command;
  Bchannel = channel;
}

//********************************************************************
Pot::Pot(byte pin, byte command, byte control, byte channel)
{
  _pin = pin;
  _control = control;
  _value = analogRead(_pin);
  _value = _value >> 3;
  _oldValue = _value << 3;
  _value = _value << 3;
  Pcommand = command;
  Pcontrol = control;
  Pchannel = channel;
}

void Pot::muxUpdate()
{
  byte temp = _muxpin;
  temp = temp << 2;
  if (_numMuxPins > 8) PORTD = PORTD & B11000011;
  else PORTD = PORTD & B11100011;
  //PORTD = PORTD & B11000011;
  PORTD = PORTD | temp;
}

Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte channel)
{
  _pin = mux.outpin;
  _numMuxPins = mux.numPins;
  _muxpin = muxpin;
  _control = control;
  muxUpdate();
  _value = analogRead(_pin);
  _value = _value >> 3;
  _oldValue = _value << 3;
  _value = _value << 3;
  Pcommand = command;
  Pcontrol = control;
  Pchannel = channel;
}

byte Pot::getValue()
{
  _value = analogRead(_pin);
  int tmp = (_oldValue - _value);
  if (tmp >= 8 || tmp <= -8) {
    _oldValue = _value >> 3;
    _oldValue = _oldValue << 3;
    return _value >> 3;
  }
  return 255;
}

void Pot::newValue(byte command, byte value, byte channel) {
  Pcommand = command;
  Pcontrol = value;
  Pchannel = channel;
}

L'altra è Controller.h

#ifndef Controller_h
#define Controller_h
#include <Arduino.h>
//***********************************************************************
class Mux
{
  public:
    Mux(byte outpin_, byte numPins_, bool analog_);
    byte outpin;
    byte numPins;
    bool analog;
};
//************************************************************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
class Button
{
  public:
    Button(byte pin, byte command, byte value, byte channel, byte debounce);
    Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce);
    byte getValue();
    void muxUpdate();
    void newValue(byte command, byte value, byte channel);
    byte Bcommand;
    byte Bvalue;
    byte Bchannel;
    byte Btoggle;
  private:
    byte _previous;
    byte _current;
    unsigned long _time;
    int _debounce;
    byte _pin;
    byte _muxpin;
    byte _numMuxPins;
    byte _value;
    byte _command;
    bool _busy;
    byte _status;
    byte _last;
    byte _enablepin;
};
//*************************************************************************
class Pot
{
  public:
    Pot(byte pin, byte command, byte control, byte channel);
    Pot(Mux mux, byte muxpin ,byte command, byte control, byte channel);
    void muxUpdate();
    void newValue(byte command, byte value, byte channel);
    byte getValue();
    byte Pcommand;
    byte Pcontrol;
    byte Pchannel;
  private:
    byte _pin;
    byte _muxpin;
    byte _numMuxPins;
    byte _control;
    int _value;
    int _oldValue;
    bool _changed;
    byte _enablepin;
};
//*************************************************************************
#endif

Non e' necessario usare tutto quel codice. Ho modificato il post in quanto mi era sfuggito che avevi scritto che lo hai trovato sul blog Notes and Volts.
Per inviare 2 semplici comandi midi e' sufficiente aprire la seriale a 31250 baudrate e inviare il comando che serve.
Dal lato elettrico in trasmissione sono sufficienti le 2 resistenze da 220 ohm, una dal +5V che va al piedino 4 del connettore midi, e il segnale su quella che collegherai al piedino 5, in quanto il circuito e' in current loop e dalla parte del ricevitore ti troverai il fotoaccoppiatore che ricevera' i dati trasmessi, esattamente come hai esposto nel circuito che hai disegnato a mano libera.

Con 4 righe di programma te ne esci

Pasquale

Ciao Pasquale, grazie della risposta.
In verità questo è solo un embrione di quella che sarà una vera e propria pedaliera con 8 pulsanti e una connessione con Jack 1/4 per metterci il pedale d'espressione. Anche in questo caso potrei sfoltire e utilizzare il codice molto più basilare come dici tu?

Certo che puoi semplificare, soprattutto visto che usi "solo" pulsanti (il che significa solo replicare il codice o parametrizzarlo per 8 valori tramite un array). Per il pedale poi in fondo è solo un potenziometro, non dovresti trovare grosse difficoltà ad implementarlo (se hai problemi, chiedi pure qui nel forum ovviamente).

Parti da un esempio più semplice, in rete trovi parecchi esempi come QUESTO diciamo o QUESTO (sono solo un paio di quelli che ho trovato cercando "arduino midi out note").

Ovvio che puoi, invece di 4 righe diventano il numero di righe per controllare la pressione dei pulsanti che ti servono e il controllo dell'ingresso analogico per il potenziometro del pedale d'espressione. Nel caso del pedale d'espressione andrai a fare l'OR logico del valore del pedale e il comando che devi inviare, quindi al variare della posizione del pedale, memorizzi il nuovo valore in una variabile che ti servira' per il successivo controllo, fai l'OR e invii sulla seriale, nulla di piu' semplice

Ricordati solo che il procollo midi per quel che riguarda il valore va da 0 a 127, quindi solo 7bit che ovviamente andrai a parametrizzare con opportune tabelle e/o operatori logici e divisori.

Pasquale

pascal69:
Ricordati solo che il procollo midi per quel che riguarda il valore va da 0 a 127, quindi solo 7bit che ovviamente andrai a parametrizzare con opportune tabelle e/o operatori logici e divisori.

Beh non mi sembra così complicato se legge il potenziometro da un ingresso analogico che va da 0 a 1023, gli basta usare una map() e quindi confrontare il precedente valore con quello corrente:

...
byte curVolume = -1;
byte prevVolume = -1;
...
void loop()
{
...
  curVolume = map(analogRead(PIN_PEDALE), 0, 1024, 0, 128);
  if (volume != prevVolume)
  {
    // Mando il nuovo valore come CC 07
...
    prevVolume = curVolume;
  }
...

Non ho detto ch era complicato, gliel'ho solo ricordato, Una semplice divisione per 8 del valore letto eviterebbe persino la map.

Pasquale

Grazie comunque per le vostre risposte. Seguirò quanto detto da voi in vista dell'ampliamento di questo progetto ma pare che il problema sia dovuto al fotoaccoppiatore del ricevente midi che utilizzavo. Infatti sostituendo l'interfaccia Midi con una di qualità un po' Superiore, con 220 ohm sulla 5 volt del pin 5 volt della Midi out tutto funziona bene.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.