Trying to turn my buttons into on/off toggle switches

Edit:
The code I provided IS function besides the button parts which is why I asked for help, no matter what I try I can't make it work the way I want. ALSO right now i’ve only changed the way the buttons work in the first if statment, because I still haven’t found a way to make those function the way I want them to, but once I do I’ll change all of them

I think the comments made it quite clear that my post was a bit vague, but stay with me now guys, I'm new to posting here and i'll try my best to clear things up.

Okay so I wanna make little device that makes a noice depending on how on object is away from the supersonic sensor, which you could probably see from the code, I want the noise to change depending on which button you pressed last. So for example if I pressed knop1 it would change the pitch it plays for all distances.

If there are any more questions let me know in the comments and i'll try helping out sooner next time!

// Ultrasonic pins
const int trigPin = 9;
const int echoPin = 10;

// LED pins
const int led1 = 5;
const int led2 = 4;
const int led3 = 2;
const int led4 = 6;

// Speaker pin
const int speakerPin = 3;

// Buttons
const int button1 = 7;
const int button2 = 8;
const int button3 = 12;

bool b1 = false;
bool b2 = false;
bool b3 = false;

#include "pitches.h"

long duration;
int distance;

int selectedNote = NOTE_C5;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);

  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);

  Serial.begin(9600);
}

void loop() {

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2;

  Serial.print("Distance: ");
  Serial.println(distance);
   if (distance <= 5) {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);    

    if (digitalRead(button1)) {
      b1 = true;
    }
    if (digitalRead(button2)) {
      b2 = true;
      selectedNote = NOTE_D4;
      Serial.println("knop2");
    }
    if (digitalRead(button3)) {
      b3 = true;
      selectedNote = NOTE_E4;
      Serial.println("knop3");
    }
    else{
      selectedNote = NOTE_B4;
    }

    if(b1 == true){
      selectedNote = NOTE_C4;
      Serial.println("knop1");
    }
    
    tone(speakerPin, selectedNote, 100);
  } 
  else if (distance <= 10) {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, LOW);

    if (digitalRead(button1)) {
      selectedNote = NOTE_C5;
      Serial.println("knop1");
    }
    if (digitalRead(button2)) {
      selectedNote = NOTE_D5;
      Serial.println("knop2");
    }
    if (digitalRead(button3)) {
      selectedNote = NOTE_E5;
      Serial.println("knop3");
    }
    else{
      selectedNote = NOTE_B5;
    }
    
    tone(speakerPin, selectedNote, 100);
  } 
  else if (distance <= 15) {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);

    if (digitalRead(button1)) {
      selectedNote = NOTE_C6;   
      Serial.println("knop1");
    }
    if (digitalRead(button2)) {
      selectedNote = NOTE_D6;
      Serial.println("knop2");
    }
    if (digitalRead(button3)) {
      selectedNote = NOTE_E6;
      Serial.println("knop3");
    }
    else{
      selectedNote = NOTE_B6;
    }
       
    tone(speakerPin, selectedNote, 100);
  }
  else if (distance <= 20) {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);

    if (digitalRead(button1)) {
      selectedNote = NOTE_C7;
      Serial.println("knop1");
    }
    if (digitalRead(button2)) {
      selectedNote = NOTE_D7;
      Serial.println("knop2");
    }
    if (digitalRead(button3)) {
      selectedNote = NOTE_E7;
      Serial.println("knop3");
    }
    else{
      selectedNote = NOTE_B7;
    }   
     
    tone(speakerPin, selectedNote, 100);
  }
  else {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);

    noTone(speakerPin);
  }

  delay(100);
}

I added the entire code

What happens now?

How are the buttons connected?

For context, tell us if you wrote that code. If not you, who or what did?

Either way, do you understand the code, how it is working now?

And tell us what you are seeing now that is not what you want.

Strip this away to one button that can toggle (turn on and off) one tone.

It's called state change (or edge) detection, a hole thing. Here's a demo, take the link in the comment at the top to see the context in which I offered it.

I'm in transit, I hunt down another thread on the topic when I get to the lab.

There's also a demo amongst the examples on offer in the IDE, it links to a competent article on this basic subject.

a7

2 Likes

You might start your search in the 'related topics' at the bottom of the thread.

You might want to do some research on a theremin, they sort of do what you want and have been around a long time. Theremin is an electronic musical instrument played without physical contact. It uses two metal antennas to control pitch and volume through the movement of the player's hands in the air around them.

How do the LEDs fit into your project?

I can see you turn them all ON when the distance is short, but once this happens you never turn them OFF

Buttons are only sensed when object is within 5cm. Can you draw a picture of what you intend?

knop2
Distance: 1 // not true... distance = 2cm
b1 toggled to: 0
knop2
Distance: 2
knop2
Distance: 1

I am confused. A toggle switch is either on or off. Your push button switch is either on or off. Both switches operate the same.

Are you really wanting your push button switches to do one thing the first time it is pressed and do something different with a second press? That is way different and can be easily programmed by counting the number of presses of your push button. If your button is pressed and the count is now 1, do something for the first press. If the count is now 2, do the second thing and reset the count back to 0.

I think the edits i made should clear up your question, if not let me know if you still have questions

I edited my post, maybe now you can see how it works, but just in case, the LEDS aren’t that important here, all they do is light up depending on the distance the supersonic sensor detects.

i figured that that shortened piece of code would be enough for people to be able help me out, but i suppose i was wrong. so to answer your question It also detects objects from 5-10cm, 10-15cm and 15-20 cm away. And what i want is that whenever i press a button it changes the tone it would play if the supersonic sensor detects something.

I understand your confusion, the reason you might think that is because my code was a little messy, but no that was not my intention. The thing I want it to do is to toggle on and off, when the button is toggled off my speaker should play the tone assigned to the distance the supersonic sensor detects. When I toggle the button on, the speaker should play the tone my button assigns the “selectedNote” to.

You say

what i want is that whenever i press a button it changes the tone it would play if the supersonic sensor detects something.

And you say

The thing I want it to do is to toggle on and off, when the button is toggled off my speaker should play the tone my button assigns the “selectedNote” to.

So it's still not clear (to me) what you are trying to do. What is clear, clearer anyway, is that you need to look into button handling and how to do things when a button gets pressed, not because it is pressed but because it became pressed, and how to do things when a button gets released, again not because it is up (released) but because it became released.

I posted an example of state change (edge) detection above. Try it out. Read the code. Read

https://docs.arduino.cc/built-in-examples/digital/StateChangeDetection/

Here's another example. Try it here

Wokwi_badge State Change Detection

and see the thread where I posted it for more.

a7

I think I understand what you want. You want the button to do something, not WHILE it is pressed, but IF it has been pressed.

1-Press the button and do an action regardless of if the button is held pressed or released.

2-Press the button again and do another action regardless of if the button is held pressed or released.

I would advise this…forget about your sketch for a little bit. Write a new one just for the button toggle action and use the serial monitor.

1-When the button is pressed once you can serial print a message. See if the message stays there when you release the button.

2-When the button is pressed again you can serial print another message and see if it stays there when you release the button.

The way to do this is to read the current button state. In an if statement compare the current button state to the previous button state. Debounce the button. Do the code in the if statement (or set a flag). Outside of the if statement set the previous button State equal to button state. This will reset the button state and get it ready for the next button push.

Try a Google search. Something like “use button as toggle in Arduino code”.

I would help you further but I'm on my phone right now not at the computer.

I see, nice idea, but I think it is better if you post your complete code (after this post, do not edit your first posted code), and draw a wiring diagram for reference. Thank you.

2 Likes