Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Programming Arduino Uno using a 2 dimentional array issue

Status
Not open for further replies.

banjorobbie

New Member
Hello, this is my first post here so please forgive me for any errors posting this.
I have an Uno programmed to play a note on each of 3 buttons. Originally this worked fine as it was using a set scale of 3 notes but I wanted to use a pot to select one of 3 scales for each of those buttons to play. I've set about using a 2d array to hold all the notes and I have a pot that's mapped to output a value of 0-2 to reference each of the 3 scales but I'm unable to understand how to continue from this point in my code to access the array in order to change scales.
Any help at all would be welcome
Code:
// musical notes
int C = 1046;
int D = 1175;
int E = 1319;
int F = 1397;
int G = 1598;
int A = 1760;
int B = 1976;
int C1 = 2093;
int D1 = 2349;

const int columns = 3;
const int scales = 3;
int potVal = 0;
const int  notes[scales][columns] = {
  {C, D, E},
  {F, G, A},
  {B, C1, D1}
};

const int numberOfButtons = 3;
int buttonPin[numberOfButtons] = {2, 7, 4};
int ledPin[numberOfButtons] = {11, 10, 9};

int buttonState = 0;         // variable for reading the pushbutton status
int speaker = 3;                 // name of the speaker key

void setup() {
  Serial.begin(9600);

  for (int i = 0; i < numberOfButtons; i++) {
    pinMode(buttonPin[i], INPUT);
    pinMode(ledPin[i], OUTPUT);
  }
  pinMode(speaker, OUTPUT);     // set speaker to be an output
}

void loop() {
  int potVal = map(analogRead(A2), 0, 1024, 0, 3);
  Serial.println(potVal);
  for (int i = 0; i < numberOfButtons; i++) {
    checkButton(buttonPin[i], notes[i], ledPin[i]);
  }
}

void checkButton(int buttonPin, int note, int ledPin)
{
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
    tone(speaker, note);                 // play the note
    delay(100);                       // wait for 1/10th of a second
  } else {
    digitalWrite(ledPin, LOW);
    noTone(speaker);                  // stop playing the note
  }
}
 
You need to access your array using the two dimensions. So notes[n} should be notes[n][j] so both dimensions are used. Couldn't use i in the square brackets as that turns on italics.

Mike.
Edit, try adding Serial.println(notes[2][2]); in your setup and you should see 2349.
 
As you may already worked out, arrays in C start with index of zero so your array indexes go from 0 to 2 - not 1 to 3.

Mike.
 
In your checkbutton routine pass the scale (pot reading) instead of note and choose the note using scale and button number.

BTW, your pot needs to map to 0 to 2 instead of 0 to 3.

Mike.
 
Your giving me gems here thanks Mike!! "BTW, your pot needs to map to 0 to 2 instead of 0 to 3." Apparrently doing it this way and using 1024 instead of 1023 gives an even spread of 0-2 across the pots travel.
 
Apparrently doing it this way and using 1024 instead of 1023 gives an even spread of 0-2 across the pots travel.
I've learned something new today. It actually makes sense now as 1023/1024 is 2.9999 something and so gets rounded down to 2. Mapping to 0 to 2 would mean that only the very last position would map to 2.

Mike.
 
Code:
// musical notes
int C = 1046;
int D = 1175;
int E = 1319;
int F = 1397;
int G = 1598;
int A = 1760;
int B = 1976;
int C1 = 2093;
int D1 = 2349;

const int columns = 3;
const int scales = 3;
int potVal = 0;
const int  notes[scales][columns] = {
  {C, D, E},
  {F, G, A},
  {B, C1, D1}
};

const int numberOfButtons = 3;
int buttonPin[numberOfButtons] = {2, 7, 4};
int ledPin[numberOfButtons] = {11, 10, 9};

int buttonState = 0;         // variable for reading the pushbutton status
int speaker = 3;                 // name of the speaker key

void setup() {
  Serial.begin(9600);

  for (int i = 0; i < numberOfButtons; i++) {
    pinMode(buttonPin[i], INPUT);
    pinMode(ledPin[i], OUTPUT);
  }
  pinMode(speaker, OUTPUT);     // set speaker to be an output
}

void loop() {
  int potVal = map(analogRead(A2), 0, 1024, 0, 3);
  Serial.println(notes[2][2]);
  for (int i = 0; i < numberOfButtons; i++) {
    checkButton(buttonPin[i], notes[scales][columns], ledPin[i]);
  }
}

void checkButton(int buttonPin, int potVal, int ledPin)
{
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
    tone(speaker, note);                 // play the note
    delay(100);                       // wait for 1/10th of a second
  } else {
    digitalWrite(ledPin, LOW);
    noTone(speaker);                  // stop playing the note
  }
}
Thats what I have so far.....
 
You need to pass numbers to checkButton so change to checkButton(i, potVal, ledPin);

Then change checkButton to,
Code:
void checkButton(int button, int scale, int ledPin)
{
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin[button]);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
    tone(speaker, note[scale][button]);                 // play the note
    delay(100);                       // wait for 1/10th of a second
  } else {
    digitalWrite(ledPin, LOW);
    noTone(speaker);                  // stop playing the note
  }
}
Note, untested code so may contain syntax errors.

Mike.
Edit, probably can't use note as a variable so changed to scale.
 
I've changed note to notes at the beginning "tone(speaker, notes[note][button]);" and now I have "'button' was not declared in this scope"
I need to declare the button?
 
Does that mean it's working as expected?

Mike.
Edit, buttonPin is the array containing the pin numbers. You need the button index which is 0 to 2.
Edit2, the note you need to play is defined by the scale set by the pot and which button is pressed (i in your for loop) and is found in notes[potVal][j]. HTH. Had to change to [j] to stop stupid BB from turning on italics.
 
Last edited:
I wish!!! Very close though....I'm getting a different note with each button though they're not from a scale exactly plus the pot isn't changing anything......This is what I have now....
Code:
// musical notes
int C = 1046;
int D = 1175;
int E = 1319;
int F = 1397;
int G = 1598;
int A = 1760;
int B = 1976;
int C1 = 2093;
int D1 = 2349;

const int columns = 3;
const int scales = 3;
int potVal = 0;
const int  notes[scales][columns] = {
  {C, D, E},
  {F, G, A},
  {B, C1, D1}
};

const int numberOfButtons = 3;
int buttonPin[numberOfButtons] = {2, 7, 4};
int ledPin[numberOfButtons] = {11, 10, 9};

int buttonState = 0;         // variable for reading the pushbutton status
int speaker = 3;                 // name of the speaker key

void setup() {
  Serial.begin(9600);

  for (int i = 0; i < numberOfButtons; i++) {
    pinMode(buttonPin[i], INPUT);
    pinMode(ledPin[i], OUTPUT);
  }
  pinMode(speaker, OUTPUT);     // set speaker to be an output
}

void loop() {
  int potVal = map(analogRead(A2), 0, 1024, 0, 3);
  Serial.println(notes[2][2]);
  for (int i = 0; i < numberOfButtons; i++) {
    checkButton(buttonPin[i], notes[scales][columns], ledPin[i]);
  }
}

void checkButton(int buttonPin, int note, int ledPin)
{
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
    tone(speaker, notes[potVal][buttonPin]);                 // play the note
    delay(100);                       // wait for 1/10th of a second
  } else {
    digitalWrite(ledPin, LOW);
    noTone(speaker);                  // stop playing the note
  }
}
 
I switched "tone(speaker, notes[note][buttonPin]);" for "tone(speaker, notes[potVal][buttonPin]);" but it made no difference
 
each button in sequence gives me a note, a higher note and then a note in between!

so there's no order looking at the array
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top