Simple Array Confusion. 9 Button Keyboard.h

Thanks UKHeliBob, I completely missed that space in the array.

I'm still not grasping what PaulS advised on and trying to find some examples.

/*
  Keyboard Message test

  For the Arduino Leonardo and Micro.

  Sends a text string when a button is pressed.

  The circuit:
   pushbutton attached from pin 4 to +5V
   10-kilohm resistor attached from pin 4 to ground

  created 24 Oct 2011
  modified 27 Mar 2012
  by Tom Igoe
  modified 11 Nov 2013
  by Scott Fitzgerald

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/KeyboardMessage
*/
#include <MIDI_controller.h> // include the library
#include "Keyboard.h"
int buttonPins[9] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
int previousButtonState[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};  // for checking the state of a pushButton

const static byte Channel_Volume = 0x07; // controller number 7 is defined as Channel Volume in the MIDI implementation.
const static byte Pan_Volume = 0x0A;
const static size_t analogAverage = 8; // Use the average of 8 samples to get smooth transitions and prevent noise

Analog fader1(A0, Channel_Volume, 1); // Create a new instance of the class 'Analog, called 'fader', on pin A0, that sends MIDI messages with controller 7 (channel volume) on channel 1.
Analog fader2(A1, Pan_Volume, 1);

char keyValues[] = " ?,.rms??";


void setup()

{
  for (int i = 0; i < 9; i++)
    pinMode(buttonPins[i], INPUT_PULLUP);
  Keyboard.begin();  // initialize control over the keyboard:
  {
    USBMidiController.blink(13);  // flash the LED on pin 13 on every message
    USBMidiController.setDelay(15);  // wait 15 ms after each message not to flood the connection
    delay(1000); // Wait a second...
    fader1.average(analogAverage); // Use the average of 8 samples to get smooth transitions and prevent noise
    fader2.average(analogAverage);
  }
  keyValues[1] = (char)KEY_RETURN;
  keyValues[7] = (char)KEY_UP_ARROW;
  keyValues[8] = (char)KEY_DOWN_ARROW;
}

void loop()
{
  fader1.refresh(); // refresh the fader (check whether the input has changed since last time, if so, send it over MIDI)
  fader2.refresh();

  {
    for (int i = 0; i < 9; i++)
    {
      int buttonState = digitalRead(buttonPins[i]);  // read the pushbutton
      if ((buttonState != previousButtonState[i])  // if the button state has changed
          && (buttonState == LOW))  // and it's currently pressed
      {
        byte arrLen = strlen(keyValues);
        for (byte b = 0; b = arrLen; b++);
        {
          Keyboard.write(keyValues[i]);
        }
      }
      previousButtonState[i] = buttonState;  // save the current button state for comparison next time
    }
  }
}

Dizzwold.

Paul was suggesting putting a ? in the array and subsequently replacing it with the required character. Doing it that way would allow you to put in characters that you cannot type and to put in characters defined elsewhere that you might not even know the value of.

Thats what I thought PaulS was suggesting, but I'm missing the bigger picture.

I appreciate that using the ?s, I'm then afterwards trying to state what each of them are for, ie keys that I can't type, up down and return keys.

I've tried moving a shuffling things around, but don't see what i'm missing?

/*
  Keyboard Message test

  For the Arduino Leonardo and Micro.

  Sends a text string when a button is pressed.

  The circuit:
   pushbutton attached from pin 4 to +5V
   10-kilohm resistor attached from pin 4 to ground

  created 24 Oct 2011
  modified 27 Mar 2012
  by Tom Igoe
  modified 11 Nov 2013
  by Scott Fitzgerald

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/KeyboardMessage
*/
#include <MIDI_controller.h> // include the library
#include "Keyboard.h"
int buttonPins[9] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
int previousButtonState[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};  // for checking the state of a pushButton

const static byte Channel_Volume = 0x07; // controller number 7 is defined as Channel Volume in the MIDI implementation.
const static byte Pan_Volume = 0x0A;
const static size_t analogAverage = 8; // Use the average of 8 samples to get smooth transitions and prevent noise

Analog fader1(A0, Channel_Volume, 1); // Create a new instance of the class 'Analog, called 'fader', on pin A0, that sends MIDI messages with controller 7 (channel volume) on channel 1.
Analog fader2(A1, Pan_Volume, 1);

char keyValues[] = " ?,.rms??";
keyValues[1] = (char)KEY_RETURN;
keyValues[7] = (char)KEY_UP_ARROW;
keyValues[8] = (char)KEY_DOWN_ARROW;

void setup()

{
  for (int i = 0; i < 9; i++)
    pinMode(buttonPins[i], INPUT_PULLUP);
  Keyboard.begin();  // initialize control over the keyboard:
  {
    USBMidiController.blink(13);  // flash the LED on pin 13 on every message
    USBMidiController.setDelay(15);  // wait 15 ms after each message not to flood the connection
    delay(1000); // Wait a second...
    fader1.average(analogAverage); // Use the average of 8 samples to get smooth transitions and prevent noise
    fader2.average(analogAverage);
  }
}

void loop()
{
  fader1.refresh(); // refresh the fader (check whether the input has changed since last time, if so, send it over MIDI)
  fader2.refresh();

  {
    for (int i = 0; i < 9; i++)
    {
      int buttonState = digitalRead(buttonPins[i]);  // read the pushbutton
      if ((buttonState != previousButtonState[i])  // if the button state has changed
          && (buttonState == LOW))  // and it's currently pressed
      {
        byte arrLen = strlen(keyValues);
        for (byte b = 0; b = arrLen; b++);
        {
          Keyboard.write(keyValues[i]);
        }
      }
      previousButtonState[i] = buttonState;  // save the current button state for comparison next time
    }
  }
}

Dizzwold.

but don't see what i'm missing?

Well, you certainly aren't missing useless curly braces.

What you are missing is:

  1. Other than variable/array declaration statements that contain assignment constructs, all assignments of values MUST happen in functions, like setup().

  2. an explanation of what the code ACTUALLY does.

        for (byte b = 0; b = arrLen; b++);
        {
          Keyboard.write(keyValues[i]);
        }

How many times do you want to send the key value ?

Sorry, that was me moving things around to try, and not puting them back 'where I think they should be'.

Are there any more curly braces uneeded? I've got rid of a couple in set-up, and atleast the faders now work, but yet to figure out the switches.

Just spotted 1 of my many errors, and missed the line;

Keyboard.write(stuffToDo[b]);

This has added further confusion and curly braces;

/*
  Keyboard Message test

  For the Arduino Leonardo and Micro.

  Sends a text string when a button is pressed.

  The circuit:
   pushbutton attached from pin 4 to +5V
   10-kilohm resistor attached from pin 4 to ground

  created 24 Oct 2011
  modified 27 Mar 2012
  by Tom Igoe
  modified 11 Nov 2013
  by Scott Fitzgerald

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/KeyboardMessage
*/
#include <MIDI_controller.h> // include the library
#include "Keyboard.h"
int buttonPins[9] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
int previousButtonState[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};  // for checking the state of a pushButton

const static byte Channel_Volume = 0x07; // controller number 7 is defined as Channel Volume in the MIDI implementation.
const static byte Pan_Volume = 0x0A;
const static size_t analogAverage = 8; // Use the average of 8 samples to get smooth transitions and prevent noise

Analog fader1(A0, Channel_Volume, 1); // Create a new instance of the class 'Analog, called 'fader', on pin A0, that sends MIDI messages with controller 7 (channel volume) on channel 1.
Analog fader2(A1, Pan_Volume, 1);

char keyValues[] = " ?,.rms??";


void setup()

{
  for (int i = 0; i < 9; i++)
    pinMode(buttonPins[i], INPUT_PULLUP);
  Keyboard.begin();  // initialize control over the keyboard:
  {
    USBMidiController.blink(13);  // flash the LED on pin 13 on every message
    USBMidiController.setDelay(15);  // wait 15 ms after each message not to flood the connection
    delay(1000); // Wait a second...
    fader1.average(analogAverage); // Use the average of 8 samples to get smooth transitions and prevent noise
    fader2.average(analogAverage);

    keyValues[1] = (char)KEY_RETURN;
    keyValues[7] = (char)KEY_UP_ARROW;
    keyValues[8] = (char)KEY_DOWN_ARROW;
  }
}

void loop()
{
  fader1.refresh(); // refresh the fader (check whether the input has changed since last time, if so, send it over MIDI)
  fader2.refresh();

  {
    for (int i = 0; i < 9; i++)
    {
      int buttonState = digitalRead(buttonPins[i]);  // read the pushbutton
      if ((buttonState != previousButtonState[i])  // if the button state has changed
          && (buttonState == LOW))  // and it's currently pressed
      {
        Keyboard.write(keyValues[i]);
        {       
          byte arrLen = strlen(keyValues);
          for (byte b = 0; b = arrLen; b++);
          {
            Keyboard.write(keyValues[b]);
          }
        }
      }
      previousButtonState[i] = buttonState;  // save the current button state for comparison next time
    }
  }
}

Dizzwold.

  Keyboard.begin();  // initialize control over the keyboard:
  { // <-- Useless curly brace
  fader2.refresh();

  { // <-- Useless curly brace
          for (byte b = 0; b = arrLen; b++);

Starting with b equal to 0, while b is assigned the value 9, do...

Really?

You have your other for loops right. Why is this one wrong?

The semicolon after the parens is probably not wanted either.

I'm at a complete loss with this extra array.

Should I be declaring something in the globals for it? Also is the following in the correct place?

 keyValues[1] = (char)KEY_RETURN;
  keyValues[7] = (char)KEY_UP_ARROW;
  keyValues[8] = (char)KEY_DOWN_ARROW;
/*
  Keyboard Message test

  For the Arduino Leonardo and Micro.

  Sends a text string when a button is pressed.

  The circuit:
   pushbutton attached from pin 4 to +5V
   10-kilohm resistor attached from pin 4 to ground

  created 24 Oct 2011
  modified 27 Mar 2012
  by Tom Igoe
  modified 11 Nov 2013
  by Scott Fitzgerald

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/KeyboardMessage
*/
#include <MIDI_controller.h> // include the library
#include "Keyboard.h"
int buttonPins[9] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
int previousButtonState[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};  // for checking the state of a pushButton

const static byte Channel_Volume = 0x07; // controller number 7 is defined as Channel Volume in the MIDI implementation.
const static byte Pan_Volume = 0x0A;
const static size_t analogAverage = 8; // Use the average of 8 samples to get smooth transitions and prevent noise

Analog fader1(A0, Channel_Volume, 1); // Create a new instance of the class 'Analog, called 'fader', on pin A0, that sends MIDI messages with controller 7 (channel volume) on channel 1.
Analog fader2(A1, Pan_Volume, 1);

char keyValues[] = " ?,.rms??";

void setup()
{
  for (int i = 0; i < 9; i++)
    pinMode(buttonPins[i], INPUT_PULLUP);
  Keyboard.begin();  // initialize control over the keyboard:

  USBMidiController.blink(13);  // flash the LED on pin 13 on every message
  USBMidiController.setDelay(15);  // wait 15 ms after each message not to flood the connection
  delay(1000); // Wait a second...
  fader1.average(analogAverage); // Use the average of 8 samples to get smooth transitions and prevent noise
  fader2.average(analogAverage);

  keyValues[1] = (char)KEY_RETURN;
  keyValues[7] = (char)KEY_UP_ARROW;
  keyValues[8] = (char)KEY_DOWN_ARROW;
}

void loop()
{
  fader1.refresh(); // refresh the fader (check whether the input has changed since last time, if so, send it over MIDI)
  fader2.refresh();

  for (int i = 0; i < 9; i++)
  {
    int buttonState = digitalRead(buttonPins[i]);  // read the pushbutton
    if ((buttonState != previousButtonState[i])  // if the button state has changed
        && (buttonState == LOW))  // and it's currently pressed
    {
      Keyboard.write(keyValues[i]);
      {
        byte arrLen = strlen(keyValues);
        for (byte b = 0; b = 9; b++);
        {
          Keyboard.write(keyValues[b]);
        }
      }
    }
    previousButtonState[i] = buttonState;  // save the current button state for comparison next time
  }
}

Dizzwold.

I'm at a complete loss with this extra array.

Which extra array ?

That says it all. Ok there is no extra array.

I think I need to declare something in the globals, and a way to associate the return, up and down keys with b?

Dizzwold.

Declare and initialise the array at the start of the program so that it is a global variable

char keyValues[] = " ?,.rms??";

In setup() replace the question marks with the special key values

keyValues[1] = (char)KEY_RETURN;
keyValues[7] = (char)KEY_UP_ARROW;
keyValues[8] = (char)KEY_DOWN_ARROW;

You cannot do this outside of a function, but because the array was declared as a global then it, and the newly inserted values, are available anywhere in the program.
Now you can refer to any of the chars in the array, including the special key values, by using the index to the array.

There are 9 values in the array each corresponding to an input pin number. So, if you read each of the inputs in turn using a for loop to iterate through the input pin array and find a button pressed you can output the corresponding key value using the current value of the for loop variable used to read the input.

Finally I've got it. That was hardwork and 2 days.

The thing that confused me was with PaulS stating;

 byte arrLen = strlen(stuffToDo);
   for(byte b=0; b<arrLen; b++)
   {
     Keyboard.write(stuffToDo[b]);
   }

I didn't need this as I already had it.

I appreciate this may have been frustraiting to you who are wiser.

Thank you for all your advice.

At least, you can't say "I've not been entertaining".

Dizzwold.

/*
  Keyboard Message test

  For the Arduino Leonardo and Micro.

  Sends a text string when a button is pressed.

  The circuit:
   pushbutton attached from pin 4 to +5V
   10-kilohm resistor attached from pin 4 to ground

  created 24 Oct 2011
  modified 27 Mar 2012
  by Tom Igoe
  modified 11 Nov 2013
  by Scott Fitzgerald

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/KeyboardMessage
*/
#include <MIDI_controller.h> // include the library
#include "Keyboard.h"
int buttonPins[9] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
int previousButtonState[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};  // for checking the state of a pushButton

const static byte Channel_Volume = 0x07; // controller number 7 is defined as Channel Volume in the MIDI implementation.
const static byte Pan_Volume = 0x0A;
const static size_t analogAverage = 8; // Use the average of 8 samples to get smooth transitions and prevent noise

Analog fader1(A0, Channel_Volume, 1); // Create a new instance of the class 'Analog, called 'fader', on pin A0, that sends MIDI messages with controller 7 (channel volume) on channel 1.
Analog fader2(A1, Pan_Volume, 1);

char keyValues[] = " ?,.rms??";

void setup()
{
  for (int i = 0; i < 9; i++)
    pinMode(buttonPins[i], INPUT_PULLUP);
  Keyboard.begin();  // initialize control over the keyboard:

  USBMidiController.blink(13);  // flash the LED on pin 13 on every message
  USBMidiController.setDelay(15);  // wait 15 ms after each message not to flood the connection
  delay(1000); // Wait a second...
  fader1.average(analogAverage); // Use the average of 8 samples to get smooth transitions and prevent noise
  fader2.average(analogAverage);

  keyValues[1] = (char)KEY_RETURN;
  keyValues[7] = (char)KEY_UP_ARROW;
  keyValues[8] = (char)KEY_DOWN_ARROW;
}

void loop()
{
  fader1.refresh(); // refresh the fader (check whether the input has changed since last time, if so, send it over MIDI)
  fader2.refresh();

  for (int i = 0; i < 9; i++)
  {
    int buttonState = digitalRead(buttonPins[i]);  // read the pushbutton
    if ((buttonState != previousButtonState[i])  // if the button state has changed
        && (buttonState == LOW))  // and it's currently pressed
    {
      Keyboard.write(keyValues[i]);    
    }
    previousButtonState[i] = buttonState;  // save the current button state for comparison next time
  }
}

Finally I've got it. That was hardwork and 2 days.

But the good news is that you got there in the end.

One small change that I would make is to make the buttonPins and previousButtonState arrays of byte instead of int. The program will work the same way but will use less memory. Not important here but in general it is better to use the smallest variable type possible.