Guitar Pedal Looper

Hallo Leute und guten Abend,

ich hoffe ich bin hier richtig! :slight_smile:
Ist mein erster Forumbeitrag.

Ich bastel gerade an einem Projekt bei dem ich nun nicht mehr weiter komme und hoffe auf Eure Hilfe.

Beschreibung:

Gitarren-Effektpedal-Looper.

Über mein Arduino Uno steure ich mithilfe von Tastern verschiedene Relais (im Testaufbau Leds) oder verschiedene Presets an. Dafür benutze ich einen Drehschalter mit drei Stellungen.

  1. Stellung: Relais-Auswahl

  2. Stellung: Relais-Auswahl als Preset auf einem der Taster speichern. (EEPROM.h)

  3. Stellung: Auswahl des vorher gespeicherten Presets.

Die Idee des Aufbaus und der Umsetzung stammt von:
CarraN

Link:

Mit diesem Code hat es auch alles so weit funktioniert, nur wollte ich es gerne um ein Relais erweitern.
Der Code basiert auf der keypad.h library . Da ich durch die Anzahl der Pins am Arduino begrenzt war hab mir extra Pins mit dem MCP23017 über I2C geschaffen. Zur Ansteuerung benutze ich die MCP23017 Library, da sie für mich schnell verständlich war. (Gute Erklärung vom Verfasser: ).

Ich hab den Code nun für meine Anwendung umgeschrieben und alles funktioniert wie gewollt, bis auf eine Sache- Ich kann alle 6 Relais ansteuern (Led on/off) und meine Auswahl als eines von 6 Presets speichern. Sobald ich aber die Presets wieder aufrufe sind Relais 1 - 5 richtig geschalten und Relais 6 ist immer aus (LOW). Ganz egal wie das Preset aussieht Relais 6 ist immer aus und das frustriert mich, da ich den Fehler nicht finden kann. Ich vermute, dass ich entweder einen Fehler beim Speichern in den EEPROM oder beim Auslesen des EEPROM habe.

Ich habe mal beide Codes angehangen als Zip.
Looper_test_file ist der umgeschriebene Code von mir, Five_pedals_looper ist der Original Code den ich mir als Vorlage genommen habe.
Ich hoffe ihr könnt mir helfen.

Lieben Gruß und vielen Dank !

EDIT: looper_test_file befindet sich nun 2 Posts weiter unten.
EDITEDIT:

#define MCP_ADDRESS 0x20 // (A2/A1/A0 = LOW) /*Libraries hinzugefügt*/
#include <Wire.h>
#include <MCP23017.h>
MCP23017 myMCP(MCP_ADDRESS,13);  /*Set Reset Pin 13*/
#include <EEPROM.h>              
#include <Keypad.h>

/**/

const byte rows = 6;              /*Manuelle Eingabe über Keypad*/
const byte cols = 3;
char keys[rows][cols] = {         /*Keypad funktion, bsp. Pin-Eingabe-Feld. Aufgebaut wie eine Matrix*/
{'a','g','m'},                    /*hier: 6Reihen; 3Spalten, daraus ergeben sich 18verschiedene Eingabe */
{'b','h','n'},                    /*Möglichkeiten. die Cols stehen für den Poti (3Positionen/"Mode")*/
{'c','i','o'},                    /*Rows sind die momentary switchs(Loop-Anwahl)*/
{'d','j','p'},                    /*s.u. 18 versch. "cases" a-r*/
{'e','k','q'}, 
{'f','l','r'},
};
byte rowPins[rows] = {2,3,4,5,6,7}; /*Arduino Ausgang*/
byte colPins[cols] = {8,9,10};     /*Arduino Ausgang */

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);


/******************************************************/

void setup()
{
  Serial.begin(9600);
  Serial.println();
  Serial.print("Loading...");
  Serial.println();
  
  /*digitalWrite(13,LOW);         /*Reset vom MCP23017*/
  /*delay(50);
  digitalWrite(13,HIGH);*/
  
  Wire.begin();
  myMCP.Init();
  
  for(int i=0; i<6; i++)
  {
    myMCP.setPortMode(B11111111, A); /*Port A - Relais alle Output*/
    myMCP.setPortMode(B11111111, B); /*Port B - LEDs alle Output*/
    myMCP.setPin(i, A, HIGH);
    delay(60);
    myMCP.setPin(i, A, LOW);
    myMCP.setPin(i, B, HIGH);
    delay(60);
    myMCP.setPin(i,B, LOW);
    }

  for(int i=4; i>0; i--)            /*buntes Farbspiel*/
  {
    myMCP.setPin(i, A, HIGH);
    delay(60);
    myMCP.setPin(i, A, LOW);
    myMCP.setPin(i, B, HIGH);
    delay(60);
    myMCP.setPin(i,B, LOW);
    }    
myMCP.setAllPins(A, HIGH);
myMCP.setAllPins(B, HIGH);
delay (500);
myMCP.setAllPins(A, LOW);
myMCP.setAllPins(B, LOW);


Serial.print("Ready!");
Serial.println();

/*readPreset(11, 1, 0);             /* initiate  default mode */

}

/*********************************************************/

int value;
int Addr;
void memory(int addr, int led)

{

  for(int i=0; i<6; i++)
  {
    value = EEPROM.read((addr)+ i);
    
    EEPROM.write((addr) + i, myMCP.getPin(i, A));
    myMCP.setPin(i, B, LOW); // all leds reset
    Serial.print("Relais ");
    Serial.print(i);
    Serial.print(" stat: ");
    Serial.print(value);
    Serial.println();

  }
  Serial.println();
  
  delay(100);
  myMCP.setPin((led), B, HIGH);
  delay(100); 
  myMCP.setPin((led), B, LOW);
  delay(100); 
  myMCP.setPin((led), B, HIGH);
  delay(100);
  myMCP.setPin((led), B, LOW);
  delay(100); 
  myMCP.setPin((led), B, HIGH);
  delay(100);
  myMCP.setPin((led), B, LOW);
  delay(100); 
  myMCP.setPin((led), B, HIGH);
  delay(100); 
  myMCP.setAllPins(B, HIGH);
  delay(500); 
  myMCP.setAllPins(B, LOW);
  
}

/*********************************************************/

void resetAllRelays()
{
  for(int i=0; i<6; i++)
  {
    myMCP.setPin(i, A, LOW);
  }
}

/*********************************************************/

void resetAllLeds()
{
  for(int i=0; i<6; i++)
  {
    myMCP.setPin(i, B, LOW);
  }
}

/*********************************************************/

int Pa;
void writeOut(int relay)

{
  resetAllLeds();
  myMCP.togglePin((relay), A); 
  
  for (int e=0; e<6; e++)
     { 
      Pa = myMCP.getPin(e, A);
      Serial.print("Pin ");
      Serial.print(e);
      Serial.print(" stat: ");
      Serial.print(Pa);
      Serial.println();
     }
  Serial.println();

/*  digitalWrite(ledPin[relay], !digitalRead(relayPin[relay]));       /*from Original Script*/
  /* thanks to  anton.efremoff.1 for this tip */

}

/*********************************************************/

void readPreset(int addr, int pcNum, int led)
{
  for(int i=0; i<6; i++)
  {
    myMCP.setPin(i, A, EEPROM.read((addr)+i));
    myMCP.setPin(i, B, LOW);
    myMCP.setPin((led), B, HIGH);
  }
}

/*********************************************************/

void loop()
{
  
  char key = keypad.getKey();
  if(key)                                   // Check for a valid key.
  {
   switch (key)
      { 
    case 'a':                                // a to x //"LoopMode"
      writeOut(0);                        // relay
      break; 
    case 'b': 
      writeOut(1);
      break;
    case 'c': 
      writeOut(2);
      break;
    case 'd': 
      writeOut(3);
      break;
    case 'e': 
      writeOut(4);
      break; 
    case 'f': 
      writeOut(5);
      break;   
    /****************************** "STORE PRESET MODE" */       
    case 'g': 
      memory(11,0);  //addr, led
      break; 
    case 'h': 
      memory(21,1);
      break;
    case 'i': 
      memory(31,2);
      break;
    case 'j': 
      memory(41,3);
      break;
    case 'k': 
      memory(51,4);
      break;
    case 'l': 
      memory(61,5);
      break;  
    /****************************** "READ PRESET MODE" */      
    case 'm':  
      readPreset(11, 1, 0); // addr, pcNum, led
      break; 
    case 'n':  
      readPreset(21, 2, 1);
      break;   
    case 'o': 
      readPreset(31, 3, 2);
      break;
    case 'p': 
      readPreset(41, 4, 3);
      break;
    case 'q': 
      readPreset(51, 5, 4);
      break;
    case 'r': 
      readPreset(61, 6, 5);
      break;     
      }
   }
}

five_pedals_looper.zip (4.05 KB)

bigsil:
Ich habe mal beide Codes angehangen als Zip.
Looper_test_file ist der umgeschriebene Code von mir, Five_pedals_looper ist der Original Code den ich mir als Vorlage genommen habe.
Ich hoffe ihr könnt mir helfen.

Dein looper_test_file fehlt.

Nur als Idee:
Du kannst alles, was Du in den eeprom schreibst auch parallel dazu auf dem seriellen Monitor ausgeben.
Andersherum geht es auch so. - auslesen und die Variable auf dem SerMon ausgeben.

Dann hast Du schon mal einen Ansatz, wo es klemmt.

Sorry komisch, wenn ich raufklicke öffnet es sich. Ich packe es einfach hier nochmal als Anhang ran.

Was ich nicht so ganz verstehe ist, dass wenn ich Taster 6 betätige leuchtet die zugehörige Led (Relais), aber im Programm ändert sich der Status nicht. Bei den andern 5 Tastern funktioniert es wie es soll und der Status an/aus ändert sich auch im seriellen Monitor, nur der Status von Nummer 6 bleibt bei 0, obwohl die Led leuchtet.

Hab Probiert den MCP23017 zu tauschen, hat aber nichts gebracht. Hatte auch ein Reset vor der Initialisierung probiert, hat aber auch nichts verändert. :confused:

Looper_test_file.zip (2.3 KB)

Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Hallo Tommy,

danke für deinen Tipp!

Hier also der Code im Post:

#define MCP_ADDRESS 0x20 // (A2/A1/A0 = LOW) /*Libraries hinzugefügt*/
#include <Wire.h>
#include <MCP23017.h>
MCP23017 myMCP(MCP_ADDRESS,13);  /*Set Reset Pin 13*/
#include <EEPROM.h>              
#include <Keypad.h>

/**/

const byte rows = 6;              /*Manuelle Eingabe über Keypad*/
const byte cols = 3;
char keys[rows][cols] = {         /*Keypad funktion, bsp. Pin-Eingabe-Feld. Aufgebaut wie eine Matrix*/
{'a','g','m'},                    /*hier: 6Reihen; 3Spalten, daraus ergeben sich 18verschiedene Eingabe */
{'b','h','n'},                    /*Möglichkeiten. die Cols stehen für den Poti (3Positionen/"Mode")*/
{'c','i','o'},                    /*Rows sind die momentary switchs(Loop-Anwahl)*/
{'d','j','p'},                    /*s.u. 18 versch. "cases" a-r*/
{'e','k','q'}, 
{'f','l','r'},
};
byte rowPins[rows] = {2,3,4,5,6,7}; /*Arduino Ausgang*/
byte colPins[cols] = {8,9,10};     /*Arduino Ausgang */

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);


/******************************************************/

void setup()
{
  Serial.begin(9600);
  Serial.println();
  Serial.print("Loading...");
  Serial.println();
  
  /*digitalWrite(13,LOW);         /*Reset vom MCP23017*/
  /*delay(50);
  digitalWrite(13,HIGH);*/
  
  Wire.begin();
  myMCP.Init();
  
  for(int i=0; i<6; i++)
  {
    myMCP.setPortMode(B11111111, A); /*Port A - Relais alle Output*/
    myMCP.setPortMode(B11111111, B); /*Port B - LEDs alle Output*/
    myMCP.setPin(i, A, HIGH);
    delay(60);
    myMCP.setPin(i, A, LOW);
    myMCP.setPin(i, B, HIGH);
    delay(60);
    myMCP.setPin(i,B, LOW);
    }

  for(int i=4; i>0; i--)            /*buntes Farbspiel*/
  {
    myMCP.setPin(i, A, HIGH);
    delay(60);
    myMCP.setPin(i, A, LOW);
    myMCP.setPin(i, B, HIGH);
    delay(60);
    myMCP.setPin(i,B, LOW);
    }    
myMCP.setAllPins(A, HIGH);
myMCP.setAllPins(B, HIGH);
delay (500);
myMCP.setAllPins(A, LOW);
myMCP.setAllPins(B, LOW);


Serial.print("Ready!");
Serial.println();

/*readPreset(11, 1, 0);             /* initiate  default mode */

}

/*********************************************************/

int value;
int Addr;
void memory(int addr, int led)

{

  for(int i=0; i<6; i++)
  {
    value = EEPROM.read((addr)+ i);
    
    EEPROM.write((addr) + i, myMCP.getPin(i, A));
    myMCP.setPin(i, B, LOW); // all leds reset
    Serial.print("Relais ");
    Serial.print(i);
    Serial.print(" stat: ");
    Serial.print(value);
    Serial.println();

  }
  Serial.println();
  
  delay(100);
  myMCP.setPin((led), B, HIGH);
  delay(100); 
  myMCP.setPin((led), B, LOW);
  delay(100); 
  myMCP.setPin((led), B, HIGH);
  delay(100);
  myMCP.setPin((led), B, LOW);
  delay(100); 
  myMCP.setPin((led), B, HIGH);
  delay(100);
  myMCP.setPin((led), B, LOW);
  delay(100); 
  myMCP.setPin((led), B, HIGH);
  delay(100); 
  myMCP.setAllPins(B, HIGH);
  delay(500); 
  myMCP.setAllPins(B, LOW);
  
}

/*********************************************************/

void resetAllRelays()
{
  for(int i=0; i<6; i++)
  {
    myMCP.setPin(i, A, LOW);
  }
}

/*********************************************************/

void resetAllLeds()
{
  for(int i=0; i<6; i++)
  {
    myMCP.setPin(i, B, LOW);
  }
}

/*********************************************************/

int Pa;
void writeOut(int relay)

{
  resetAllLeds();
  myMCP.togglePin((relay), A); 
  myMCP.getPort(A);
  
  for (int e=0; e<6; e++)
     { 
      Pa = myMCP.getPin(e, A);
      Serial.print("Pin ");
      Serial.print(e);
      Serial.print(" stat: ");
      Serial.print(Pa);
      Serial.println();
     }
  Serial.println();

/*  digitalWrite(ledPin[relay], !digitalRead(relayPin[relay]));       /*from Original Script*/
  /* thanks to  anton.efremoff.1 for this tip */

}

/*********************************************************/

void readPreset(int addr, int pcNum, int led)
{
  for(int i=0; i<6; i++)
  {
    myMCP.setPin(i, A, EEPROM.read((addr)+i));
    myMCP.setPin(i, B, LOW);
    myMCP.setPin((led), B, HIGH);
  }
}

/*********************************************************/

void loop()
{
  
  char key = keypad.getKey();
  if(key)                                   // Check for a valid key.
  {
   switch (key)
      { 
    case 'a':                                // a to x //"LoopMode"
      writeOut(0);                        // relay
      break; 
    case 'b': 
      writeOut(1);
      break;
    case 'c': 
      writeOut(2);
      break;
    case 'd': 
      writeOut(3);
      break;
    case 'e': 
      writeOut(4);
      break; 
    case 'f': 
      writeOut(5);
      break;   
    /****************************** "STORE PRESET MODE" */       
    case 'g': 
      memory(11,0);  //addr, led
      break; 
    case 'h': 
      memory(21,1);
      break;
    case 'i': 
      memory(31,2);
      break;
    case 'j': 
      memory(41,3);
      break;
    case 'k': 
      memory(51,4);
      break;
    case 'l': 
      memory(61,5);
      break;  
    /****************************** "READ PRESET MODE" */      
    case 'm':  
      readPreset(11, 1, 0); // addr, pcNum, led
      break; 
    case 'n':  
      readPreset(21, 2, 1);
      break;   
    case 'o': 
      readPreset(31, 3, 2);
      break;
    case 'p': 
      readPreset(41, 4, 3);
      break;
    case 'q': 
      readPreset(51, 5, 4);
      break;
    case 'r': 
      readPreset(61, 6, 5);
      break;     
      }
   }
}

bigsil:
Sorry komisch, wenn ich raufklicke öffnet es sich. Ich packe es einfach hier nochmal als Anhang ran.

AAhhh.

Du hast in dem File five_pedals_looper.zip das Looper_test_file.ino mit eingepackt.
Das ist ungünstig und verwirrt, wenn das nicht mit angegeben wird.

Ja, sorry. Nächste mal wird klarer beschriftet! :grinning:

Der Code, den ich nachträglich hinzugefügt habe, ist ein bisschen ordentlicher und aufgeräumter und mit Funktionen für den seriellen Monitor.

bigsil:
Ja, sorry. Nächste mal wird klarer beschriftet! :grinning:

Der Code, den ich nachträglich hinzugefügt habe, ist ein bisschen ordentlicher und aufgeräumter und mit Funktionen für den seriellen Monitor.

AAhhh - Danke. Ich schau gfls. noch drüber.

Ich versuche nochmal mit Bildern mein Problem zu verdeutlichen:

Ich wähle alle 6 Led's über meine Taster an:
Bild 1

Ich lasse mir über den seriellen Monitor gleichzeitig den Status der Led's ausgeben (obwohl ich den Status ja eigentlich sehen kann - Led's leuchten). Status aller Led's auf "1" außer Led 6 an Pin 5, Port A(MCP23017):
Bild 2

Zweiter Versuch:
Ich wähle Led 1 und 6 über die jeweiligen Taster an und Sie leuchten:
Bild 3

Wieder lass ich mir den Status der Led's ausgeben:
Bild 4

Led 1 = Status 1; Led 6 = Status 0 !?
aber Sie leuchtet doch, warum ist der Status immer 0?

Das Problem spielt sich logischerweise durch das ganze Programm, da wenn ich ein Preset abspeichern will, die Led 6 immer mit dem Status 0 abgespeichert wird, auch wenn sie angewählt war. Folglich ist beim Abrufen aller Presets der Status der Led immer 0.

Jetzt ist die Frage, wo ich den Fehler habe, das der Status von der Led 6 an Pin5, Port A (MCP23017) sich nicht ändert?

Hier der Ausschnitt meines Codes mit dem ich den Test gemacht habe, Leds anwählen, Status auslesen, etc.

int Pa;
void writeOut(int relay)

{
  
  resetAllLeds();
  myMCP.togglePin((relay), A);
  myMCP.getPort(A);
  
  for (int e=0; e<6; e++)
     { 
      Pa = myMCP.getPin(e, A);
      Serial.print("Pin ");
      Serial.print(e);
      Serial.print(" stat: ");
      Serial.print(Pa);
      Serial.println();
     }
  Serial.println();
  /*  
   *   
  digitalWrite(ledPin[relay], !digitalRead(relayPin[relay]));       /*from Original Script*/
  /* thanks to  anton.efremoff.1 for this tip */
}

EDIT:´Leider hat er die Bilder nicht mit in den Text genommen, also als .jpg im Anhang. Reihenfolge 1,2,3,4

Hier die Bilder sichtbar:

Bild 1:

Bild 2:

Bild 3:

Bild 4:

Sooooo.. ich schäme mich …

Die Led 6 hab ich versehentlich direkt an den Pin angeschlossen statt über den Widerstand (bin ein Loch verrutscht). Die Frustration wandelt sich nun in Ärger :slight_smile:
Manchmal reichen 20 Kontrollen nicht, da muss es die 21ste sein.
Der unbegrenzte Stromfluss hat scheinbar den MCP23017 durcheinander gebracht.

Der Code der im ersten Post ist, funktioniert wunderbar und lässt sich, für denjenigen den es interessiert, auch um je 2 Leds(Relais's), Leds(Presets) und Taster erweitern. Dafür muss nur das Keypad, die "Cases" und die Zahl in den for-Schleifen geändert werden.

Das war also meine erste Forum-Erfahrung :slight_smile:
Vielen Dank trotzdem Euch!!

Das Topic kann also geschlossen werden.

Gruß Silas

bigsil:
Sooooo.. ich schäme mich …

Warum? Tue es nicht.

Die Led 6 hab ich versehentlich direkt an den Pin angeschlossen statt über den Widerstand (bin ein Loch verrutscht). Die Frustration wandelt sich nun in Ärger :slight_smile:
Manchmal reichen 20 Kontrollen nicht, da muss es die 21ste sein.
Der unbegrenzte Stromfluss hat scheinbar den MCP23017 durcheinander gebracht.

Der Code der im ersten Post ist, funktioniert wunderbar und lässt sich, für denjenigen den es interessiert, auch um je 2 Leds(Relais's), Leds(Presets) und Taster erweitern. Dafür muss nur das Keypad, die "Cases" und die Zahl in den for-Schleifen geändert werden.

Na das ist doch eine Aussage, mit der die Nachwelt noch was anfangen kann.

Das war also meine erste Forum-Erfahrung :slight_smile:
Vielen Dank trotzdem Euch!!

Das Topic kann also geschlossen werden.

Du hast alles getan um hier Dein Vorhaben und das Problem darzustellen und jedem der es wollte alle norwendigen Infos gegeben.

Du hast selbst noch weiter daran gearbeitet, Du hast selbst die Lösung gefunden und zudem für alle, die es interessiert, auch noch diese präsentiert.

++++1