[Solved] Attack3 Joystick buttons to turn on LEDs on Arduino?

Hello, community

I’m new to Processing and coding in general so please bear with me.
I am trying to control 2 servos and a bunch of LEDs attached to an Arduino Nano clone using Logitech Attack3 Joystick and Processing with the GameControlPlus library.

I figured out how to control the Servos as shown in the code below, but I have no idea how can I make pressing a button on the joystick control an LED, I need a sample code to do that so I can build on it.

Question 2 :
When using Processing with Arduino, do I create the entire code in Processing? I mean what will be the Arduino and Arduino IDE job afterward other than uploading the Firmatta code to it and attaching the devices to be controlled to it?

The Processing code:

import processing.serial.*;

import net.java.games.input.*;
import org.gamecontrolplus.*;
import org.gamecontrolplus.gui.*;

import cc.arduino.*;
import org.firmata.*;

ControlDevice cont;
ControlIO control;
Arduino arduino;

float joystickX;
float joystickY;
boolean but1;

int servoXPin=3;  // Where servoX is connected to arduino
int servoYPin=5;  // Where servoY is connected to arduino

void setup() {

  size(360, 200);
  control = ControlIO.getInstance(this);
  cont = control.getMatchedDevice("attack3");

  if (cont == null) {
    println("Controller not connected! Please check it out.");
    System.exit(-1);
  } //End of "if" code

  println(Arduino.list());  //Reads the connected USB devices 

  arduino = new Arduino(this, Arduino.list()[2], 57600);
  arduino.pinMode(servoXPin, Arduino.SERVO);
  arduino.pinMode(servoYPin, Arduino.SERVO);
  arduino.pinMode(13, Arduino.OUTPUT);
} //End of void setup loop

public void getUserInput() {

  joystickX = map(cont.getSlider("servoX").getValue(), -1, 1, 0, 180);
  joystickY = map(cont.getSlider("servoY").getValue(), -1, 1, 0, 180);
  but1 = cont.getButton("bn1").pressed();  // NOT SURE IF THIS PART IS CORRECT!!!!

  /*joystick = map(cont.getSlider("bn2").getValue(), 0, 1, 0, 1);
   joystick = map(cont.getSlider("bn3").getValue(), 0, 1, 0, 1);
   joystick = map(cont.getSlider("bn4").getValue(), 0, 1, 0, 1);
   joystick = map(cont.getSlider("bn5").getValue(), 0, 1, 0, 1);
   joystick = map(cont.getSlider("bn6").getValue(), 0, 1, 0, 1);
   joystick = map(cont.getSlider("bn7").getValue(), 0, 1, 0, 1);
   joystick = map(cont.getSlider("bn8").getValue(), 0, 1, 0, 1);
   joystick = map(cont.getSlider("bn9").getValue(), 0, 1, 0, 1);
   joystick = map(cont.getSlider("bn9").getValue(), 0, 1, 0, 1);
   joystick = map(cont.getSlider("bn10").getValue(), 0, 1, 0, 1);
   joystick = map(cont.getSlider("bn11").getValue(), 0, 1, 0, 1);
   */

  print(but1);
  print (", ");
  print(joystickX);
  print (", ");
  println (joystickY);
  delay (100);
} // End of public void loop

void draw() {

  getUserInput();
  background(joystickX, 100, 255);
  background(joystickY, 50, 180);

  arduino.servoWrite(servoXPin, (int)joystickX);
  arduino.servoWrite(servoYPin, (int)joystickY);

  if (but1 == true) {
    arduino.digitalWrite(13, 1); // NOT SURE OF THIS WOULD WORK TO TURN ON ARDUINO LED 13
  }
}
1 Like

Split this into two problems

  1. Read a joystick button press and store the result in some variable
  2. Read the variable and send a message to the Arduino

I can’t help with the second part but there are examples that come with the GCP library and a number of videos on my website about using this library.

1 Like

A button has two states either HIGH or LOW (Or maybe true & false ?)
first I need to define a variable then how do I store the button state in the variable, I mean what is the code structure to do that?

Please bear with me here

Many thanks…

Obviously you would need a boolean variable to store the state.

In Processing select File | Examples in the menu and in the window that opens locate the GCP library and open the joystick example.

1 Like

Thank you @quark, some progress here,

I edited this part of code


public void getUserInput() {

  joystickX = map(cont.getSlider("servoX").getValue(), 1, -1, 0, 150);
  joystickY = map(cont.getSlider("servoY").getValue(), -1, 1, 12, 180);
  but1 = cont.getButton("bn1").pressed();
  
  if (but1 == true) {
   
    arduino.digitalWrite(ledPin, Arduino.HIGH);
    println("button1 is pressed");
    
  }

When pressing the button, the serial monitor prints the message “button1 is pressed” meaning that the “if” part of code is working and I am entering it, but the led pin is never high meaning the code arduino.digitalWrite(ledPin, Arduino.HIGH); is not working somehow!
just to be clear I didn’t edit anything in the Firmata sketch uploaded to Arduino!

As I said, I can’t help with the Arduino side as I have no experience using it. Sorry.

Hi @Code7,

You want to make your Processing sketch send and receive via Arduino to the Arduino I.O. There are 2 ways (at least).

  1. Fermata. Put the firmata code in the Arduino, use the Processing examples that work with firmata.

  2. Put your own code in the Arduino. Your own code in Ard and Processing has to put messages together and receive them.

If ‘new to coding’ probably quicker to get going with firmata. I’ve always preferred the 2nd method as my projects usually start with the Arduino doing something, then want comms to PC as optional GUI or data logging.

1 Like

I have figured out the reason why it wasn’t working, It was some wiring mistakes!

Now the code I’m using to fully controlling my Logitech Attack 3 joystick is as follows


import processing.serial.*;

import net.java.games.input.*;
import org.gamecontrolplus.*;
import org.gamecontrolplus.gui.*;

import cc.arduino.*;
import org.firmata.*;

ControlDevice cont;  //Sets the Devices Name that will be used to control the Arduino e.g. Joystick 
ControlIO control;
Arduino arduino;

float joystickX;
float joystickY;
float joystickZ;

boolean but1;
boolean but2;
boolean but3;
boolean but4;
boolean but5;
boolean but6;
boolean but7;
boolean but8;
boolean but9;
boolean but10;
boolean but11;

int servoXPin=3;  // Where servoX is connected to arduino
int servoYPin=5;  // Where servoY is connected to arduino
int servoZpin=12;  //
int led1Pin=6;
int led2Pin=7;
int led3Pin=8;
int led4Pin=9;

void setup() {

  size(360, 200);
  control = ControlIO.getInstance(this);
  cont = control.getMatchedDevice("attack3");  // between "" there is the name givin to the joystick or the controller used

  if (cont == null) {  // if the device "joystick or Gamepad etc .. " is not connected to USB then sow the following msg
    println("Controller not connected! Please check it out.");
    System.exit(-1);
  } //End of "if" code

  println(Arduino.list());  //Reads the connected USB devices and prints it to the Serial Monitor

  arduino = new Arduino(this, Arduino.list()[2], 57600); // change the number between [] to the device port's number
  arduino.pinMode(servoXPin, Arduino.SERVO);
  arduino.pinMode(servoYPin, Arduino.SERVO);
  arduino.pinMode(led1Pin, Arduino.OUTPUT);
  arduino.pinMode(led2Pin, Arduino.OUTPUT);
  arduino.pinMode(led3Pin, Arduino.OUTPUT);
  arduino.pinMode(led4Pin, Arduino.OUTPUT);
  
  
} //End of void setup loop

public void getUserInput() {

  joystickX = map(cont.getSlider("servoX").getValue(), 1, -1, 0, 150);     // joystick configuration
  joystickY = map(cont.getSlider("servoY").getValue(), -1, 1, 12, 180);    // joystick configuration
  but1 = cont.getButton("bn1").pressed();
  but2 = cont.getButton("bn2").pressed();
  but3 = cont.getButton("bn3").pressed();
  but4 = cont.getButton("bn4").pressed();
  but5 = cont.getButton("bn5").pressed();
  but6 = cont.getButton("bn6").pressed();
  but7 = cont.getButton("bn7").pressed();
  but8 = cont.getButton("bn8").pressed();
  but9 = cont.getButton("bn9").pressed();
  but10 = cont.getButton("bn10").pressed();
  but11 = cont.getButton("bn11").pressed();
  
  
 
  
   


  print(but1);
  print (", ");
  print(joystickX);
  print (", ");
  println (joystickY);
} // End of public void loop

void draw() {

  getUserInput();
  background(joystickX, 100, 255);
  background(joystickY, 5, 68);

  arduino.servoWrite(servoXPin, (int)joystickX);
  arduino.servoWrite(servoYPin, (int)joystickY);

  if (but1 == true) {
    arduino.digitalWrite(led1Pin, Arduino.HIGH);
  } // End if 1
  
  if (but2 == true) {
    arduino.digitalWrite(led1Pin, Arduino.LOW);
    arduino.digitalWrite(led2Pin, Arduino.LOW);
    arduino.digitalWrite(led3Pin, Arduino.LOW);
    arduino.digitalWrite(led4Pin, Arduino.LOW);
  } // End if 2
  
  if (but3 == true) {
    arduino.servoWrite(servoXPin, 10);
    delay (500);
    arduino.servoWrite(servoXPin, 140);
    delay (500);
  } // End if 3
  
  if (but4 == true) {
    arduino.servoWrite(servoXPin, 150);
  } // End if 4
  
  if (but5 == true) {
    arduino.servoWrite(servoXPin, 1);
  } // End if 5
  
  
  if (but6 == true) {
    arduino.digitalWrite(led2Pin, Arduino.HIGH);
  } // End if 6
  
  if (but7 == true) {
    arduino.digitalWrite(led3Pin, Arduino.HIGH);
  } // End if 7
  
  if (but8 == true) {
    arduino.digitalWrite(led4Pin, Arduino.HIGH);
  } // End if 8
  
  
  
} 

For now, everything is going well so far.

1 Like

Working, good. I don’t know what performance you expect, but the delays on the but3 action mean that for 1 second it’s not responding to the joystick. Maybe that doesn’t matter but I would set the frameRate to something achievable, e.g. 20, and use a counter to trigger the second servoWrite.

You don’t need all the ‘== true’. ‘if (but6)’ is fine, or ‘if (!but6)’ for testing for false.

Thank you Richard,
As is I said before, I’m new and still learning to code so please bear with me, for this part:

I couldn’t understand, how to achieve such a thing? I mean could you please give me a code example to do it in a better and more proper manner?

please note that If I decrease the delay the servo either won’t fully turn left and right or It will jerk in its place without even turning!

See frameRate and frameRate() in the help. Let’s find out how often your draw is running. Try this just before end of draw function

if (frameCount % 120 == 0){print frameRate(); print " ");}

At the moment your sketch is repeatedly reading the joystick and transmitting to Ard 60 times/sec if it can keep up with that. I would put frameRate(20); just after the size statement. Then we know draw is running every 50 mS and we can use counters to control when things happen.

At the start of draw you are sending joystick x and y to Ard. If but3,4,5 are pressed you send different x values just after. I think that’s the reason for the mis-behaviour and the delays stop some of it. What do you want the x servo to do? Something like 'follow the x joystick except if but3 is pressed go to min then max, and if but4 is pressed go to max, but3 to min? After those specific movements go back to following the joystick after a set time? Does the servo have position signals back to the Ard? (We could put something on screen that shows where you want the servo, and where it is.)

1 Like