Trying to make a bluetooth turret with joystick

Hi, I'm trying to make a bluetooth nerf- turret for a school project, and I'm not sure if the code is quite right, any red flags or visible issues?

Code:

#include <Servo.h>
#include <SoftwareSerial.h>

// Servo Variabler
Servo xservo;
Servo yservo;
Servo zservo;

// Pins, hvor de skal koble til arduino
const int XServoPin = 9;
const int YServoPin = 10;
const int ZServoPin = 11;

const int buttonPin = A3;
const int xposPin = A0;
const int yposPin= A1 ;


// Motor (2, motore foran, de som dytter ut dart)
const int motorPin = 12;

// Bluetooth RX og TX pins
const int RxPin = 0;
const int TxPin = 1;

// softwareserial objekt
SoftwareSerial bluetooth(RxPin,TxPin);

// Joystick variabler
int Xpos = 90; // default posisjon for joystick, både x og y (90)
int Ypos = 90; // "-"
int buttonPress = LOW; // Default posisjon for knapp (ikke presset)

// Variabler (recoil)
const byte recoil_rest = 180;
const byte recoil_pushed = 125;
unsigned recoil_start_time = 0;
unsigned recoil_time = 300;

void setup() {
  delay(3000);
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);

  xservo.attach(XServoPin);
  yservo.attach(YServoPin);
  zservo.attach(ZServoPin);

  pinMode(motorPin, OUTPUT);
  digitalWrite(motorPin, HIGH);

  // Start bluetooth
  bluetooth.begin(9600);
}

void loop() {
  if (bluetooth.available() > 0) {
    // les fra bluetooth
    Xpos = bluetooth.parseInt();
    Ypos = bluetooth.parseInt();
    buttonPress = bluetooth.parseInt();

 buttonPress = digitalRead(buttonPin);
  
  if (buttonPress == LOW) { // presses ikke
    // **ingenting skjer**
  } else { // blir presset
    // Slå på servo, dytt dart ut
    zservo.write(recoil_pushed);
    delay(recoil_time); // veeeeent
    zservo.write(recoil_rest); // tilbake til 'rest' posisjon
  }
  Xpos = analogRead(xposPin); //leser av x posisjon 
  Xpos = map(Xpos, 0, 1023, 0, 180); //leser og 'mapper' x verdier til servo sine verdier (0-180(1023))
  Ypos = analogRead(yposPin); //leser av y posisjon
  Ypos = map(Ypos, 0, 1023, 0, 180); //leser of 'mapper' y verdier til servo sine verdier (0-180(1023))
  xservo.write(Xpos); //flytt x servo til der x er på joystick
  yservo.write(Ypos); //flytt y servo til der y er på joystick
  }
}

did you write that?
does it work?

I wrote it, yeah,

not entirely sure if it works yet though.. we have had some issues putting the turret together so I'm just looking for some second opinions on the code for now

what feels weird is that you enter the code in the loop only if you have something to read over your bluetooth serial connection and you try to parse Xpos, yPos and buttonPress started out of the BT connection but right after you replace those values by reading the out of the arduino's pins.

for example, this does not make sense

    buttonPress = bluetooth.parseInt();
    buttonPress = digitalRead(buttonPin);

why would you try to read an int from BT to store that into buttonPress and right after forget about that value and replace it with whatever voltage level (HIGH or LOW) is seen on buttonPin

same goes for

    Xpos = analogRead(xposPin); //leser av x posisjon
    Xpos = map(Xpos, 0, 1023, 0, 180); //leser og 'mapper' x verdier til servo sine verdier (0-180(1023))
    Ypos = analogRead(yposPin); //leser av y posisjon
    Ypos = map(Ypos, 0, 1023, 0, 180); //leser of 'mapper' y verdier til servo sine verdier (0-180(1023))
    xservo.write(Xpos); //flytt x servo til der x er på joystick
    yservo.write(Ypos); //flytt y servo til der y er på joystick

you basically overwrite Xpos and Ypos you acquired from the BT connexion...

➜ post a circuit of what you are trying to build and provide more information

We're basing the project on the turret by littlefrenchkev. https://www.littlefrenchkev.com/bluetooth-nerf-turret

We're trying to incorperate a physical joystick that controls the turret's movement and shooting.

circuit for the turret:


would it be smarter to put the pieces of code you mentioned into a second code thats just for the joystick? would that help avoid the override?

do you want to control by BT or by the physical joystick or both?

well.. both

we have two arduinos, both connected to bluetooth, one being the turret itself, and the other being the joystick. I'm trying to make that work lol

you don't want two arduinos to try to control the servos - only one

But you need to think about what happens if you receive an order from BT and that the position does not match the position of the joystick?

you execute what the BT said and then read again the joystick and execute that too?

➜ clarify your requirements on how this is supposed to work. May be you need a button to say you are in manual mode or BT mode ?

The plan is to have a master/slave connection with two bluetooth components that communicate.
in theory, the first one, that is connected to the joystick will read the information from the joystick and send it to the other bluetooth component, and carry out the action.
that's what we're aiming for at least

ah OK - so you have one remote control unit made with a joystick, an arduino and a BT component and another Arduino inside the turret taking orders from the BT

➜ you need two different programs, one for the turret and one for the remote control

the turret code should not read the joystick, just listen to the BT Serial line
the remote control code should not read the BT Serial line, just read the joystick and button and if something has changed send a message using BT (I would suggest to study Serial Input Basics to handle the Serial communication)

Thank you! I'm gonna try this :slight_smile:

come back with your 2 codes if you need help

I will, thank you!

hi, I'm back (sorry for being a noob)

I'm writing the code for the joystick (the master code), and I've ran into an issue with it that I cant seem to fix. This is my first shot at the code:

#include <Servo.h>
#include <SoftwareSerial.h>

//Pins
const int buttonPin = A3;
const int xposPin = A0;
const int yposPin = A1;

//Pins bluetooth
const int RxPin = 0;
const int TxPin = 1;

//Variabler for joystick
int Xpos = 0; //default posisjon for joystick
int Ypos = 0; 
int buttonPress = LOW; // Default posisjon for knapp (ikke presset)


SoftwareSerial bluetooth(RxPin, TxPin);

void setup() {
  delay(3000);
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH);
  //Start bluetooth
  bluetooth.begin(9600);
  buttonPress = digitalRead(buttonPin);
}

void loop() {
  

  }
  Xpos = analogRead(xposPin); //leser av x posisjon 
  Xpos = map(Xpos, 0, 1023, 0, 180); //leser og 'mapper' x verdier til servo sine verdier (0-180(1023))
  Ypos = analogRead(yposPin); //leser av y posisjon
  Ypos = map(Ypos, 0, 1023, 0, 180); //leser of 'mapper' y verdier til servo sine verdier (0-180(1023))
  xservo.write(Xpos); //flytt x servo til der x er på joystick
  yservo.write(Ypos); //flytt y serco til der y er på joystick
  }

}

I ran into an issue with this part:

  Xpos = analogRead(xposPin); //leser av x posisjon 
  Xpos = map(Xpos, 0, 1023, 0, 180); //leser og 'mapper' x verdier til servo sine verdier (0-180(1023))
  Ypos = analogRead(yposPin); //leser av y posisjon
  Ypos = map(Ypos, 0, 1023, 0, 180); //leser of 'mapper' y verdier til servo sine verdier (0-180(1023))
  xservo.write(Xpos); //flytt x servo til der x er på joystick
  yservo.write(Ypos); //flytt y serco til der y er på joystick

it tells me that Xpos doesnt name a type, any tips? I've had this exact line in every other version of the code, and I've went over it a dozen times, but I cant seem to fix it.

code need to be within the functions - in between the starting { and the closing }

look at your loop() function

void loop() {
  

  }

it's empty and then the code comes after that and you have irrelevant }}

if you press ctrl-T (PC) or cmd-T (Mac) in the IDE it will indent the code and it gets easy to see the blocks that are not where they need to be


the other issue is using 0 and 1 for the BT element. pin 0 and 1 are used by Serial and when you upload. You can still use them (if you unplug the BT module while loading code) but in that case juste use Serial and there is no need to use SoftwareSerial at all.


last but not least, if you write the code for the joystick (the remote control) why do you deal with the Servo there? you should just send the data over BT to the other arduino which is driving the Servos.

so I think something like this would be more appropriate

#include <Servo.h>
#define bluetoothSerial Serial

//Pins
const int buttonPin = A3;
const int xposPin = A0;
const int yposPin = A1;

int xPos = -100, yPos = -100, buttonState = HIGH;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP); // wired as A3 ---- button --- GND
  bluetoothSerial.begin(9600);      //Start bluetooth (module connected on pin 0 and 1)
}

void loop() {
  int x = map(analogRead(xposPin), 0, 1023, 0, 180); //leser og 'mapper' x verdier til servo sine verdier (0-180(1023))
  int y = map(analogRead(yposPin), 0, 1023, 0, 180); //leser of 'mapper' y verdier til servo sine verdier (0-180(1023))
  int b = digitalRead(buttonPin);

  if (x != xPos or y != yPos or b != buttonState) {
    // something has changed, notify the other arduino so that action is taken
    bluetoothSerial.write('<'); // start marker
    bluetoothSerial.print(x);
    bluetoothSerial.write(',');
    bluetoothSerial.print(y);
    bluetoothSerial.write(',');
    bluetoothSerial.write(b == HIGH ? 0 : 1); // because of the pullup, not pressed is HIGH
    bluetoothSerial.write('>'); // end marker

    // remember the current state
    xPos = x;
    yPos = y;
    buttonState = b;
  }
}

it reads the joystick and button and if something has changed since the last message it sends over Serial (which is connected to the BT module) a message in the form <joystick X, joystick Y, joystick Button> for example if you are at 90° and 45° and button is pressed it will send <90,45,1>. if button is not pressed it would send <90,45,0>.


PS : we all started as noob :wink: no need to apologise

Well.. I'm back yet again! wooo!

So.. I'm trying to fix a master/slave connection with the bluetooth modules, and I'm struggling to get the "master" to switch role from slave to master, I've been able to communicate with both the bluetooth modules, but I struggle with this in particular, any tips?

what's your BT module?

the module is HC-05

I've seen lots of people having some trouble with some recent HC-05 which would not work as master, as if they were really HC-06...

you'd need to try sending AT commands

that's what I've been doing :sweat_smile:
still doesnt seem to work though.