Arduino push button problem with sending single value

Viewed 618

I am working on a project currently involving Arduino. I need a button that is sending the value of 1 when pressed, but only one single time. The reason is that I am sending it to Processing and it's currently a problem for my script if it receives the value more than once. This I discovered, after making my buttons into toggle switches. My next attempt was to just print the value of a single button, but it changes between 1 and 0 way too often. I need to remove the noise on the input and send a single value of 1 after the press.

Code for Arduino:

#include "mpr121.h"
#include <Wire.h>
#include <FastLED.h>

#define NUM_LEDS 5 //
#define DATA_PIN 13
CRGB leds[NUM_LEDS];

int capacitivePin = 2; //IRQ
boolean touchStates[12];

const int pingPin = 7; //Ping1
long duration, cm;

//const int pingPin2 = 8; //Ping2
//long duration2, cm2; 

int buttonPin = 3;
int buttonValue;

bool are_sensors_read = false; //mpr toggle
uint16_t  is_touched = 0;
uint16_t was_touched = 0;

void setup(){
  FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
  pinMode(capacitivePin, INPUT);
  digitalWrite(capacitivePin, HIGH); //enable pullup resistor
  pinMode(buttonPin, INPUT);

  Serial.begin(9600);
  Wire.begin();
  mpr121_setup();
}

void loop(){
  readTouchInputs();
  Leds();
  GetPings();
  Buttons();

  Serial.print(cm);
  Serial.print( "," );
  //Serial.print(cm2);
  //Serial.print( "," );
  Serial.print( touchStates[0] );
  Serial.print( "," );
  Serial.print( touchStates[1] );
  Serial.print( "," );                                              //NB!
  Serial.print( touchStates[2] );       //[cm,-cm2-,touch0,touch1,touch2,touch3,touch4,touch5,-touch6-,touch7,-touch8-,touch10,]
  Serial.print( "," );
  Serial.println( buttonValue );
  delay( 100 );
}


// DOWN FROM HERE STARTS CODE FOR CAPACITIVE SENSOR
void readTouchInputs() {
  if (!checkInterrupt()) {

    Wire.requestFrom(0x5A, 2);

    byte LSB = Wire.read();
    byte MSB = Wire.read();

    is_touched = ((MSB << 8) | LSB);
    uint16_t is_toggled = is_touched & ( was_touched ^ 65535 );

    for (int i = 0; i < 12; i++) {
      if ( is_toggled & (1 << i) ) {
        touchStates[i] = !touchStates[i];
        are_sensors_read = true;
      }
    }
    was_touched = is_touched;
  }
}

void mpr121_setup(void){
  set_register(0x5A, ELE_CFG, 0x00); 

  // Section A - Controls filtering when data is > baseline.
  set_register(0x5A, MHD_R, 0x01);
  set_register(0x5A, NHD_R, 0x01);
  set_register(0x5A, NCL_R, 0x00);
  set_register(0x5A, FDL_R, 0x00);

  // Section B - Controls filtering when data is < baseline.
  set_register(0x5A, MHD_F, 0x01);
  set_register(0x5A, NHD_F, 0x01);
  set_register(0x5A, NCL_F, 0xFF);
  set_register(0x5A, FDL_F, 0x02);

  // Section C - Sets touch and release thresholds for each electrode
  set_register(0x5A, ELE0_T, TOU_THRESH);
  set_register(0x5A, ELE0_R, REL_THRESH);

  set_register(0x5A, ELE1_T, TOU_THRESH);
  set_register(0x5A, ELE1_R, REL_THRESH);

  set_register(0x5A, ELE2_T, TOU_THRESH);
  set_register(0x5A, ELE2_R, REL_THRESH);

  set_register(0x5A, ELE3_T, TOU_THRESH);
  set_register(0x5A, ELE3_R, REL_THRESH);

  set_register(0x5A, ELE4_T, TOU_THRESH);
  set_register(0x5A, ELE4_R, REL_THRESH);

  set_register(0x5A, ELE5_T, TOU_THRESH);
  set_register(0x5A, ELE5_R, REL_THRESH);

  set_register(0x5A, ELE6_T, TOU_THRESH);
  set_register(0x5A, ELE6_R, REL_THRESH);

  set_register(0x5A, ELE7_T, TOU_THRESH);
  set_register(0x5A, ELE7_R, REL_THRESH);

  set_register(0x5A, ELE8_T, TOU_THRESH);
  set_register(0x5A, ELE8_R, REL_THRESH);

  set_register(0x5A, ELE9_T, TOU_THRESH);
  set_register(0x5A, ELE9_R, REL_THRESH);

  set_register(0x5A, ELE10_T, TOU_THRESH);
  set_register(0x5A, ELE10_R, REL_THRESH);

  set_register(0x5A, ELE11_T, TOU_THRESH);
  set_register(0x5A, ELE11_R, REL_THRESH);

  // Section D
  // Set the Filter Configuration
  // Set ESI2
  set_register(0x5A, FIL_CFG, 0x04);

  // Section E
  // Electrode Configuration
  // Set ELE_CFG to 0x00 to return to standby mode
  set_register(0x5A, ELE_CFG, 0x0C);  // Enables all 12 Electrodes

  // Section F
  // Enable Auto Config and auto Reconfig
  /*set_register(0x5A, ATO_CFG0, 0x0B);
  set_register(0x5A, ATO_CFGU, 0xC9);  // USL = (Vdd-0.7)/vdd*256 = 0xC9 @3.3V   set_register(0x5A, ATO_CFGL, 0x82);  // LSL = 0.65*USL = 0x82 @3.3V
  set_register(0x5A, ATO_CFGT, 0xB5);*/  // Target = 0.9*USL = 0xB5 @3.3V

  set_register(0x5A, ELE_CFG, 0x0C);
}

boolean checkInterrupt(void){
  return digitalRead(capacitivePin);
}

void set_register(int address, unsigned char r, unsigned char v){
    Wire.beginTransmission(address);
    Wire.write(r);
    Wire.write(v);
    Wire.endTransmission();
}


// DOWN FROM HERE STARTS CODE FOR PING
void GetPings() {
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  cm = microsecondsToCentimeters(duration);


//  pinMode(pingPin2, OUTPUT);
//  digitalWrite(pingPin2, LOW);
//  delayMicroseconds(2);
//  digitalWrite(pingPin2, HIGH);
//  delayMicroseconds(5);
//  digitalWrite(pingPin2, LOW);

//  pinMode(pingPin2, INPUT);
//  duration2 = pulseIn(pingPin2, HIGH);

 // cm2 = microsecondsToCentimeters2(duration2);
}

long microsecondsToCentimeters(long microseconds) {
  return microseconds / 29 / 2;
}

//long microsecondsToCentimeters2(long microseconds2) {
//  return microseconds2 / 29 / 2;
//}

// DOWN FROM HERE STARTS CODE FOR LEDS
void Leds(){
//    if (cm < 50) {
//        leds[0] = CRGB::Blue;
//        FastLED.show(); 
//    }else if (cm > 50){
//        leds[0] = CRGB::Black; 
//        FastLED.show(); 
//    }

    if (touchStates[0] == 1) {
        leds[0] = CRGB::Green; 
        FastLED.show(); 
    }else{
        leds[0] = CRGB::Black; 
        FastLED.show(); 
    }

    if (touchStates[1] == 1) {
        leds[1] = CRGB::Green; 
        FastLED.show(); 
    }else{
        leds[1] = CRGB::Black; 
        FastLED.show(); 
    }

    if (touchStates[2] == 1) {
        leds[2] = CRGB::Green; 
        FastLED.show(); 
    }else{
        leds[2] = CRGB::Black; 
        FastLED.show(); 
    }

    if (touchStates[3] == 1) {
        leds[3] = CRGB::Green; 
        FastLED.show(); 
    }else{
        leds[3] = CRGB::Black; 
        FastLED.show(); 
    }

    if (touchStates[4] == 1) {
        leds[4] = CRGB::Green; 
        FastLED.show(); 
    }else{
        leds[4] = CRGB::Black; 
        FastLED.show(); 
    }
}

// DOWN FROM HERE STARTS CODE FOR BUTTONS
void Buttons(){
  buttonValue = digitalRead(buttonPin);

}

Code for Processing:

//---libs
import processing.serial.*;
import ddf.minim.*;

//---init1
int[] data = new int[12]; //arr send via serial from uno
String val; //storing arr

boolean isPlaying;
boolean buttonport5; //if choice buttons are active
boolean buttonport7;
boolean buttonport10;

//---init2
Serial myPort;
Minim minim;
AudioPlayer drums;
AudioPlayer guitar;
AudioPlayer lead;
AudioPlayer vocals;

//---begin
void setup() { 
  size(200,200);
  myPort = new Serial(this, "COM3", 9600);

  minim = new Minim(this);
  //startingSong();

  drums = minim.loadFile("ds_sos_drums.mp3", 2048);
  guitar = minim.loadFile("ds_sos_guitar.mp3", 2048);
  lead = minim.loadFile("ds_sos_lead.mp3", 2048);
  vocals = minim.loadFile("ds_sos_vocals.mp3", 2048);
}

//---loop
void draw() {
    if (myPort.available() > 0) {
        val = myPort.readStringUntil(10);

        if (val != null) {
            val = trim(val);
            int[] data = int(split(val, ','));
            //println(data);
            checkSensors(data);

          }  
      } 

}

//--songs
void startingSong() {
    drums = minim.loadFile("ds_sos_drums.mp3", 2048);
    guitar = minim.loadFile("ds_sos_guitar.mp3", 2048);
    lead = minim.loadFile("ds_sos_lead.mp3", 2048);
    vocals = minim.loadFile("ds_sos_vocals.mp3", 2048);
}

void songOne() {
    drums.pause();
    guitar.pause();
    lead.pause();
    vocals.pause();
    drums = minim.loadFile("dm_es_drums.mp3", 2048);
    guitar = minim.loadFile("dm_es_guitar.mp3", 2048);
    lead = minim.loadFile("dm_es_bass.mp3", 2048);
    vocals = minim.loadFile("dm_es_vocals.mp3", 2048);
    //print("now playing: depeche mode");
}

void songTwo() {
    drums.pause();
    guitar.pause();
    lead.pause();
    vocals.pause();
    drums = minim.loadFile("synnys_005_drums.mp3", 2048);
    guitar = minim.loadFile("synnys_005_stabs.mp3", 2048);
    lead = minim.loadFile("synnys_005_synth1.mp3", 2048);
    vocals = minim.loadFile("synnys_005_synth2.mp3", 2048);
    //print("now playing: synnys");
}

void songThree() {
    drums.pause();
    guitar.pause();
    lead.pause();
    vocals.pause();
    drums = minim.loadFile("dm_es_drums.mp3", 2048);
    guitar = minim.loadFile("dm_es_guitar.mp3", 2048);
    lead = minim.loadFile("dm_es_bass.mp3", 2048);
    vocals = minim.loadFile("dm_es_vocals.mp3", 2048);
    print("now playing: depeche mode");
}

//---actions
void checkSensors (int []data) {
    int ultrasonic = data[0];
    //int ultrasonic2 = data[1];
    int port0 = data[1];
    int port1 = data[2];
    int port2 = data[3];
    int port3 = data[4];
    int port4 = data[5];
    int port5 = data[6];
    //int port6 = data[];
    int port7 = data[7];
    //int port8 = data[];
    int port10 = data[8];

    println("ultrasonic: " + data[0]);
    //println("ultrasonic2: " + data[1]);
    println("port 0: " + data[1]);
    println("port 1: " + data[2]);
    println("port 2: " + data[3]);
    println("port 3: " + data[4]);
    println("port 4: " + data[5]);
    println("port 5: " + data[6]);
    //println("port 6: " + data[]);
    println("port 7: " + data[7]);
    //println("port 8: " + data[]);
    println("port 10: " + data[8]);
    print(isPlaying);

    chooseSong(port5, port7, port10);
    doActions(ultrasonic, port0, port1, port2);
}

void chooseSong (int port5, int port7, int port10) {
    if (port5 == 1 && buttonport7 == false && buttonport10 == false ) {
        isPlaying = false;
        songOne();
        buttonport5 = true;
    } else if (port7 == 1 && buttonport5 == false && buttonport10 == false) {
        isPlaying = false;
        songTwo();
        buttonport7 = true;
    } else if (port10 == 1 && buttonport5 == false && buttonport7 == false) {
        isPlaying = false;
        songThree();
        buttonport10 =true;
    } else {
        //startingSong();
        buttonport5 = false;
        buttonport7 = false;
        buttonport10 = false;
    }

    if (port5 == 1){
      if (buttonport7 == false && buttonport10 == false ){
        isPlaying = false;
        songOne();
        buttonport5 = true;
        buttonport7 = false;
        buttonport10 = false;
      }
    } else  {
        buttonport5 = false;
    }

    if (port7 == 1){
      if (buttonport5 == false && buttonport10 == false ){
        isPlaying = false;
        songTwo();
        buttonport7 = true;
        buttonport5 = false;
        buttonport10 = false;
      }
    } else {
        buttonport7 = false;
    }

    if (port10 == 1){
      if (buttonport5 == false && buttonport7 == false ){
        isPlaying = false;
        songThree();
        buttonport10 = true;
        buttonport5 = false;
        buttonport7 = false;
      }
    } else {
        buttonport10 = false;
    }


} 

void doActions (int ultrasonic, int port0, int port1, int port2) {
    if ((ultrasonic < 50)) {   // || (ultrasonic < 20) , || (isPlaying= false)
      if(isPlaying == false){
        isPlaying = true;
        drums.play();
        guitar.play();
        lead.play();
        vocals.play();

      }
    } else if (ultrasonic > 50) {   
        isPlaying = false;
        drums.rewind();
        guitar.rewind();
        lead.rewind();
        vocals.rewind();
    }       


    if (port0 == 1) {
        guitar.setGain(75);
    } else if (port0 == 0) {
        guitar.setGain(-50);
    }

    if (port1 == 1) {
        lead.setGain(75);
    } else if (port1 == 0) {
        lead.setGain(-50);
    }

    if (port2 == 1) {
        vocals.setGain(75);
    } else if (port2 == 0) {
        vocals.setGain(-50);
    }

}

Edit: Sorry for not posting the code the first time, it is my first time posting here and I am still trying to get used to.

PS: I started learning to program recently, so I hope this might excuse to a degree possible stupid mistakes or missing stuff. I hope everything makes sense.

1 Answers

As for the button changing from 0 to 1 too often, that is switch bounce. Google that. There are innumerable articles on something called "debounce" that will solve that issue.

As for sending the signal only once per press of the button, study the "State Change Example" that comes with the IDE. Basically you need to have a variable to store the last state of the button so you can compare when you next read and see if it has changed. That way you can act only if it does change. Look at the state change example and if you don't follow then google that as well. There are TONS of examples on how to do it.

Related