Newbie pin assignment errors?

Let me start by saying that my coding knowledge is very limited!

I’m trying to help a friend that is making a MIDI pedalboard w/LCD display for a guitar. He is following a design he found on a website for hardware and asked me to help with the Arduino coding. There was a sketch that was provided but the library files were not included. I’ve found and installed what I believe to be similar proper substitute libraries but I could be wrong (and probably am). Also, a request from my friend was to disable the velocity measuring feature. He just wanted the keys to be seen as on or off. I made changes to try to achieve this but I’m getting errors due to my changes and probably because of the libraries.

After I clear these hurdles, there will likely be more challenges ahead for me. Any help for this newbie would be greatly appreciated.

The sketch is an attachment due to the 9000 character limit. I have included my error messages.

In file included from C:\Users\delk\Desktop\bass_pedals_001_pde_RevB\bass_pedals_001_pde_RevB.ino:8:0:

C:\Users\delk\Documents\Arduino\libraries\NewSoftSerial/NewSoftSerial.h:76:16: error: conflicting return type specified for 'virtual void NewSoftSerial::write(uint8_t)'

   virtual void write(uint8_t byte);

                ^

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26:0,

                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,

                 from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:232,

                 from sketch\bass_pedals_001_pde_RevB.ino.cpp:1:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:48:20: error:   overriding 'virtual size_t Print::write(uint8_t)'

     virtual size_t write(uint8_t) = 0;

                    ^

C:\Users\delk\Desktop\bass_pedals_001_pde_RevB\bass_pedals_001_pde_RevB.ino: In function 'void loop()':

bass_pedals_001_pde_RevB:100: error: 'outputMIDI' was not declared in this scope

   outputMIDI();    // DWISOTT

              ^

bass_pedals_001_pde_RevB:101: error: 'scanButtons' was not declared in this scope

   scanButtons();   // Scan the function buttons and process actions

               ^

bass_pedals_001_pde_RevB:102: error: 'doPWM' was not declared in this scope

   doPWM();         // Control LED outputs

         ^

bass_pedals_001_pde_RevB:103: error: 'updateLCD' was not declared in this scope

   updateLCD();

             ^

C:\Users\delk\Desktop\bass_pedals_001_pde_RevB\bass_pedals_001_pde_RevB.ino: In function 'void scanKeys()':

bass_pedals_001_pde_RevB:121: error: expected primary-expression before ')' token

     if ( ( ((input_port & B00000100) >> 2) == 1) && (((input_port & B00001000) >> 3) == 1) && (keyActive[(i * 3)] == 0))) /* && (keyTimer[(i*3)]!=0))  { keyTimer[(i*3)]--; if (keyTimer[(i*3)]<0) {keyTimer[(i*3)]=0;}*/ }    // previously off key in transition

                                                                                                                         ^

bass_pedals_001_pde_RevB:122: error: 'i' was not declared in this scope

       if ( ( ((input_port & B00000100) >> 2) == 1) && (((input_port & B00001000) >> 3) == 1) && (keyActive[(i * 3)] == 0))) /* && (keyTimer[(i*3)]==0))  { keyTimer[(i*3)]=127; */}    // previously off key in transition  

                                                                                                             ^

bass_pedals_001_pde_RevB:122: error: expected primary-expression before ')' token

       if ( ( ((input_port & B00000100) >> 2) == 1) && (((input_port & B00001000) >> 3) == 1) && (keyActive[(i * 3)] == 0))) /* && (keyTimer[(i*3)]==0))  { keyTimer[(i*3)]=127; */}    // previously off key in transition  

                                                                                                                           ^

C:\Users\delk\Desktop\bass_pedals_001_pde_RevB\bass_pedals_001_pde_RevB.ino: At global scope:

bass_pedals_001_pde_RevB:124: error: expected unqualified-id before 'if'

         if (i < 4) { // Row 4,5 is special case as only 1 key

         ^

exit status 1
'outputMIDI' was not declared in this scope

bass_pedals_001_pde_RevB.ino (15.3 KB)

C:\Users\delk\Documents\Arduino\libraries\NewSoftSerial/NewSoftSerial.h

There is a long history behind that class. The IDE used to come with SoftwareSerial, but it was horrible. So, NewSoftSerial was created, and was better. Then, after several versions of the IDE, NewSoftSerial was incorporated into the IDE, improved again, and renamed SoftwareSerial.

So, replace that ancient header file with SoftwareSerial.h.

Did you type that code? The indentation is horrible, and you appear to have missed, or mis-located, a } somewhere.

Thanks for the reply! No, I didn’t write this code. It was passed along to me to try to modify it to work with my friend’s project. The original code came from a website.

I made the library change as suggested and that seemed to work. I am left with the issue related to the missing/misplaced }.

The error I have remaining is listed below. The updated code is attached.

C:\Users\delk\Desktop\bass_pedals_001_pde_RevB\bass_pedals_001_pde_RevB.ino: In function 'void loop()':

bass_pedals_001_pde_RevB:100: error: 'outputMIDI' was not declared in this scope

   outputMIDI();    // DWISOTT

              ^

bass_pedals_001_pde_RevB:101: error: 'scanButtons' was not declared in this scope

   scanButtons();   // Scan the function buttons and process actions

               ^

bass_pedals_001_pde_RevB:102: error: 'doPWM' was not declared in this scope

   doPWM();         // Control LED outputs

         ^

bass_pedals_001_pde_RevB:103: error: 'updateLCD' was not declared in this scope

   updateLCD();

             ^

C:\Users\delk\Desktop\bass_pedals_001_pde_RevB\bass_pedals_001_pde_RevB.ino: In function 'void scanKeys()':

bass_pedals_001_pde_RevB:121: error: expected primary-expression before ')' token

     if ( ( ((input_port & B00000100) >> 2) == 1) && (((input_port & B00001000) >> 3) == 1) && (keyActive[(i * 3)] == 0))) /* && (keyTimer[(i*3)]!=0))  { keyTimer[(i*3)]--; if (keyTimer[(i*3)]<0) {keyTimer[(i*3)]=0;}*/ }    // previously off key in transition

                                                                                                                         ^

bass_pedals_001_pde_RevB:122: error: 'i' was not declared in this scope

       if ( ( ((input_port & B00000100) >> 2) == 1) && (((input_port & B00001000) >> 3) == 1) && (keyActive[(i * 3)] == 0))) /* && (keyTimer[(i*3)]==0))  { keyTimer[(i*3)]=127; */}    // previously off key in transition  

                                                                                                             ^

bass_pedals_001_pde_RevB:122: error: expected primary-expression before ')' token

       if ( ( ((input_port & B00000100) >> 2) == 1) && (((input_port & B00001000) >> 3) == 1) && (keyActive[(i * 3)] == 0))) /* && (keyTimer[(i*3)]==0))  { keyTimer[(i*3)]=127; */}    // previously off key in transition  

                                                                                                                           ^

C:\Users\delk\Desktop\bass_pedals_001_pde_RevB\bass_pedals_001_pde_RevB.ino: At global scope:

bass_pedals_001_pde_RevB:124: error: expected unqualified-id before 'if'

         if (i < 4) { // Row 4,5 is special case as only 1 key

         ^

exit status 1
'outputMIDI' was not declared in this scope

bass_pedals_001_pde_RevB.ino (15.4 KB)

Most of those errors are because your braces {} are in a mess. If you do an Autoformat (Ctrl-T) you should see that the scanKeys() code doesn't end where it should. Fix that first and then see what errors are left.

Steve

I’ve managed to clean up a few things, but still getting errors related probably to the braces.

bass_pedals_001_pde_RevB.ino (15.5 KB)

Yes I think so. But you'll have to sort them out yourself because I don't know what the code is intended to do.

You've probably got a lot of "i not defined in scope" errors. The first ones I looked at were because i was defined in a for loop, the was loop ended } and then you tried to use i again by which time it was out of scope. But I can't tell where that loop was supposed to end or if i should have been defined in some wider scope.

Steve

Something may be missing. For example in the scankeys function, it starts of with a for which is eventually terminated (several if else if later) with the closing brace }.

The very next line contains an opening brace {. While that is “legal” in the language, there is no reason for it. Perhaps there should have been an additional for Loop which would also use the variable i. Since the for is missing, the i wasn’t “defined in scope”.

Are you truly sure that the Person that gave you code containing lines like:

if ( ( ( (input_port & B00000100) >> 2) == 1) && (((input_port & B00001000) >> 3) == 1) && (keyActive[(i * 3)] == 0) )  /* && (keyTimer[(i*3)]!=0))  { keyTimer[(i*3)]--; if (keyTimer[(i*3)]<0) {keyTimer[(i*3)]=0;}*/
      // previously off key in transition
      if ( ( ((input_port & B00000100) >> 2) == 1) && (((input_port & B00001000) >> 3) == 1) && (keyActive[(i * 3)] == 0) )  /* && (keyTimer[(i*3)]==0))  { keyTimer[(i*3)]=127; */
        // previously off key in transition
      }

is your friend?

You said that your “coding knowledge is very limited”. Do you understand that line enough to see that the comment (everything between the /* and */) radically changes what appears to have been the original program structure? Before part of it was commented out, the if applied to code solely within what was commented out (specifically between the opening and closing braces). Because it was commented out, that first if now applies to the second if. The second if used to be Independent of the first if and now it is dependent.

Are those changes you made or were they in what was given to you?

Thanks JaBa.

So it looks like I’ve done more damage than good as I feared when trying to disable the key timer. It looks like it’s better to take a few steps back in order to move forward. I’m now including the original sketch provided to me as it must’ve worked for the original programmer. The only edits I’ve done is auto-format and the above mentioned suggestion for the softwareserial.h library. I need help with the appropriate liquidcrystal_I2C library. The one installed in the IDE doesn’t seem to work with this sketch as written.

Regarding the key timer, my friend who is ultimately the end user, his request was to not use the key velocity measurements. He wanted the keys to just be seen as on or off. I didn’t think simply deleting the references to key timer was the best way to go so I commented them out. Seems that was wrong also. What would be the proper thing to do?

If it helps, the original sketch is actually found online. The original programmer’s description of the sketch is:

The Wire and LiquidCrystal libraries are used for I2C (LCD physical interface) and LCD routines for printing / cursor location etc

The NewSoftSerial library is used to create a software UART at 31250 baud for the MIDI out. This is because otherwise you have to use TX/RX which kills the USB port (used for my debugging)

The ports are setup for I/O as per the description earlier on. We enable the internal pull-ups on inputs by writing HIGH to the input pins

Three arrays are used to track what’s happening - keyActive (means pedal is ‘on’ this time around the loop), LastkeyActive (pedal has been processed as ‘on’ in a previous loop iteration) and keyTimer which counts the time between a pedal being ‘off’ and it reaching the ‘on’ position

The main program loop scans keys, sends any MIDI (note on, off, program change), reads the function buttons, updates the PWM LED brightness (if any are on) and updates the LCD if any of the relevant display items have changed. There is also a 1ms delay in the loop otherwise I found that the velocity reading was difficult to get working.

The scanKeys function looks at groups of inputs for the pedals. It uses bitmasks to pull out the contact pairs, and then looks at whether it’s transitioned from ‘off’ to ‘in between’ (if so it starts counting down keyTimer from 127), or if it’s fully ‘on’ of ‘off’. There are different lines to cope with the fact that not all positions in the diode matrix have pedals connected

outputMIDI has some switches to cope with the play mode - either polyphonic which is ‘normal’ or MONO mode which only sustains the last note, and only sends a note off if the playing note changes to a new one. This also calculates the velocity for note ons from the value of keyTimer such that fast transitions will result in higher velocities

doPWM deals with the fading in and out - which changes direction so it’s a nice glow, and also the speed is variable for the Octave display to indicate how many octaves up/down - 1 fade per second per octave

We’re going to be using an Arduino Uno instead of a Nano. The pin configuration is going to be different and I have drawings of the hardware wiring but I was going to worry about that later.

Thanks in advance for helping!

bass_pedals_001_pde.ino (15.6 KB)

Surely the easy way to stop it from using velocity is simply in the turnNoteOn() function. Change to:

void turnNoteOn(byte noteval, byte velvalue) {
  // NOTE - velocity set to constant 127, no longer using velvalue parameter 
  noteOn(midichan, noteval + (globTranspose * 12), 127); // Note on - with velocity 127
}

It's crude but it means if you decide using velocity was a good idea after all then it's a simple change back.

Now was there anything else you needed to work differently?

Steve

Great, thanks! I’ll give it a try. I’m also not sure which LiquidCrystal library I should be using. I tried using the one that the IDE already has but I get errors with it.

Since you asked, changes that were requested by the user are: 18 keyboard keys instead of 12, and the ‘D’ control key have the added function of being a MIDI channel button to increment from channel 1 to 5 then roll over back to 1. I’ve attached 2 drawings of the wiring diagram we’re using.

So far I've updated the pins for the led's and arrays for more keys.

unsigned char lastKeyActive[18];  // Array to hold which keys were active on last loop 0..17 = 18 pedals
unsigned char keyActive[18];  // Array to hold which keys were active on this loop
unsigned int keyTimer[18];  // Array to hold timers for measuring key velocity
#define octDownLEDPin 5   // Pin for octave down LED
#define octUpLEDPin 6   // Pin for octave up LED
#define modeLEDPin 3   // Pin for  mode LED

Am I on the right track?

Don't Forget to update the for Loops (for example in the Setup to clear everything, and two in function outputMIDI).

So I think I’m in the home stretch now. I believe that I have the compatible libraries, and my pin assignments are setup correctly. I get no errors now. The last feature I’m trying to implement is using the ‘function’ button which is buttonActive[5] in the scanButtons() function. At present, this button is not used for anything.

I would like for it to increment everytime the button is pressed the ‘midichan’ variable from 1 up to 5 and then roll over back to 1 if pressed again. ‘midichan’ was originally a constant and I made it into a variable as I believe that would be where to start. I’ve done some searching around in the forum and there doesn’t seem to be a quick easy way to do this. Am I mistaken? The latest version of my code is attached.

Once again, thanks to all that have helped me up to this point!

Once I get this last feature straightened out, I should be ready to load it on the Uno and try it!

bass_pedals_001_pde.ino (15.5 KB)

JDrummer, you did not heed my last post. You still have the following code:

In Setup:

  for (int i = 0; i < 13; i++) // Ensure arrays are cleared

Now that there are 18 keys instead of 12…

  for (int i = 0; i < 18; i++) // Ensure arrays are cleared

Incrementing through 5 and rolling over to 0 can be done in one line:

midichan = (midichan ==5) ? 0 : midichan++;

Read that as: if midichan = 5 then midichan = 0 else increase midichan by 1.

Or, you could do it in several lines:

midichan++;  // increment channel
if(midichan = 6)
  midichan = 0; //After 5, rollover to 0

Thanks Jaba for catching my oversight! And also thanks for the advice on incrementing midichan. I don't know why it didn't click for me earlier. Your multiline method is the same way that the progNumber variable is incremented and rolls over with button #3. I should've been able to recognize that.

The sketch compiled and was loaded onto the Uno. The LCD didn’t work. After some research, alot of people had the issue of the LCD’s documentation stating it’s address was 0x27 when in reality it wasn’t. To figure it out, we ran an I2C scanner sketch and discovered the LCD was 0x3F. Made the adjustment and solved that problem.

So here’s where I’m stuck now.

Now, the buttons don’t seem to work. I’m guessing I have the pin assignments wrong in the code. I’ve been researching but I am not understanding how the pin assignments on the board relate to how they’re coded. The schematics are attached in post #9.

My code is attached in this post. I’m sure I’m making more rookie mistakes. I appreciate any help that can be provided!

bass_pedals_midi_1.ino (15.6 KB)

I’ll have to admit, it’s confusing me too.

Your schematic says that 3, 5, and 6 are PWM. So, the schematic is referring to D3, D5, and D6 on the Arduino. Got it.

Your schematic also Shows 8-13. That’s six Pins if I know how to Count. The scanKeys() function starts off with: for (int i = 0; i < 5; i++) // Turn pins 12-17 high

#1, Isn’t that only five Pins (0 - 4)? So, what is it? 4 keys or 5 keys?

The comment says “Turn Pins 12-17 high”…

#2, What does the schematic mean when it says 8-13 and/or what does the code mean when it refers to 12-17. The math in scanKeys() also uses “i + 12” so it is definitely addressing the numbers 12 - 16. The “i < 5” causes the Loop to terminate as soon as i reaches 5, so 5+12 = 17 will not be used and therefore doesn’t match the comment.

#3), The schematic says that 14-17 refers to analog 0 through analog 3. If 14 refers then to analog 0, how could 12-17 refer to digital Pins?

Which Arduino board or ATMEGA chip are you using?

The pin numbering looks reasonable. Some of the confusion is because on the UNO the analog pins (A0-A5) can be used as digital IO pins in which case they can be addressed as pins 14-19. That's o.k.

But I'm still having trouble getting my head round what exactly the scan routines are doing and if the DDR settings are all correct.

Steve

Some of the confusion is because on the UNO the analog pins (A0-A5) can be used as digital IO pins in which case they can be addressed as pins 14-19. That's o.k

I agree. That numbering on the schematic would seem to indicate that the schematic is referring to a UNO.

However... The program itself seems to be using 12-16/17... Assuming the program is correct... That would indicate using maybe a Mega which leads to my question "what Atmega chip or Arduino board".

Something is definitly wrong with the program if it assumes that Pins 12-16/17 are digital Outputs and at the same time assumes that 14 is an analog pin.

Maybe the OP (JDrummer) could post an actual Picture of the Project. (?)

In post #15 Jdrummer says the code was loaded onto the Uno which seems fairly definite.

But where in the code can you see A0/Pin14 used as an analog input? The DDR setup seems to make it an output i.e. digital pin.

One problem I see is that SoftwareSerial is set up on pin 20 and AFAIK Uno doesn't have a pin 20. But perhaps that's o.k. if you never try to receive anything. Getting way outside my experience now!

Steve