Go Down

Topic: Midi Footcontroller switch problem (Read 8290 times) previous topic - next topic

gregchill

Cool Mike thanks!!,

Just for cleaning up the code is it possible to read both pins A1 and A5 in the void loop.
Code: [Select]
void loop()
{
  a=readButtons(5);
  //lcd.clear();
  if (a==0 && notePlaying){
    playNote(0); // turn off the note
    notePlaying = false;
   
  }   
else
    if (a>0 && !notePlaying) // someone pressed a button!
    {
      notePlaying = true; // indicate the note is playing
      playNote(a); //go and play note
    }

   
     a=readButtons(1);
  //lcd.clear();
  if (a==0 && notePlaying){
    playNote(0); // turn off the note
    notePlaying = false;
   
  }   
else
    if (a>0 && !notePlaying) // someone pressed a button!
    {
      notePlaying = true; // indicate the note is playing
      playNote(a); //go and play note
    }
}


to something like a=readButtons(1&5);

Grumpy_Mike

No each analogue input must be put into a variable one at a time. If you use the same variable one after the other then you are just throwing the first variable away.

gregchill

Hi,

This is all working fine until i press 2 buttons together then it does nothing what i want it to do is when one button is pressed then the second button is pressed it activates switch three and sends 2 cc messages, it is picking up an analog reading for switch 3 (when the 2 buttons are pressed together) but not sending the message is there a boolean for making this work?

Code: [Select]
// Example 25.3

//define DEBUG
int a=0;
boolean notePlaying;
boolean notePlaying1;
void setup()
{
 // lcd.begin(20, 4);
 Serial.begin(31250);
 
  pinMode(A5, INPUT); // sets analog pin for input

}

int readButtons(int pin)
// returns the button number pressed, or zero for none pressed
// int pin is the analog pin number to read
{
  int b,c = 0;
  c=analogRead(5); // get the analog value
  if (c<50)
  {
    b=0;
    // buttons have not been pressed
  }   
else
  if (c>500 && c<550)
  {
    b=1;
    // button 1 pressed
  }     
  else
    if (c>180 && c<200)
    {
      b=2;
     
      // button 2 pressed
    }       
    else
      if (c>555 && c<580)
      {
        b=3; // button 3 pressed
      }         
   
         
return b;
}

int readButtons1(int pin1)
// returns the button number pressed, or zero for none pressed
// int pin is the analog pin number to read
{
  int b,c = 0;
  c=analogRead(pin1); // get the analog value
  if (c<50)
  {
    b=0;
    // buttons have not been pressed
  }   
else
  if (c>500 && c<550)
  {
    b=1;
    // button 1 pressed
  }     
  else
    if (c>180 && c<200)
    {
      b=2;
     
      // button 2 pressed
    }       
    else
      if (c>555 && c<580)
      {
        b=3; // button 3 pressed
      }         
   
         
return b;
}
void playNote(int button){
switch(button){
  // add the other case statements for the other buttons.
  case 0:
    midiCc(1, 80, 0);
    midiCc(1, 82, 0);
    midiCc(1, 83, 0);
    break;
  case 1:
      midiCc(1, 80, 127);
      break;
  case 2:
      midiCc(1, 82, 127);
      break;
  case 3:
      midiCc(1, 80, 127);
      midiCc(1, 82, 127);
      break;

  }
}
void playNote1(int button1){
switch(button1){
  // add the other case statements for the other buttons.
  case 0:
    midiCc(1, 81, 0);
    midiCc(1, 84, 0);

    break;
  case 1:
      midiCc(1, 81, 127);
      break;
  case 2:
      midiCc(1, 84, 127);
      break;
  case 3:
      midiCc(1, 81, 127);
      midiCc(1, 84, 127);
      break;

  }
}
void loop()
{
  a=readButtons(5);
  //lcd.clear();
  if (a==0 && notePlaying){
    playNote(0); // turn off the note
    notePlaying = false;
   
  }   
else
    if (a>0 && !notePlaying) // someone pressed a button!
    {
      notePlaying = true; // indicate the note is playing
      playNote(a); //go and play note
    }

   
     a=readButtons1(4);
  //lcd.clear();
  if (a==0 && notePlaying1){
    playNote1(0); // turn off the note
    notePlaying1 = false;
   
  }   
else
    if (a>0 && !notePlaying1) // someone pressed a button!
    {
      notePlaying1 = true; // indicate the note is playing
      playNote1(a); //go and play note
    }
  delay(100); 
}


void midiCc(int channel, int command, int value) {
  Serial.write(175 + channel);
  Serial.write(command);
  Serial.write(value);
}


Grumpy_Mike

Quote
This is all working fine until i press 2 buttons together then it does nothing
Using an analogue input for several buttons has the disadvantage of not working when two are pressed at the same time.
Depending on how it is wired up it could be used to detect two at once but most are not designed to do this.

There is nothing you can do in software to make it work.

gregchill

Cheers Mike,

I thought doing it this way would have its limitations alright, i have included the circuit that i used just to see if the switches can detect whats going on.

Grumpy_Mike

The arrangement you need to detect simultaneously key presses is called a weighted ladder or an R2R ladder.

gregchill

Hi,

I decided to get a mega so it would be able to cope with the extra switches, all external switches work fine except two of the internal switches wont work, the max bank is reading 63 instead of 15 and it wont let you select any other number also the midi channel is also stuck on 63 and wont select any other midi channel.so no midi is being sent, i think it has something to do with the memory, when i run the software on the nano omitting the extra switches it works perfectly.Also on the mega the bank up goes up to 631 instead of 15,  i have included the sketch any help would be great.

gregchill

It seams to be acting the same way as the teensy 3.1.

After experimenting with the storage.cpp it still acts the same wont let the user change midi channel through the lcd, and has the same  midi channel number as the the maximum bank number.

gregchill

Is there a way to override the midi channel user select in the internal menu with code.

gregchill

Hi,

I have included the midi.h and MIDI_CREATE_DEFAULT_INSTANCE();now i am getting midi to transmit to the device. change  program channels are working and switches are sending midi cc messages, however it will still not let me send any midi messages from the internal menu and the lcd is displaying 12 banks as apposed to 63. i still think its something to do with storage. cpp. or the mega is faulty.

Can anyone help please.

gregchill

Solved

I tried a different IDE.

All working perfectly now.

gregchill

In the interest of learning, i am trying to put another switch that works of the lcd menu with a button press with the 2 existing switches.
I copied all the entry's in the sketch of switch 1 and changed them to switch 3, inorder to make the switch state on or off for switch 3 it needs to work independently.
I have narrowed the code down to the section (bool StorageClass::readS3State(int patchno))
the section with the bit_fld toggles the on and off( i think). But i dont know what the (return (EEPROM.read(Offset(patchno) + 3) & 0x1) == 0x1) is and how it works.

Would someone be kind enough to explain this, and what the new entry's for the switch should be.

i have tried changing the entry's  to see how they work.but cant get it working.

Code: [Select]
// Memory stucture:
// byte 0 -> init marker
// byte 1 -> midi channel
// byte 2 -> maximum bank
// byte 4/5 -> PDL1 min
// byte 6/7 -> PDL1 max
// byte 8/9 -> PDL2 min
// byte 10/11 -> PDL2 max
// byte 12 -> Performance mode
// from byte 16 and further
// Each patch, 16 bytes long:
// 0 : ProgChangeNo
// 1 : S1 CC
// 2 : S2 CC
// 3 : S1/S2 state and vol->wah (bitwise)
// 4..15: 12-character name
// 16 : S3 CC
// 17 : S3 State
//

#include "Storage.h"
#include "constants.h"

void StorageClass::init()
{
  if (EEPROM.read(0) != 127)
  {
    EEPROM.write(0,127);
   // for (int i = 0; i < 4024; i++)
    // EEPROM.write(i, 0);

    writeChannel(1);
    writeMaxBank(12);

    writePatchName(0, "JMP1");
    writePatchName(1, "CleanChorus");
    writePatchName(2, "Clean");
    writePatchName(3, "Lead");
    writePatchName(4, "JMP1");
    writePatchName(5, "CleanCh");
    writePatchName(6, "Cry");
    writePatchName(7, "Luke");
    writePatchName(8, "JMP1!");
    writePatchName(9, "Clubclean");
    writePatchName(10, "Country");
    writePatchName(11, "CountryTS");

for (int i = 0; i < 63; i++)
{
writeS1CC(i, 50);
writeS2CC(i, 17);
                writeS3CC(i, 90);
}
for (int i = 0; i < 4; i++)
{
writeS1State(i, true);

writeS2W2VState(6, true);
}
    writeS3State(2, true);
   
  }
}

int StorageClass::Offset(int patchno)
{
  return (patchno * 16) + 16;
}

byte StorageClass::readChannel()
{
  EEPROM.read(1);
}
void StorageClass::writeChannel(byte channel)
{
  EEPROM.write(1, channel);
}
byte StorageClass::readMaxBank()
{
  EEPROM.read(2);
}
void StorageClass::writeMaxBank(byte maxbank)
{
  // 63 programs max
  maxbank = min(byte(63 / banksize), maxbank);
  EEPROM.write(2, maxbank);
}
String StorageClass::readPatchName(int patchno)
{
  // start in EEPROM from position 16, max = 1007 => 63 patches max!
  // Each patch, 16 bytes long:
  // 0 : ProgChangeNo (not used)
  // 1 : S1 CC
  // 2 : S2 CC
  // 3 : S1/S2 state and vol->wah (bitwise)
  // 4..15: 12-character name
  char buf[13];
  for (int i = 0; i < 12; i++)
  buf[i] = EEPROM.read(Offset(patchno) + i + 4);
  buf[12] = 0;

  return String(buf);
}
void StorageClass::writePatchName(int patchno, char *patchname)
{
  int len = strlen(patchname);
  for (int i = 0; i < 12; i++)
  { 
    if (i < len)
EEPROM.write(Offset(patchno) + i + 4, patchname[i]);
    else
EEPROM.write(Offset(patchno) + i + 4, ' ');
  }
}

byte StorageClass::readS1CC(int patchno)
{
return EEPROM.read(Offset(patchno) + 1);
}
void StorageClass::writeS1CC(int patchno, byte CC)
{
EEPROM.write(Offset(patchno) + 1, CC);
}
  byte StorageClass::readS2CC(int patchno)
{
return EEPROM.read(Offset(patchno) + 2);
}
void StorageClass::writeS2CC(int patchno, byte CC)
{
EEPROM.write(Offset(patchno) + 2, CC);
}
byte StorageClass::readS3CC(int patchno)
{
return EEPROM.read(Offset(patchno) + 3);
}
void StorageClass::writeS3CC(int patchno, byte CC)
{
EEPROM.write(Offset(patchno) + 3, CC);
}
bool StorageClass::readS1State(int patchno)
{
// 3 : S1/S2 state and vol->wah (bitwise)
return (EEPROM.read(Offset(patchno) + 3) & 0x1) == 0x1;
}
void StorageClass::writeS1State(int patchno, bool state)
{
byte bit_fld = EEPROM.read(Offset(patchno) + 3);
  if (state)
bit_fld |= 1 << 0;
else
bit_fld &= ~(1 << 0);
EEPROM.write(Offset(patchno) + 3, bit_fld);
}
bool StorageClass::readS2State(int patchno)
{
return (EEPROM.read(Offset(patchno) + 3) & 0x2) == 0x2;
}
void StorageClass::writeS2State(int patchno, bool state)
{
byte bit_fld = EEPROM.read(Offset(patchno) + 3);
if (state)
bit_fld |= 1 << 1;
else
bit_fld &= ~(1 << 1);
EEPROM.write(Offset(patchno) + 3, bit_fld);
}
  bool StorageClass::readS2W2VState(int patchno)
{
return (EEPROM.read(Offset(patchno) + 3) & 0x4) == 0x4;
}
void StorageClass::writeS2W2VState(int patchno, bool state)
{
byte bit_fld = EEPROM.read(Offset(patchno) + 3);
if (state)
bit_fld |= 1 << 2;
else
bit_fld &= ~(1 << 2);
EEPROM.write(Offset(patchno) + 3, bit_fld);
}

void StorageClass::writePDL1Min(int Value)
{
    EEPROM.write(4,highByte(Value));
    EEPROM.write(5,lowByte(Value));
}

int StorageClass::readPDL1Min()
{
    return word(EEPROM.read(4),EEPROM.read(5));
}

void StorageClass::writePDL1Max(int Value)
{
    EEPROM.write(6,highByte(Value));
    EEPROM.write(7,lowByte(Value));
}

int StorageClass::readPDL1Max()
{
    return word(EEPROM.read(6),EEPROM.read(7));
}

  void StorageClass::writePDL2Min(int Value)
{
    EEPROM.write(8,highByte(Value));
    EEPROM.write(9,lowByte(Value));
}

int StorageClass::readPDL2Min()
{
    return word(EEPROM.read(8),EEPROM.read(9));
}

void StorageClass::writePDL2Max(int Value)
{
    EEPROM.write(10,highByte(Value));
    EEPROM.write(11,lowByte(Value));
}

int StorageClass::readPDL2Max()
{
    return word(EEPROM.read(10),EEPROM.read(11));
}

byte StorageClass::readPrgChg(int patchno)
{
  // start in EEPROM from position 16, max = 1007 => 63 patches max!
  // Each patch, 16 bytes long:
  // 0 : ProgChangeNo (not used)
  // 1 : S1 CC
  // 2 : S2 CC
  // 3 : S1/S2 state and vol->wah (bitwise)
  // 4..15: 12-character name
  return EEPROM.read(Offset(patchno));
}
void StorageClass::writePrgChg(int patchno, byte PrgChg)
{
    EEPROM.write(Offset(patchno), PrgChg);
}

void StorageClass::ResetProgramMap()
{
    for(int i = 0; i < 63; i++)
      writePrgChg(i, i);
}

void StorageClass::writePerfMode(boolean Value)
{
    EEPROM.write(12,Value ? 1 : 0);
}

boolean StorageClass::readPerfMode()
{
    return EEPROM.read(12) == 1;
}



bool StorageClass::readS3State(int patchno)
{
// 3 : S1/S2 state and vol->wah (bitwise)
return (EEPROM.read(Offset(patchno) + 3) & 0x1) == 0x1;
}
void StorageClass::writeS3State(int patchno, bool state)
{
byte bit_fld = EEPROM.read(Offset(patchno) + 3);
  if (state)
bit_fld |= 1 << 0;
else
bit_fld &= ~(1 << 0);
EEPROM.write(Offset(patchno) + 3, bit_fld);
}

gregchill

Got It working through trial and error, but would love to know how and why it works.

Go Up