0

this is my first post here. For some time I have been struggling with a problem and would like to know if anyone has a solution to share.

I am building a 4 tone sequencer, where I use 4 potentiometers to change the pitch of each tone beat. I want to add more beats to the sequencer so I would like to have an elegant solution instead of keep adding potentiometers. My idea was to use 1 potentiometer to control the pitch and use multiple push buttons with the single potentiometer for this process. All in all it goes like this: - When switch1=HIGH, pitch1=analogRead(A0); - When switch2=HIGH, pitch2=analogRead(A0); The problem is that when I change pitch1 and pitch2 the end up getting the same values as soon as I press their switch. My code looks like this:

   if(switch1state==HIGH)
  {
    Tone1Pot=analogRead(A0); // 0 – 1023
    pitch1=Tone1Pot/13;
  }

tone(speakerPin, notes[pitch1], 200);

Serial.print(pitch1);
Serial.print("     ");
delay(tempo);

if(switch2state==HIGH)
  {
    Tone2Pot=analogRead(A0); // 0 – 1023
    pitch2=Tone2Pot/13;  
  }

tone(speakerPin, notes[pitch2], 200);

Serial.print(pitch2);
Serial.print("     ");
delay(tempo);

I would really like to store that analog reading value when I press switch1 and keep it until switch1 goes HIGH again.

EDIT:

Let me try to explain the issue better: I have 2 push buttons and 1 potentiometer, all of them are inputs. The code I am aiming for is to do the following: 1 - While pressing push button1 I want to read the value of potentiometer and store it to a variable1. When the button1 is not pressed I want to keep that variable stored. 2 - While pressing push button2 I want to read the value of potentiometer and store it to a variable2. When the button2 is not pressed I want to keep that variable stored. I have successfully achieved this, however the problem comes when I press button1 again to adjust variable1, variable2 is also getting adjusted in the process, even when I am not pressing button2 Chris - The push buttons are correct since I can change the states of the digital pins when I press them ( and I measure the 5V when pressed). I do not need the buttons to be pressed at the same time. What I need is the buttons to trigger the event of storing potentiometer data only when either one of them is pressed accordingly. jsotola - Sorry for the bad explanation. I hope this one is better. Code:

#include "pitches.h"

int notes[]={

NOTE_B1,
NOTE_C2,
NOTE_CS2,
NOTE_D2,
NOTE_DS2,
NOTE_E2,
NOTE_F2,
NOTE_FS2,
NOTE_G2,
NOTE_GS2,
NOTE_A2,
NOTE_AS2,
NOTE_B2, 
NOTE_C3, 
NOTE_CS3,
NOTE_D3, 
NOTE_DS3,
NOTE_E3, 
NOTE_F3,
NOTE_FS3,
NOTE_G3, 
NOTE_GS3, 
NOTE_A3,  
NOTE_AS3, 
NOTE_B3,  
NOTE_C4,  
NOTE_CS4, 
NOTE_D4,  
NOTE_DS4, 
NOTE_E4,  
NOTE_F4,  
NOTE_FS4, 
NOTE_G4,  
NOTE_GS4, 
NOTE_A4,  
NOTE_AS4, 
NOTE_B4,  
NOTE_C5,  
NOTE_CS5, 
NOTE_D5,  
NOTE_DS5, 
NOTE_E5,  
NOTE_F5,  
NOTE_FS5, 
NOTE_G5,  
NOTE_GS5, 
NOTE_A5,  
NOTE_AS5, 
NOTE_B5,  
NOTE_C6,  
NOTE_CS6, 
NOTE_D6,  
NOTE_DS6, 
NOTE_E6,  
NOTE_F6,  
NOTE_FS6, 
NOTE_G6,  
NOTE_GS6, 
NOTE_A6,  
NOTE_AS6, 
NOTE_B6,  
NOTE_C7,  
NOTE_CS7, 
NOTE_D7,  
NOTE_DS7, 
NOTE_E7,  
NOTE_F7,  
NOTE_FS7, 
NOTE_G7,  
NOTE_GS7, 
NOTE_A7,  
NOTE_AS7, 
NOTE_B7,  
NOTE_C8, 
NOTE_CS8,
NOTE_D8,  
NOTE_DS8
};

int Tone = 0;
int speakerPin = 3;

int switch1=6;
int switch2=7;
int switch3=8;
int switch4=9;
int switch5=10;
int switch6=11;
int switch7=12;
int switch8=13;


void setup() {

Serial.begin(9600);

pinMode(switch1, INPUT);
pinMode(switch2, INPUT);
pinMode(switch3, INPUT);
pinMode(switch4, INPUT);
pinMode(switch5, INPUT);
pinMode(switch6, INPUT);
pinMode(switch7, INPUT);
pinMode(switch8, INPUT);


}

void loop() {

 // get potentiometers inputs
//int TonePot = analogRead(A0); // 0 – 1023
//int DurationPot = analogRead(A1); // 0 – 1023
int TempoPot = analogRead(A2); // 0 – 1023

int Tone1Pot;
int Tone2Pot;
int Tone3Pot;
int Tone4Pot;
int Tone5Pot;
int Tone6Pot;
int Tone7Pot;
int Tone8Pot;

int Duration1Pot;
int Duration2Pot;
int Duration3Pot;
int Duration4Pot;
int Duration5Pot;
int Duration6Pot;
int Duration7Pot;
int Duration8Pot;


// calculate corresponding, divide by 13 as we have 77 pitches. 1023/77 ~ 13
int pitch1;
int pitch2;
int pitch3;
int pitch4;
int pitch5;
int pitch6;
int pitch7;
int pitch8;

int pitch1stored;
int pitch2stored;

int noteduration1 = Duration1Pot/8;
int noteduration2 = Duration2Pot/8;
int noteduration3 = Duration3Pot/8;
int noteduration4 = Duration4Pot/8;
int noteduration5 = Duration5Pot/8;
int noteduration6 = Duration6Pot/8;
int noteduration7 = Duration7Pot/8;
int noteduration8 = Duration8Pot/8;

int tempo = TempoPot;


//Get state of switches if HIGH or LOW
int switch1state=digitalRead(switch1);
int switch2state=digitalRead(switch2);
int switch3state=digitalRead(switch3);
int switch4state=digitalRead(switch4);
int switch5state=digitalRead(switch5);
int switch6state=digitalRead(switch6);
int switch7state=digitalRead(switch7);
int switch8state=digitalRead(switch8);


////////////////////////////////////////Sound generation code /////////////////////////////////

if(switch1state==HIGH)
  {
    Tone1Pot=analogRead(A0); // 0 – 1023
    pitch1=Tone1Pot/13;
  }

tone(speakerPin, notes[pitch1], 200);

//tone(speakerPin, 0, 200);}// make the tone mute

Serial.print("pitch1= ");
Serial.print(pitch1);
Serial.print("     ");
delay(tempo);



if(switch2state==HIGH)
  {
    Tone2Pot=analogRead(A0); // 0 – 1023
    pitch2=Tone2Pot/13;  
  }

tone(speakerPin, notes[pitch2], 200);

Serial.print("pitch2= ");
Serial.print(pitch2);
Serial.print("     ");
delay(tempo);



if(switch3state==HIGH)
  {
    Tone3Pot=analogRead(A0); // 0 – 1023
    pitch3=Tone3Pot/13;  
  }

tone(speakerPin, notes[pitch3], 200);

Serial.print("pitch3= ");
Serial.print(pitch3);
Serial.print("     ");
delay(tempo);
}
  • what causes this state? switch1=HIGH – jsotola Feb 11 at 18:38
  • 1
    The description of your problem is unclear to me, please elaborate more. Also please provide the full code, not just a small part of it. – chrisl Feb 11 at 19:33
  • store that analog reading value when I press switch1 and keep it until switch1 goes HIGH again ... what does that mean? ... what does switch1 goes HIGH again actually mean? ... i think that your main problem is that you do not actually know how you want the device to work – jsotola Feb 11 at 20:37
1

I cannot see, how your code would show the described behavior (assuming that, you have connected the buttons correctly with a pulldown resistor). But your code can be greatly simplified, which would make it less error prone.

You have 8 buttons, which screams for the usage of arrays (IMO you should always use arrays, if you have more than 2 or 3 equal buttons). First put the button pins into an array:

#define N_BUTTONS 8
int button_pins[N_BUTTONS] = {6, 7, 8, 9, 10, 11, 12, 13};

Then define an array to hold the measured pitches (here initialized with 0):

int pitches[N_BUTTONS] = {0};

In your setup() function you can loop over the button_pins array to set them as input:

for(int pin : button_pins) pinMode(pin, INPUT);

In the loop() function you again loop over the button pins, but this time you check, if the current button is pressed. If yes, you measure the analog voltage, calculate the pitch and save it into the corresponding element of the pitches array:

for(int button=0;button < N_BUTTONS;button++){
    if(digitalRead(button_pins[button])){
        pitches[button] = analogRead(A0)/13;
    }
}

This always works for multiple pressed buttons at once.

Also you should avoid calls to delay() in your loop() function. That is just time, that the Arduino cannot do anything, including checking your buttons. If you want to do something timed, you should use a non-blocking coding style, like in the BlinkWithoutDelay example, that comes with the Arduino IDE. Basically it uses the millis() function as a clock, checking regularily, if the needed time has passed and only doing something if it had passed; letting other code execute, if not. There are tons of tutorials about this on the web.

As you have seen above, I didn't include the tone() function in my answer. That is because you should decouple your input and output code. The code above is the input code. It saves the wanted pitches into the corresponding array. Then, after that code, you can write all the code you need for outputting the pitches as tones (however you actually want to output them). The only real logical connection between these 2 parts of code is the pitches array. That makes it easier to have more and different inputs (for example if you wanted to have a reset button, which sets all the pitches at onece to a predefined value). Also the function of the input code (which needs to very regularily check the buttons, to be responsive) is not disturbed by the output code.

| improve this answer | |
  • Thank you so much for the support. I will change my code accordingly and will get back to you to show the results. – Sushyoshi Feb 12 at 15:14
  • I am trying to compile your code but encountered a problem which I cannot resolve for(int button=0;button < N_BUTTONS;button++){ if(digitalRead(button_pins[button])){ pitches[button] = analogRead(A0)/13; } } The above code gives me the following error: "exit status 1 expected primary-expression before ';' token" Any thoughts? – Sushyoshi Feb 12 at 16:40
  • The bit of code, that you are showing, is ok. The error must lay in the rest of the code, most probably above – chrisl Feb 12 at 20:02
  • I cant seem to find where the error is. I have looked for the whole code, maybe I am missing something. Error code: Arduino: 1.8.10 (Windows 10), Board: "Arduino/Genuino Uno" C:\Users\teclast\Documents\Arduino\Sequencer_Project_Version0.1\Sequencer_Project_Version0.1.ino: In function 'void loop()': Sequencer_Project_Version0.1:105:36: error: expected primary-expression before ';' token for (int button=0; button<N_BUTTONS; button++){ ^ exit status 1 expected primary-expression before ';' token – Sushyoshi Feb 13 at 2:05
  • I have been trying to get that bit of code to work and it doesn't let me use the code: 'for(int button=0;button < N_BUTTONS;button++){' If I change N_BUTTONS to 8 the code gets accepted. With this I can change the value of pitches[0] with the analog read and button[0], however I cannot change the value of pitches[1] afterwards and so on. – Sushyoshi Feb 13 at 4:42
0

So based on the information you provided I understand that the issue is that both the if(switch1state==HIGH) and the `if(switch2state==HIGH)' statements evaluate to true if either switch is flipped. That means one of the following things is happening:

1) Somewhere in your code you're mixing their values and assigning ones value to the other

2) Your configuration of the digitalRead pins is wrong (either wrong pins or wrong pupdr config as I've seen incorrect pull-up and pull-down resistors propagate unexpected behavior across the ground)

3) your wires are crossed. If you're using a breadboard make sure you know how it's connected internally. Some swap between horizontal and vertical rows.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.