Проблема с кнопкой Arduino при отправке одного значения - PullRequest
2 голосов
/ 02 июля 2019

Я работаю над проектом, в котором сейчас участвует Arduino.Мне нужна кнопка, которая отправляет значение 1 при нажатии, но только один раз.Причина в том, что я отправляю его в Processing, и в настоящее время это проблема для моего скрипта, если он получает значение более одного раза.Это я обнаружил после превращения моих кнопок в тумблеры.Моя следующая попытка состояла в том, чтобы просто напечатать значение одной кнопки, но оно слишком часто меняется от 1 до 0.Мне нужно убрать шум на входе и послать одно значение 1 после нажатия.

Код для 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);

}

Код для обработки:

//---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);
    }

}

Редактировать: Извините, что не опубликовал код в первый раз, это мой первый пост здесь, и я все еще пытаюсь привыкнуть.

PS: я недавно начал учиться программировать, поэтому я надеюсь, что это может оправдать в какой-то степени возможные глупые ошибки или пропущенные вещи.Я надеюсь, что все имеет смысл.

1 Ответ

3 голосов
/ 02 июля 2019

Что касается кнопки, изменяющейся от 0 до 1 слишком часто, то есть отказов переключателя. Google это. Есть бесчисленное множество статей на тему «debounce», которые решат эту проблему.

Что касается отправки сигнала только один раз за нажатие кнопки, изучите «Пример изменения состояния», который поставляется с IDE. По сути, вам нужна переменная для хранения последнего состояния кнопки, чтобы вы могли сравнить ее при следующем чтении и посмотреть, изменилась ли она. Таким образом, вы можете действовать, только если он действительно изменится. Посмотрите на пример изменения состояния, и если вы не будете следовать, то и Google тоже. Есть множество примеров того, как это сделать.

...