Function in the wrong place?

Hello to all... I have an issue trying to get a function recognised in this piece of code. My compilation error is "'sendCC' was not declared in this scope".
Can someone please tell me if the function "Void sendCC" can be placed where it is and if it is a question of curly braces causing the error?
Much appreciated for any help.

#include "TM1637.h"  // include TM1637 library
#include <EEPROM.h>
#include <PinButton.h>
#include <MIDI.h>
#include <Control_Surface.h>

const int expPin = A0;
const int CCNum = 4;
int newExpVal = 0;
int lastExpVal = 0;

MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
byte midi_clock = 0xf8;


#define CLK 2  // define TM1637 clock pin
#define DIO 3  // define TM1637 data pin

// initialize the TM1637 library
TM1637 tm1637(CLK, DIO);

//myButtonDN single click (de-increment preset)
//myButtonUP single click (increment preset)
//myButtonDN double click (increment bank)
//myButtonUP long click (save preset)
PinButton myButtonUP(4);
PinButton myButtonDN(5);

int num = 0, prev_num = 1;
int let = 0, prev_let = 1;
int i = 0, prev_i = 1;

const unsigned int numReadings = 3;
int storedValues[numReadings];
int Saves[numReadings];

int address1 = 0;  // bank A // adresses need two spaces for ints! One for bytes
int address2 = 2;  // bank B
int address3 = 4;  // bank C



void setup() {

  MIDI.begin(MIDI_CHANNEL_OMNI);

  // initialize the TM1637 display
  tm1637.init();
  // set display brightness (from 0 to 7)
  tm1637.set(3);

  EEPROM.get(address1, Saves[0]);  // bank A
  EEPROM.get(address2, Saves[1]);  // bank B
  EEPROM.get(address3, Saves[2]);  // bank C

  MIDI.sendRealTime(midi_clock);
}
/*
void sendCC(int val) {
  usbMIDI.sendControlChange(CCNum, val, 3);
  MIDI.sendControlChange(CCNum, val, 3);
}
*/
void loop() {

  (MIDI.read());

  myButtonUP.update();
  myButtonDN.update();

  int channel = let;  // A B or C, midi chan, 1, 2 or 3! (pedal 1 2 or 3!)
  int program = num;

  if (num != prev_num) {
    // if the displayed (current) number was changed
    prev_num = num;  // save current value of 'num'
    //int program = num;
    // print all data
    //Serial.println(Saves[let]);
    MIDI.sendProgramChange(program, (channel + 1));  // +1 means A = 1 etc!
    tm1637.display(2, num / 10 % 10);                // print tens digit
    tm1637.display(3, num % 10);                     // print ones digit
    //delay(200);                        // wait 200 milliseconds
  }


  if (let != prev_let) {
    // if the displayed (current) number was changed
    prev_let = let;  // save current value of 'let'
    // print all data
    tm1637.display(0, (let + 10));  //this gives me 10, 11 & 12 (A,b & C)
  }

  if (i != prev_i) {
    // if the displayed (current) number was changed
    prev_i = i;                                 // save current value of 'let'
    tm1637.display(2, (Saves[let]) / 10 % 10);  // print tens digit
    tm1637.display(3, (Saves[let]) % 10);       // print ones digit
    MIDI.sendProgramChange(Saves[let], (channel + 1));
  }

  if (myButtonUP.isSingleClick()) {
    // if the UP button is presses
    num++;         // increment 'num'
    if (num > 99)  //99
      num = 0;
    //Serial.println(num);
  }

  if (myButtonDN.isSingleClick()) {
    // if the DN button is presses
    num--;  // decrement 'num'
    if (num < 0)
      num = 99;  //99
                 //Serial.println(num);
  }

  if (myButtonDN.isDoubleClick()) {
    //Serial.println("double");
    let++;        // increment 'let'
    if (let > 2)  // >= 3
      let = 0;
    num = Saves[let];
    //Serial.println(Saves[let]);
  }

  if (myButtonUP.isLongClick()) {
    //Serial.println("long");
    Saves[let] = num;
    i++;
    if (let > 2)  // >= 3
      let = 0;
    //Serial.println(F("Saving presets to EEPROM"));
    //******** add serial print show what will be saved
    for (byte i = 0; i < 3; i++) {
      //Serial.println(Saves[i]);
    }

    newExpVal = analogRead(expPin);
    newExpVal = map(newExpVal, 0, 1023, 0, 127);
    newExpVal = constrain(newExpVal, 0, 127);
    if (newExpVal != lastExpVal) {
    sendCC(newExpVal);
      
    }
    lastExpVal = newExpVal;
  }
  void sendCC(int val) {
  usbMIDI.sendControlChange(CCNum, val, 3);
  MIDI.sendControlChange(CCNum, val, 3);
}

  
  EEPROM.put(address3, Saves[2]);  // bank C
  EEPROM.put(address2, Saves[1]);  // bank B
  EEPROM.put(address1, Saves[0]);  // bank A
}

Yes the function void sendCC() is in the wrong place. Use auto-format to see that the function is within the {} of loop().

That's the first error reported. It is caused by another error: having 'sendCC()' defined inside 'loop()'.

i have auto formatted but how do I tell the function is within the{} of loop()?

Did you try things?

Did you try to put the cursor in front of the last }? Did a little popup show void loop()? What would the little popup mean if you put the cursor in front of the last { ?

After an autoformat, a function definition should start at the beginning of a line; if it doesn't, it's inside something where it should not be (in your case loop().

void loop()
{
  ...
  ...

__void sendCC(int val)
  {
    usbMIDI.sendControlChange(CCNum, val, 3);
    MIDI.sendControlChange(CCNum, val, 3);
__}
  ...
  ...
}

I've put two underscores in fromnt of it to make it more visible. The three dots represent the other parts of your code.

Note:
The result of your autoformat might differ from mine.

Well for one thing, figure out what function this line of code is in:

  EEPROM.put(address3, Saves[2]);  // bank C

I have more questions related to these questions now and I'm not great at articulating the resonses your asking for but I'll try...
@Idahowalker when I place the cursor in front of the last } it highlights along with the first one at the beginning of loop(). When placed in front of the last {, which is for my function, the two curly braces for the function are highlighted. there is no popup though.
@sterretje nothing is revealed in my auto-format other than a tidying of my code.

It's not in a function from what i understand.

@sterretje I understand that a little better now....
I've changed this and It compiles but the intended use of the function doesn't work.

#include "TM1637.h"  // include TM1637 library
#include <EEPROM.h>
#include <PinButton.h>
#include <MIDI.h>
#include <Control_Surface.h>

const int expPin = A0;
const int CCNum = 4;
int newExpVal = 0;
int lastExpVal = 0;

MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
byte midi_clock = 0xf8;


#define CLK 2  // define TM1637 clock pin
#define DIO 3  // define TM1637 data pin

// initialize the TM1637 library
TM1637 tm1637(CLK, DIO);

//myButtonDN single click (de-increment preset)
//myButtonUP single click (increment preset)
//myButtonDN double click (increment bank)
//myButtonUP long click (save preset)
PinButton myButtonUP(4);
PinButton myButtonDN(5);

int num = 0, prev_num = 1;
int let = 0, prev_let = 1;
int i = 0, prev_i = 1;

const unsigned int numReadings = 3;
int storedValues[numReadings];
int Saves[numReadings];

int address1 = 0;  // bank A // adresses need two spaces for ints! One for bytes
int address2 = 2;  // bank B
int address3 = 4;  // bank C



void setup() {

  MIDI.begin(MIDI_CHANNEL_OMNI);

  // initialize the TM1637 display
  tm1637.init();
  // set display brightness (from 0 to 7)
  tm1637.set(3);

  EEPROM.get(address1, Saves[0]);  // bank A
  EEPROM.get(address2, Saves[1]);  // bank B
  EEPROM.get(address3, Saves[2]);  // bank C

  MIDI.sendRealTime(midi_clock);
}
/*
void sendCC(int val) {
  usbMIDI.sendControlChange(CCNum, val, 3);
  MIDI.sendControlChange(CCNum, val, 3);
}
*/
void loop() {

  (MIDI.read());

  myButtonUP.update();
  myButtonDN.update();

  int channel = let;  // A B or C, midi chan, 1, 2 or 3! (pedal 1 2 or 3!)
  int program = num;

  if (num != prev_num) {
    // if the displayed (current) number was changed
    prev_num = num;  // save current value of 'num'
    //int program = num;
    // print all data
    //Serial.println(Saves[let]);
    MIDI.sendProgramChange(program, (channel + 1));  // +1 means A = 1 etc!
    tm1637.display(2, num / 10 % 10);                // print tens digit
    tm1637.display(3, num % 10);                     // print ones digit
    //delay(200);                        // wait 200 milliseconds
  }


  if (let != prev_let) {
    // if the displayed (current) number was changed
    prev_let = let;  // save current value of 'let'
    // print all data
    tm1637.display(0, (let + 10));  //this gives me 10, 11 & 12 (A,b & C)
  }

  if (i != prev_i) {
    // if the displayed (current) number was changed
    prev_i = i;                                 // save current value of 'let'
    tm1637.display(2, (Saves[let]) / 10 % 10);  // print tens digit
    tm1637.display(3, (Saves[let]) % 10);       // print ones digit
    MIDI.sendProgramChange(Saves[let], (channel + 1));
  }

  if (myButtonUP.isSingleClick()) {
    // if the UP button is presses
    num++;         // increment 'num'
    if (num > 99)  //99
      num = 0;
    //Serial.println(num);
  }

  if (myButtonDN.isSingleClick()) {
    // if the DN button is presses
    num--;  // decrement 'num'
    if (num < 0)
      num = 99;  //99
                 //Serial.println(num);
  }

  if (myButtonDN.isDoubleClick()) {
    //Serial.println("double");
    let++;        // increment 'let'
    if (let > 2)  // >= 3
      let = 0;
    num = Saves[let];
    //Serial.println(Saves[let]);
  }

  if (myButtonUP.isLongClick()) {
    //Serial.println("long");
    Saves[let] = num;
    i++;
    if (let > 2)  // >= 3
      let = 0;
    //Serial.println(F("Saving presets to EEPROM"));
    //******** add serial print show what will be saved
    for (byte i = 0; i < 3; i++) {
      //Serial.println(Saves[i]);
    }

    newExpVal = analogRead(expPin);
    newExpVal = map(newExpVal, 0, 1023, 0, 127);
    newExpVal = constrain(newExpVal, 0, 127);
    if (newExpVal != lastExpVal) {
      sendCC(newExpVal);
    }
    lastExpVal = newExpVal;
  }


  EEPROM.put(address3, Saves[2]);  // bank C
  EEPROM.put(address2, Saves[1]);  // bank B
  EEPROM.put(address1, Saves[0]);  // bank A
}
void sendCC(int val) {
    usbMIDI.sendControlChange(CCNum, val, 3);
    MIDI.sendControlChange(CCNum, val, 3);
  }

So now, the function is outside the loop but still no joy.


I've marked the two spaces in front of void sendCC and at the closing curly of void sendCC; they indicate that void sendCC is inside another function (loop() in your case).

@sterretje I will check that again...

So I have made the necessary changes and now this works!
Thank you all for prompting my brain cells!!

#include "TM1637.h"  // include TM1637 library
#include <EEPROM.h>
#include <PinButton.h>
#include <MIDI.h>
#include <Control_Surface.h>

const int expPin = A0;
const int CCNum = 4;
int newExpVal = 0;
int lastExpVal = 0;

MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
byte midi_clock = 0xf8;


#define CLK 2  // define TM1637 clock pin
#define DIO 3  // define TM1637 data pin

// initialize the TM1637 library
TM1637 tm1637(CLK, DIO);

//myButtonDN single click (de-increment preset)
//myButtonUP single click (increment preset)
//myButtonDN double click (increment bank)
//myButtonUP long click (save preset)
PinButton myButtonUP(4);
PinButton myButtonDN(5);

int num = 0, prev_num = 1;
int let = 0, prev_let = 1;
int i = 0, prev_i = 1;

const unsigned int numReadings = 3;
int storedValues[numReadings];
int Saves[numReadings];

int address1 = 0;  // bank A // adresses need two spaces for ints! One for bytes
int address2 = 2;  // bank B
int address3 = 4;  // bank C



void setup() {

  MIDI.begin(MIDI_CHANNEL_OMNI);

  // initialize the TM1637 display
  tm1637.init();
  // set display brightness (from 0 to 7)
  tm1637.set(3);

  EEPROM.get(address1, Saves[0]);  // bank A
  EEPROM.get(address2, Saves[1]);  // bank B
  EEPROM.get(address3, Saves[2]);  // bank C

  MIDI.sendRealTime(midi_clock);
}
/*
void sendCC(int val) {
  usbMIDI.sendControlChange(CCNum, val, 3);
  MIDI.sendControlChange(CCNum, val, 3);
}
*/
void loop() {

  (MIDI.read());

  myButtonUP.update();
  myButtonDN.update();

  int channel = let;  // A B or C, midi chan, 1, 2 or 3! (pedal 1 2 or 3!)
  int program = num;

  if (num != prev_num) {
    // if the displayed (current) number was changed
    prev_num = num;  // save current value of 'num'
    //int program = num;
    // print all data
    //Serial.println(Saves[let]);
    MIDI.sendProgramChange(program, (channel + 1));  // +1 means A = 1 etc!
    tm1637.display(2, num / 10 % 10);                // print tens digit
    tm1637.display(3, num % 10);                     // print ones digit
    //delay(200);                        // wait 200 milliseconds
  }


  if (let != prev_let) {
    // if the displayed (current) number was changed
    prev_let = let;  // save current value of 'let'
    // print all data
    tm1637.display(0, (let + 10));  //this gives me 10, 11 & 12 (A,b & C)
  }

  if (i != prev_i) {
    // if the displayed (current) number was changed
    prev_i = i;                                 // save current value of 'let'
    tm1637.display(2, (Saves[let]) / 10 % 10);  // print tens digit
    tm1637.display(3, (Saves[let]) % 10);       // print ones digit
    MIDI.sendProgramChange(Saves[let], (channel + 1));
  }

  if (myButtonUP.isSingleClick()) {
    // if the UP button is presses
    num++;         // increment 'num'
    if (num > 99)  //99
      num = 0;
    //Serial.println(num);
  }

  if (myButtonDN.isSingleClick()) {
    // if the DN button is presses
    num--;  // decrement 'num'
    if (num < 0)
      num = 99;  //99
                 //Serial.println(num);
  }

  if (myButtonDN.isDoubleClick()) {
    //Serial.println("double");
    let++;        // increment 'let'
    if (let > 2)  // >= 3
      let = 0;
    num = Saves[let];
    //Serial.println(Saves[let]);
  }

  if (myButtonUP.isLongClick()) {
    //Serial.println("long");
    Saves[let] = num;
    i++;
    if (let > 2)  // >= 3
      let = 0;
    //Serial.println(F("Saving presets to EEPROM"));
    //******** add serial print show what will be saved
    for (byte i = 0; i < 3; i++) {
      //Serial.println(Saves[i]);
    }

    EEPROM.put(address3, Saves[2]);  // bank C
    EEPROM.put(address2, Saves[1]);  // bank B
    EEPROM.put(address1, Saves[0]);  // bank A
  }


  newExpVal = analogRead(expPin);
  newExpVal = map(newExpVal, 0, 1023, 0, 127);
  newExpVal = constrain(newExpVal, 0, 127);
  if (newExpVal != lastExpVal) {
    sendCC(newExpVal);
  }
  lastExpVal = newExpVal;
}
void sendCC(int val) {
  usbMIDI.sendControlChange(CCNum, val, 3);
  MIDI.sendControlChange(CCNum, val, 3);
}

Now you've got your function figured out, you might consider moving some of the code out of loop into some new ones. Loop is currently quite long and that makes it harder to spot problems with curly braces.

And BTW, having a global variable called i is asking for trouble :stuck_out_tongue:

Does your loop() function contain another function? loop() is a function that is not supposed to contain another function.

Good luck.

Thank you Wildbill and Idahowalker... Lots of important reminders, especially as I have a bit more to add to this yet :grinning:

1 Like

And it's a disaster to find it back :slight_smile: Just counted the i's in the code for the fun: 198

I wonder if any of ye have a solution for this next issue.
This code allows me to connect a foot controller. Amongst other things, read midi clock from an external drum machine and pass that clock onto other delay pedals to keep them in sync with the tempo from the drum machine. The delay pedals have repeats (echoes) of what music I play through them and these repeats stay in sync with the drum machine. This all works perfectly except for the fact that the repeats become audibly garbled when the foot controller's value is above 0!
The controller's midi messages have nothing to do with the repeats which makes me think that the processes happening in the loop function related to

are affecting the stability of the clock messages?.
If so, Is the another way I can write this code that wouldn't cause this problem?

I have the culprit I think..... The foot controller at certain positions is continuously spitting out controller messages and this is what appears to cause the audible garbling. I'm using a Teensy so I can monitor the messages. Time to deploy some measures!
I will add that this wasn't happening when I used a simple potentiometer to test the code first.

Well I can't understand it... I have added smoothing and it really does work as far as only sending midi from the controller when the value has changed.

#include "TM1637.h"  // include TM1637 library
#include <EEPROM.h>
#include <PinButton.h>
#include <MIDI.h>
#include <Control_Surface.h>

#include <Smoothed.h> 	// Include the library

#define SENSOR_PIN A0    // The input pin for the sensor. In this example we are reading from an Arduino analogue pin. 
// If you don't have a sensor you can still see the effect if the analogue pin is left floating its value will vary wildly.

// Create two instances of the class to use. 
Smoothed <float> mySensor; 
Smoothed <float> mySensor2;

const int expPin = A0;
const int CCNum = 4;
int newExpVal = 0;
int lastExpVal = 0;

MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
byte midi_clock = 0xf8;


#define CLK 2  // define TM1637 clock pin
#define DIO 3  // define TM1637 data pin

// initialize the TM1637 library
TM1637 tm1637(CLK, DIO);

//myButtonDN single click (de-increment preset)
//myButtonUP single click (increment preset)
//myButtonDN double click (increment bank)
//myButtonUP long click (save preset)
PinButton myButtonUP(4);
PinButton myButtonDN(5);

int num = 0, prev_num = 1;
int let = 0, prev_let = 1;
int i = 0, prev_i = 1;

const unsigned int numReadings = 3;
int storedValues[numReadings];
int Saves[numReadings];

int address1 = 0;  // bank A // adresses need two spaces for ints! One for bytes
int address2 = 2;  // bank B
int address3 = 4;  // bank C




void setup() {

 MIDI.begin(MIDI_CHANNEL_OMNI);

 mySensor.begin(SMOOTHED_AVERAGE, 10);	
   mySensor2.begin(SMOOTHED_EXPONENTIAL, 10);


 // initialize the TM1637 display
 tm1637.init();
 // set display brightness (from 0 to 7)
 tm1637.set(3);

 EEPROM.get(address1, Saves[0]);  // bank A
 EEPROM.get(address2, Saves[1]);  // bank B
 EEPROM.get(address3, Saves[2]);  // bank C

 MIDI.sendRealTime(midi_clock);

     mySensor.clear();

}

void loop() {

 (MIDI.read());

 myButtonUP.update();
 myButtonDN.update();

 // Read the value from the sensor
   float currentSensorValue = analogRead(SENSOR_PIN);
   
   // Add the new value to both sensor value stores
   mySensor.add(currentSensorValue);
   mySensor2.add(currentSensorValue);
   
   // Get the smoothed values
   float smoothedSensorValueAvg = mySensor.get();
   float smoothedSensorValueExp = mySensor2.get();
   
   // Output the smoothed values to the serial stream. Open the Arduino IDE Serial plotter to see the effects of the smoothing methods.
   Serial.print(currentSensorValue); Serial.print("\t"); Serial.print(smoothedSensorValueAvg); Serial.print("\t"); Serial.println(smoothedSensorValueExp);
   
   
   // If needed we can also return the last stored value which will be unsmoothed
   float lastValueStoredAvg = mySensor.getLast();
   float lastValueStoredExp = mySensor2.getLast();

   

 int channel = let;  // A B or C, midi chan, 1, 2 or 3! (pedal 1 2 or 3!)
 int program = num;

 if (num != prev_num) {
   // if the displayed (current) number was changed
   prev_num = num;  // save current value of 'num'
   //int program = num;
   // print all data
   //Serial.println(Saves[let]);
   MIDI.sendProgramChange(program, (channel + 1));  // +1 means A = 1 etc!
   tm1637.display(2, num / 10 % 10);                // print tens digit
   tm1637.display(3, num % 10);                     // print ones digit
   //delay(200);                        // wait 200 milliseconds
 }


 if (let != prev_let) {
   // if the displayed (current) number was changed
   prev_let = let;  // save current value of 'let'
   // print all data
   tm1637.display(0, (let + 10));  //this gives me 10, 11 & 12 (A,b & C)
 }

 if (i != prev_i) {
   // if the displayed (current) number was changed
   prev_i = i;                                 // save current value of 'let'
   tm1637.display(2, (Saves[let]) / 10 % 10);  // print tens digit
   tm1637.display(3, (Saves[let]) % 10);       // print ones digit
   MIDI.sendProgramChange(Saves[let], (channel + 1));
 }

 if (myButtonUP.isSingleClick()) {
   // if the UP button is presses
   num++;         // increment 'num'
   if (num > 99)  //99
     num = 0;
   //Serial.println(num);
 }

 if (myButtonDN.isSingleClick()) {
   // if the DN button is presses
   num--;  // decrement 'num'
   if (num < 0)
     num = 99;  //99
                //Serial.println(num);
 }

 if (myButtonDN.isDoubleClick()) {
   //Serial.println("double");
   let++;        // increment 'let'
   if (let > 2)  // >= 3
     let = 0;
   num = Saves[let];
   //Serial.println(Saves[let]);
 }

 if (myButtonUP.isLongClick()) {
   //Serial.println("long");
   Saves[let] = num;
   i++;
   if (let > 2)  // >= 3
     let = 0;
   //Serial.println(F("Saving presets to EEPROM"));
   //******** add serial print show what will be saved
   for (byte i = 0; i < 3; i++) {
     //Serial.println(Saves[i]);
   }

   EEPROM.put(address3, Saves[2]);  // bank C
   EEPROM.put(address2, Saves[1]);  // bank B
   EEPROM.put(address1, Saves[0]);  // bank A
 }


 newExpVal = (smoothedSensorValueAvg);  //(smoothedSensorValueAvg); //analogRead(expPin);

 newExpVal = map(newExpVal, 0, 1023, 0, 127);
 newExpVal = constrain(newExpVal, 0, 127);
 if (newExpVal != lastExpVal) {
   sendCC(newExpVal);
 }
 lastExpVal = newExpVal;
}

void sendCC(int val) {
usbMIDI.sendControlChange(CCNum, val, 3);
      MIDI.sendControlChange(CCNum, val, 3);
}

However, the audio in the delay repeats is always garbled (even at an output value of 0) and I can't think why.
Without the smoothing controller messages are flying but the warble stops when the controller value is 0, or if I can get it to settle on any last number sent.
Does anyone have any ideas at all?
Much appreciated