how to write if() condition from 4 control change midi values ?

Status
Not open for further replies.

rotabox

Well-known member
hello
im trying to write if condition from 4 values i get from midi control change.
every 2 values gives me 1 commend for example:
Code:
//ch number(massage1)
control == 12
value == 0

//button is pressed(massage2)
control == 44
value == 66

i try to write it in the simple way but its not working when i try to add massage2 with another if in that way:

Code:
if(control == 12 && value == 0){
if(control == 44 && value == 66){
// do somthing

how should i write this condition to do somthing only if i got those 4 values in this order?
tnx
rota
 
From this tiny code fragment, all I can see is you're missing the '}' close brace.

We can probably better help you figure out what's wrong if you show us a complete program. Make sure whatever you share actually works when we copy it into Arduino and upload to a real board. Small details matter. We're much better at helping when we see a full program with all those details.
 
tnx for your fast replay paul
thats the full code. im trying to get the solo mute commend from control change
the control change send 2 massage follow 1 by another for every time i press on mute butto in software.
every massage ii print it in two values control witch is the controller number and the value that controller sends.
in this case massage 1 is the ch number witch is gives me controller 12 value 0. the next massage (2) is the press and release commend of the button
witch gives me control 44 value 66.
i print in control change:

Serial.print(control);
Serial.print(value);

if i press button its looks like that:
12
0
44
66

if i release button its looks like that:
12
0
44
2

if im wire condition only for the first massage


Code:
if ((control == 12)&&(value == 0)) {
its working but not but not in the right way.
if i add the second if right after that its not working at all.

Code:
#include <i2c_t3.h>
#include <U8g2lib.h>

U8G2_SSD1306_128X64_NONAME_F_SW_I2C  u8g2(U8G2_R0, /* clock=*/ 37, /* data=*/ 38, /* reset=*/ U8X8_PIN_NONE);   // All Boards without Reset of the Display

int SCRNUM[8] = {0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00};

int MUTNUM[8] = {7,6,5,4,3,2,1,0,};
int dbRA[8] = {0,0,0,0,0,0,0,0};

String chname1[8];
String chname2[8];
String chname3[8];
String chname4[8];
int centerword[8];
int hi[8];
int lo[8];
int Gain[8];
String chmute[8] ;
String chsolo[8] ;

elapsedMicros sinceupdatescreenvalues;                         // timer for fader check
unsigned int  updatescreenvaluesInterval = 1000;

void setup(void) {
  // Setup for Master mode, pins 18/19, external pullups, 400kHz, 200ms default timeout
  Wire1.begin(I2C_MASTER, 0x00, I2C_PINS_37_38, I2C_PULLUP_EXT, 400000);
  Wire1.setDefaultTimeout(200000); // 200ms
  usbMIDI.setHandleControlChange(myControlChange);
  usbMIDI.setHandleSysEx(handleSysEx); 
  u8g2.begin();
  startscreen();

}
void loop(void) {
   usbMIDI.read();
   if (sinceupdatescreenvalues >=updatescreenvaluesInterval) {
    sinceupdatescreenvalues = sinceupdatescreenvalues - updatescreenvaluesInterval;
    updatescreenvalues();
   }
   while (usbMIDI.read()) {
  }
}

void tcaselect(uint8_t i) {
  if (i > 7) return;
  Wire1.beginTransmission(0x70);
  Wire1.write(1 << i);
  Wire1.endTransmission();

  while (usbMIDI.read()) {
  }
}
void handleSysEx(const byte* sysExData, uint16_t sysExSize, bool complete) 
{ 
    //sysex array
    const byte *pSysExArray = usbMIDI.getSysExArray(); //capture data   
    for (int t=0;t<8;t++) {
    if (pSysExArray[6] == 0x10){  // 0x10 = Scribble strip 4 bytes
     if (pSysExArray[7] == SCRNUM[t]){           
         for (int i=8;i<11;i++) {
         String data = String(sysExData[i]);
         int w = u8g2.getUTF8Width(data.c_str());
         int center = 64-w;                           
         centerword[t] = center;                                                 
         chname1[t] = sysExData[8];
         chname2[t] = sysExData[9];
         chname3[t] = sysExData[10];
         chname4[t] = sysExData[11];
         }
         }
     }
    }
}
void myControlChange(byte channel, byte control, byte value) {               // blink the LED a number of times  

 // value = map(value, 0, 127, 127, 0);
  for (int i=0; i<8;i++){

  if (control == i+32) {   
   hi[i] = value;
  }
  if (control == i) {
    lo[i] = value;
    
    Gain[i] = (hi[i] >> 7) + lo[i]*8.055;
    Gain[i] = map(Gain[i], 0, 1022, 1022, 0);
    
    //GainScreen[i] = (hi[i] >> 7) + lo[i];
    dbRA[7]=GetDB(lo[0]);
    dbRA[6]=GetDB(lo[1]);
    dbRA[5]=GetDB(lo[2]);
    dbRA[4]=GetDB(lo[3]);
    dbRA[3]=GetDB(lo[4]);
    dbRA[2]=GetDB(lo[5]);
    dbRA[1]=GetDB(lo[6]);
    dbRA[0]=GetDB(lo[7]); 
  } 
  }
  //Serial.println(usbMIDI.getData1());

  for (int t=0; t<8;t++){
  if ((control == 12)&&(value == MUTNUM[t])) { 
  chmute[t] = "M";     
  }
  if ((control == 44)&&(value == 2)) { 
  chmute[t] = " ";     
  }
  }
  Serial.println(value);
}
void updatescreenvalues(){
    
     for (int i=0;i<8;i++){
     Wire1.begin();   
     tcaselect(i);    
     chname1[i].toUpperCase();
     chname2[i].toUpperCase();
     chname3[i].toUpperCase();
     chname4[i].toUpperCase();
     //page structure
     u8g2.clearBuffer();
     u8g2.drawLine(0, 32, 128, 32);
     u8g2.setFont(u8g2_font_ncenB10_tr); // choose a suitable font
     u8g2.setCursor(90, 60);
     u8g2.print("dbA");
     
     //values update
     u8g2.setFont(u8g2_font_ncenB14_tr);     
     u8g2.setCursor(centerword[i], 18);       
     u8g2.print(String(chname1[i]+chname2[i]+chname3[i]+chname4[i]));            
     u8g2.setFont(u8g2_font_ncenB14_tr); // choose a suitable font
     u8g2.setCursor(50, 60);
     u8g2.print(dbRA[i]);
      
    
     
     if(chmute[i] == "M"){
     u8g2.setFontMode(1);  /* activate transparent font mode */
     u8g2.drawBox(01,35, 24, 50);
     u8g2.setDrawColor(2);
     u8g2.setFont(u8g2_font_ncenB14_tr); // choose a suitable font
     u8g2.setCursor(04, 57);    
     u8g2.print(chmute[i]);
   
     }
     if(chsolo[i] == "S"){
     u8g2.setFontMode(1);  /* activate transparent font mode */
     u8g2.drawBox(01,20, 24, 50);
     u8g2.setDrawColor(2);
     u8g2.setFont(u8g2_font_ncenB12_tr); // choose a suitable font
     u8g2.setCursor(07, 32);
     u8g2.print(chsolo[i]);
  
     }
     u8g2.sendBuffer(); 
     }
}
void startscreen(){
  for (int i=0;i<8;i++){
  Wire1.begin();
  tcaselect(i);
  u8g2.begin();
  u8g2.clearBuffer();          // clear the internal memory
  u8g2.drawRFrame(2 ,2,122,62,7);
  u8g2.setFont(u8g2_font_ncenB18_tr); // choose a suitable font
  u8g2.setCursor(25,35);
  u8g2.print("AMC8");  // write something to the internal memory
  u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
  u8g2.setCursor(26, 55);
  u8g2.print("HUI Protocol"); // write something to the internal memory
  u8g2.sendBuffer();          // transfer internal memory to the display
 }
delay(7000);
}

float GetDB(int Gain){ 
float DB; 
 if (Gain == 0){
DB = -140.0 ;
}
if (Gain == 1){
DB = -100.0 ;
}
if (Gain == 2){
DB = -84.0 ;
}
if (Gain == 3){
DB   = -78.4 ;
}
if (Gain == 4){
DB   = -72.7 ;
}
if (Gain == 5){
DB   = -69.7 ;
}
if (Gain == 6){
DB   = -67.2;
}
if (Gain == 7){
DB   = -64.6;
}
if (Gain == 8){
DB   = -62.0;
}
if (Gain == 9){
DB   = -59.4;
}
if (Gain == 10){
DB   = -56.8;
}
if (Gain == 11){
DB  = -54.2;
}
if (Gain == 12){  
DB = -51.6;
}
if (Gain == 13){
DB  = -49.1;
}
if (Gain == 14){
DB = -46.5;
}
if (Gain == 15){  
DB   = -43.9;
}
if (Gain == 16){
DB  = -41.3;
}
if (Gain == 17){
DB  = -39.7;
}
if (Gain == 18){
DB  = -39.0;
}
if (Gain == 19){
DB  = -38.4;
}
if (Gain == 20){
DB  = -37.7;
}
if (Gain == 21){
DB  = -37.1;
}
if (Gain == 22){
DB  = -36.4;
}
if (Gain == 23){
DB  = -35.8;
}
if (Gain == 24){
DB  = -35.1 ;
}
if (Gain == 25){
DB  = -34.5;
}
if (Gain == 26){
DB  = -33.8;
}
if (Gain == 27){
DB  = -33.2;
}
if (Gain == 28){
DB  = -32.5;
}
if (Gain == 29){
DB  = -31.9;
}
if (Gain == 30){
DB  = -31.2;
}
if (Gain == 31){
DB  = -30.6;
}
if (Gain == 32){
DB  = -30.0;
}
if (Gain == 33){
DB  = -29.3;
}
if (Gain == 34){
DB  = -28.7;
}
if (Gain == 35){
DB  = -28.0;
}
if (Gain == 36){
DB  = -27.4;
}
if (Gain == 37){
DB  = -26.7;
}
if (Gain == 38){
DB  = -26.1;
}
if (Gain == 39){
DB  = -25.4 ;
}
if (Gain == 40){
DB  = -24.8;
}
if (Gain == 41){
DB  = -24.1;
}
if (Gain == 42){
DB  = -23.5;
}
if (Gain == 43){
DB  = -22.8;
}
if (Gain == 44){
DB  = -22.2;
}
if (Gain == 45){
DB  = -21.5;
}
if (Gain == 46){
DB  = -20.9;
}
if (Gain == 47){
DB  = -20.2;
}
if (Gain == 48){
DB  = -19.7;
}
if (Gain == 49){
DB  = -19.3;
}
if (Gain == 50){
DB  = -18.9;
}
if (Gain == 51){
DB  = -18.5;
}
if (Gain == 52){
DB  = -18.1;
}
if (Gain == 53){
DB  = -17.5;
}
if (Gain == 54){
DB  = -17.2;
}
if (Gain == 55){
DB  = -16.8;
}
if (Gain == 56){
DB  = -16.4;
}
if (Gain == 57){
DB  = -16.0;
}
if (Gain == 58){
DB  = -15.6;
}
if (Gain == 59){
DB  = -15.2;
}
if (Gain == 60){
DB  = -14.8;
}
if (Gain == 61){
DB  = -14.4;
}
if (Gain == 62){
DB  = -13.9 ;
}
if (Gain == 63){
DB  = -13.5;
}
if (Gain == 64){
DB  = -13.1;
}
if (Gain == 65){
DB  = -12.7;
}
if (Gain == 66){
DB  = -12.2;
}
if (Gain == 67){
DB  = -11.8;
}
if (Gain == 68){
DB  = -11.4;
}
if (Gain == 69){
DB  = -11.0;
}
if (Gain == 70){
DB  = -10.6;
}
if (Gain == 71){
DB  = -10.2;
}
if (Gain == 72){
DB  = -9.8;
}
if (Gain == 73){
DB  = -9.4 ;
}
if (Gain == 74){
DB  = -8.9;
}
if (Gain == 75){
DB  = -8.5;
}
if (Gain == 76){
DB  = -8.1;
}
if (Gain == 77){
DB  = -7.7;
}
if (Gain == 78){
DB  = -7.3;
}
if (Gain == 79){
DB  = -6.9;
}
if (Gain == 80){
DB  = -6.5;
}
if (Gain == 81){
DB  = -6.1;
}
if (Gain == 82){
DB  = -5.6;
}
if (Gain == 83){
DB  = -5.2;
}
if (Gain == 84){
DB  = -4.8;
}
if (Gain == 85){
DB  = -4.4;
}
if (Gain == 86){
DB  = -4.0;
}
if (Gain == 87){
DB  = -3.6;
}
if (Gain == 88){
DB  = -3.2;
}
if (Gain == 89){
DB  = -2.8;
}
if (Gain == 90){
DB  = -2.3;
}
if (Gain == 91){
DB  = -1.9 ;
}
if (Gain == 92){
DB  = -1.5;
}
if (Gain == 93){
DB  = -1.1;
}
if (Gain == 94){
DB  = -0.7;
}
if (Gain == 95){
DB  = -0.3;
}
if (Gain == 96){
DB  = 0.1;
}
if (Gain == 97){
DB  = 0.5;
}
if (Gain == 98){
DB  = 1.0;
}
if (Gain == 99){
DB  = 1.2;
}
if (Gain == 100){
DB = 1.6;
}
if (Gain == 101){
DB = 2.0;
}
if (Gain == 102){
DB = 2.4;
}
if (Gain == 103){
DB = 2.8;
}
if (Gain == 104){
DB = 3.1;
}
if (Gain == 105){
DB = 3.5;
}
if (Gain == 106){
DB = 4.0;
}
if (Gain == 107){
DB = 4.2;
}
if (Gain == 108){
DB = 4.6;
}
if (Gain == 109){
DB = 5.0;
}
if (Gain == 110){
DB = 5.4;
}
if (Gain == 111){
DB = 5.7;
}
if (Gain == 112){
DB = 6.1;
}
if (Gain == 113){
DB = 6.5;
}
if (Gain == 114){
DB = 7.0;
}
if (Gain == 115){
DB = 7.2;
}
if (Gain == 116){
DB = 7.6;
}
if (Gain == 117){
DB = 8.0;
}
if (Gain == 118){
DB = 8.4;
}
if (Gain == 119){
DB = 8.7;
}
if (Gain == 120){
DB =9.1;
}
if (Gain == 121){
DB = 9.5;
}
if (Gain == 122){
DB = 10.0;
}
if (Gain == 123){
DB = 10.2;
}
if (Gain == 124){
DB = 10.6;
}
if (Gain == 125){
DB = 11.0;
}
if (Gain == 126){
DB = 11.4;
}
if (Gain == 127){
DB = 12.00;
}
  return DB;}
 
Last edited:
First, this code
Code:
if ((control == 12)&&(value == 0)) {
doesn't appear anywhere in the full code that you posted.
The only place that control 12 or 44 occur is in this code in the myControlChange function
Code:
  for (int t=0; t<8; t++) {
    if ((control == 12)&&(value == MUTNUM[t])) {
      chmute[t] = "M";
    }
    if ((control == 44)&&(value == 2)) {
      chmute[t] = " ";
    }
  }

If this is where you are having problems, is this the code which fails or which works?

Second, your description of a control change message doesn't seem to be accurate. A MIDI control change message consists of three bytes. The first byte indicates that it is a Control Change message and also contains the channel number. The second byte is the 7-bit control number. The third byte is the 7-bit control value.
When you push a button I would expect that you get one control change message with 3 bytes containing something like this:
Status byte (1) - 0xBC this indicates a control change message (B) on channel 12 (C)
byte (2) - 44 indicates controller number 44
byte (3) - 2 indicates the controller value

Releasing the button would generate a message with the same values for bytes 1 and 2 but byte 3 would have a different value indicating the button is off. When it is just a button, I would have thought the device would send zero for off and 127 for on.
Your description suggests that the device sends two control change messages for button down and two for button up.

Which device is it and does it have online documentation of the MIDI messages that it generates?

At the end of the myControlChange function you have this statement:
Code:
  Serial.println(value);
change it to
Code:
  Serial.print(channel);
  Serial.print(", ");
  Serial.print(control);
  Serial.print(", ");
  Serial.println(value);
This will print one complete control change message per line. Post the output of this when you push and release a button.

Pete
 
First, this code
Code:
if ((control == 12)&&(value == 0)) {
doesn't appear anywhere in the full code that you posted.
The only place that control 12 or 44 occur is in this code in the myControlChange function
Code:
  for (int t=0; t<8; t++) {
    if ((control == 12)&&(value == MUTNUM[t])) {
      chmute[t] = "M";
    }
    if ((control == 44)&&(value == 2)) {
      chmute[t] = " ";
    }
  }

If this is where you are having problems, is this the code which fails or which works?

Second, your description of a control change message doesn't seem to be accurate. A MIDI control change message consists of three bytes. The first byte indicates that it is a Control Change message and also contains the channel number. The second byte is the 7-bit control number. The third byte is the 7-bit control value.
When you push a button I would expect that you get one control change message with 3 bytes containing something like this:
Status byte (1) - 0xBC this indicates a control change message (B) on channel 12 (C)
byte (2) - 44 indicates controller number 44
byte (3) - 2 indicates the controller value

Releasing the button would generate a message with the same values for bytes 1 and 2 but byte 3 would have a different value indicating the button is off. When it is just a button, I would have thought the device would send zero for off and 127 for on.
Your description suggests that the device sends two control change messages for button down and two for button up.

Which device is it and does it have online documentation of the MIDI messages that it generates?

At the end of the myControlChange function you have this statement:
Code:
  Serial.println(value);
change it to
Code:
  Serial.print(channel);
  Serial.print(", ");
  Serial.print(control);
  Serial.print(", ");
  Serial.println(value);
This will print one complete control change message per line. Post the output of this when you push and release a button.

Pete
Hi el_supremo
Tnx for you replay. I know most of the info about control change. The protocol I used to send midi data is HUI protocol and I'm sending it with protocols software all commend of HUI protocol runs under midi channel 1 and for sure its an control change commend so i dont need to print channel. Also all commend i read r under control change so no need to define the first byte 0xBC
Like I write above the first if() alone is working but not in the right way.
If I add another if after it its not working at all.
And yes the code line you mention that's the line I'm talking about I just multiplay it for 8 screens
This protocol not act like 0-127 velocity for determine the press of a button its send the byte I mention above
 
Hi el_supremo
Tnx for you replay. I know most of the info about control change. The protocol I used to send midi data is HUI protocol and I'm sending it with protocols software all commend of HUI protocol runs under midi channel 1 and for sure its an control change commend so i dont need to print channel. Also all commend i read r under control change so no need to define the first byte 0xBC
Like I write above the first if() alone is working but not in the right way.
If I add another if after it its not working at all.
And yes the code line you mention that's the line I'm talking about I just multiplay it for 8 screens
This protocol not act like 0-127 velocity for determine the press of a button its send the byte I mention above
I mean prootools software(not protocol software)
 
First, this code
Code:
if ((control == 12)&&(value == 0)) {
doesn't appear anywhere in the full code that you posted.
The only place that control 12 or 44 occur is in this code in the myControlChange function
Code:
  for (int t=0; t<8; t++) {
    if ((control == 12)&&(value == MUTNUM[t])) {
      chmute[t] = "M";
    }
    if ((control == 44)&&(value == 2)) {
      chmute[t] = " ";
    }
  }

If this is where you are having problems, is this the code which fails or which works?

Second, your description of a control change message doesn't seem to be accurate. A MIDI control change message consists of three bytes. The first byte indicates that it is a Control Change message and also contains the channel number. The second byte is the 7-bit control number. The third byte is the 7-bit control value.
When you push a button I would expect that you get one control change message with 3 bytes containing something like this:
Status byte (1) - 0xBC this indicates a control change message (B) on channel 12 (C)
byte (2) - 44 indicates controller number 44
byte (3) - 2 indicates the controller value

Releasing the button would generate a message with the same values for bytes 1 and 2 but byte 3 would have a different value indicating the button is off. When it is just a button, I would have thought the device would send zero for off and 127 for on.
Your description suggests that the device sends two control change messages for button down and two for button up.

Which device is it and does it have online documentation of the MIDI messages that it generates?

At the end of the myControlChange function you have this statement:
Code:
  Serial.println(value);
change it to
Code:
  Serial.print(channel);
  Serial.print(", ");
  Serial.print(control);
  Serial.print(", ");
  Serial.println(value);
This will print one complete control change message per line. Post the output of this when you push and release a button.

Pete

update:
thats the commend the control change recive

Code:
  //mute commends
  for (int t=0; t<8;t++){
   if(usbMIDI.read() == 0xB0,0x0C,MUTNUM[t],0xB0,0x2C,0x42){ 
   chmute[t] = "M";  
   }
   
  
   if(usbMIDI.read() == 0xB0,0x0C,MUTNUM[t],0xB0,0x2C,0x02){   
   chmute[t] = " "; 
   }


MUTNUM[t] represent the channle number.
i stiil not able to get it read in the right way
i dont know if im doing ok to use usbmidi.read here
allso if try to read only 0xB0,0x0C,MUTNUM[t] its respond some how.
 
The basic problem is that the device sends two control change messages for each event. A button down generates two CCs and button up generates two more CCs. You can't check for control==12 and control==44 at the same time because they don't occur at the same time.
You would have to write your code so that it can handle two CC messages instead of just one. Your code will have to look for control==12 and save that and the value, plus set a "flag" to mean that you've seen the first half of the total message. When another CC arrives, if that "flag" is set, you now look for the second half of the total message and then process the whole thing - and then clear the "flag".

Pete
 
Why not simply shifting the incoming bytes into an unsigned 32bit integer and then compare for the command sequence pattern?

uint32_t sr;
sr = (sr << 8) | newbyte; // each time a byte arrives

after 4 Bytes arrived (let‘s call them aa, bb, cc, and dd), sr will be 0xaabbccdd. Now you can compare against your mask:
if (sr & 0x12004400 == 0x12004400){ // that‘s the sequence which you are expecting
byte firstval = (sr & 0xff0000) >> 16; // this is the bb byte
byte secondval = sr & 0xff; // this is the dem byte
}
 
The basic problem is that the device sends two control change messages for each event. A button down generates two CCs and button up generates two more CCs. You can't check for control==12 and control==44 at the same time because they don't occur at the same time.
You would have to write your code so that it can handle two CC messages instead of just one. Your code will have to look for control==12 and save that and the value, plus set a "flag" to mean that you've seen the first half of the total message. When another CC arrives, if that "flag" is set, you now look for the second half of the total message and then process the whole thing - and then clear the "flag".

Pete

Thanks to all of you guys
you guide me to the right point
the problem is SOLVED

im not expert so i use that method please tell me if you can think about lighter version of it

Code:
  for (int t=0; t<8;t++){
  if (control == 44) {   
   hibyte[t] = value;
  }
  if (control == 12) {
    lobyte[t] = value;
  } 
     if(lobyte[t] == MUTNUM[t]){
     if(hibyte[t] == 2){
     chmute[t] = " ";
     }
     if(lobyte[t] == MUTNUM[t]){
     if(hibyte[t] == 66){
     chmute[t] = "M";
     }
     }
     }
  }
}
 
Status
Not open for further replies.
Back
Top