Using Arduino buttons to do something in processing. Best method?

edited September 2014 in Arduino

I'm working on a project that is quite simple, but very confusing for a beginner like myself...

In summary, this is the goal: - I push a button (BTN01) on Arduino, my computer plays Sound01A - I flick a swicth (BTN02) on Arduino, it plays Sound02A or Sound02B (depending on it's state) - There will be many, many buttons...

I have a few questions:

1) Is the best method of wiring each button (with two pins) GND and corresponding Digital Input Pin? Do I need a pullup resistor? (I'm testing on Uno but finalising on Mega) ** 2)** Should use "serial.print" or "serial write" in the Arduino code?

3) How should I best label each button state in Arduino that is sent via serial? I was thinking 01a, 01b, 02a, 02b, etc (number is the button/pin, letter is the state eg pushed or not)

4) Should I use some kind of array to m ake the code easier to create and work with? Or should I just have lots of separate if statements (one for each button)?

5) What would be the recommended/ simplest method of receiving the serial inputs in processing?

Answers

  • Hello. I may have little experience but I can tell you this. Before you do ANYTHING, know how it will affect your code. Ask yourself: what is serial.print? How will it affect my code? What will it do? Ask the same about serial.write. That what you will know if it interferes with anything else in your code and such. Usually when I label things, I make sure that I will recognize it even if I hadn't look at the code for years. Preferably I would label the buttons the name of the sound so when you add the sounds it will be easier to know where to put it. Again these are just suggestions.

    Good luck

    Techwiz777

  • edited September 2014

    Not a super expert, but I'll give you some hints.

    1. Read about Pushbutton and for example this article on serial connection with Processing.

    2. If you're OK with your labelling, you may use that.

    3. Instead of if statements it may be easier to use switch.

    4. You gonna need to import serial library into processing sketch. The article I suggested in 1 should make it clear.

  • Thanks Ater, I'm using labels (Serial.print) such as "3High", "3Low", "4High", etc from the Arduino, all separated with \n. Basically to say which button is pushed and what state it's in.

    This is where I'm at at the moment but can't get it to work:

    import processing.serial.*;
    
    Serial myPort;  // Create object from Serial class
    String val;     // Data received from the serial port
    
    void setup() 
    {
        size(600, 600);
    // Open whatever port is the one you're using.
    String portName = Serial.list()[1]; //change the 0 to a 1 or 2 etc. to match your port
    myPort = new Serial(this, portName, 9600); 
    }
    
    void draw()
    {
      if ( myPort.available() > 0) 
      {  // If data is available,
      val = myPort.readStringUntil('\n');         // read it and store it in val
      } 
    println(val); //print it out in the console
    
      //DRAW RECTANGLE (that changes on different switch states)
      background(127,0,0);
    
      if (val == "3High"){
        fill(255,200,200);
        ellipse(60,20,100,100);
      }
      if (val == "3Low"){
        fill(200);
        ellipse(250, 250, 100, 100);    
      }
    
    
    }
    

    P.S - Switches look great but only seem to be for numbers, not labels like mine. I'd use numbers but my project has a lot of buttons and would be too confusing otherwise.

  • edited September 2014

    Your if expressions @ lines #25 & #29 will never work. They'll result false every time! :-&
    The reason why is b/c variable val and those literals "3High" & "3Low" are all different String objects!

    In order to check their contents, rather than their object references, we gotta use String's equals() method:
    http://processing.org/reference/String_equals_.html

  • that would make sense, but I can get it to work:

      if (val.equals("3High") == true){
        fill(255,200,200);
        ellipse(60,20,100,100);
      }
    
  • edited September 2014

    No need to check against true. It can be safely omitted. Method equals() returns a boolean already! : ;;)

    http://processing.org/reference/boolean.html

    if ("3High".equals(val)) {
      fill(255,200,200);
      ellipse(60,20,100,100);
    }
    
  • edited September 2014

    If it's still failing, perhaps there might be some undesirable chars from the returning readStringUntil() String.
    Method trim() can deal w/ some of those pesky invisible extra characters. Give it a try: =:)

    http://processing.org/reference/trim_.html

    String val = trim( myPort.readStringUntil(ENTER) );
    
  • I'm almost there, after a lot of tinkering it works for a few seconds. Seems to be the trim() that has results.

    The error I get now is "Null Pointer Exception" on the line "val = trim(myPort.readStringUntil(ENTER));"

    Here's my complete code, hopefully you can spot something :)

    import processing.serial.*;
    
    Serial myPort;  // Create object from Serial class
    String val;     // Data received from the serial port
    
    
    
    void setup() 
    {
      size(600, 600);
    
      // Open the port (usually change to [0] or [1]
      String portName = Serial.list()[1];
      myPort = new Serial(this, portName, 9600);
    
    }
    
    void draw()
    {
      if (myPort.available() > 0) {
        val = trim(myPort.readStringUntil(ENTER));
        if (val != null) {
          println(val);
        }
      }
    
      if ("3High".equals(val)) {
        fill(255,200,200);
        ellipse(160,120,100,100);
      }
      if ("3Low".equals(val)) {
        fill(155,100,100);
        ellipse(60,20,100,100);
      }
    
    }
    
  • edited September 2014

    Forgot that readStringUntil() can fail and return null. Therefore, we gotta test for it before trim():

    if ( (val = myPort.readStringUntil(ENTER)) == null )  return;
    else  val = trim(val);
    
  • PERFECT!!! Many thanks to you GoToLoop :)

    Here's my working code:

    import processing.serial.*;
    
    Serial myPort;  // Create object from Serial class
    String val;     // Data received from the serial port
    
    
    
    void setup() 
    {
      size(600, 600);
    
      // Open the port (usually change to [0] or [1]
      String portName = Serial.list()[1];
      myPort = new Serial(this, portName, 9600);
    
    }
    
    void draw()
    {
      if (myPort.available() > 0) {
        if ( (val = myPort.readStringUntil(ENTER)) != null )  val = trim(val);
        else return;
        if (val != null) {
          println(val);
        }
      }
    
      // MAKE SHAPE THAT CHANGES ON BUTTON PRESS
      ellipse(60,20,100,100);
    
      if ("3High".equals(val)) {
        fill(255,200,200);
      }
      if ("3Low".equals(val)) {
        fill(155,100,200);
      }
    
    }
    
  • Errrrrhem. You are welcome.

  • Apologies, I got a little overexcited. Thanks to everyone :p

  • Thank you! :)

  • Hi, I know this is really old, but I am working on a similar project and am having trouble on the arduino side of things. Is there any way you could share the arduino code used in this project?

    Thanks

Sign In or Register to comment.