Bluetooth wireless joystick mouse between two Arduinos

Hello guys,
I'm new at programming Arduino. Stuck with the following coding which has a joystick on a Arduino Nano (Master) connected via Bluetooth to a Arduino Micro (Slave) to act as mouse emulation. I was able to make it work wired but in this wireless setup the code has a problem. Any help will be appreciated. Thanks :slight_smile:

MASTER


#include <SoftwareSerial.h>
int horzPin = A1;
int vertPin = A0;
int selPin = 9;
int vertZero, horzZero;
int vertValue, horzValue;
const int sensitivity = 200;
int mouseClickFlag = 0;

#define tx 1
#define rx 0

void setup()
{
Serial.begin(9600);
pinMode(horzPin, INPUT);
pinMode(vertPin, INPUT);
pinMode(selPin, INPUT);
digitalWrite(selPin, HIGH);
delay(1000);
vertZero = analogRead(vertPin);
horzZero = analogRead(horzPin);

pinMode(tx, OUTPUT);
pinMode(rx, INPUT);

}

void loop()
{
vertValue = analogRead(vertPin) - vertZero;
horzValue = analogRead(horzPin) - horzZero;

Serial.write(vertValue);
Serial.write(horzValue);
Serial.write(selPin);
}

SLAVE


#include <SoftwareSerial.h>
#include <Mouse.h>
int vertZero, horzZero;
int vertValue, horzValue;
const int sensitivity = 200;
int mouseClickFlag = 0;
int selPin = 9;
#define tx 0
#define rx 1

void setup()
{
Serial.begin(9600);
digitalWrite(selPin, HIGH);
pinMode(tx, OUTPUT);
pinMode(rx, INPUT);
delay(1000);
}

void loop()
{
{
if(Serial.available())

Mouse.begin();
if (vertValue != 0)
Mouse.move(0, vertValue/sensitivity, 0);
if (horzValue != 0)
Mouse.move((horzValue/sensitivity)*-1, 0, 0);

if ((selPin == 0) && (!mouseClickFlag))
{
mouseClickFlag = 1;
Mouse.press(MOUSE_LEFT);
}
else if ((digitalRead(selPin))&&(mouseClickFlag))
{
mouseClickFlag = 0;
Mouse.release(MOUSE_LEFT);
}}
Mouse.end();
}

Please follow the advice on posting code given in posting code

In particular note the advice to Auto format code in the IDE and to use code tags when posting code here as it prevents some combinations of characters in code being interpreted as HTML commands such as italics, bold or a smiley character, all of which render the code useless

Hello Jack and welcome to the forum,

you should re-edit your post to insert your code as a code-section
You should post code by using code-tags

There is an automatic function for doing this inthe Arduino-IDE
just three steps

  1. press Ctrl-T for autoformatting your code
  2. do a rightclick with the mouse and choose "copy to forum"
  3. paste clipboard into write-window of a posting

IO-pin 0 and 1 are used by the UBS-to-serial-connection. If you connect a second device to IO-pin s0,1 the two devices disturb each other.

Your code does not include any initialisation of the software-serial.
I recommend that you do some pre-tests by wiring up the two arduinos by wiring
Tx-to-Rx and Rx-to-Tx on different IO-pins than 0,1
then use a simple testprogram that is proven to work to test the wiring between the two arduinos
communictating over softwareserial.

Then add the bluetooth moduls and test again.

The microcontroller-world is not superstandardised like USB-devices. You have to take care of more details than just

"does the plug fit into the socket?"

You have to

  • analyse datasheets and
  • check if voltages are compatible

gain some basic knowledge about electronics and having a digital multimeter will be very useful

best regards Stefan

The Micro has a spare HardwareSerial port (Serial1) on pins 0 and 1 and it would be much better to use that rather than SoftwareSerial.

This code (on the slave)

 if(Serial.available())

Mouse.begin();         
  if (vertValue != 0)

makes not attempt to read any value from Serial nor to place that value in the variable vertValue.

Have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.

You can send data in a compatible format with code like this (or the equivalent in any other programming language)

Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker

The examples can easily be adapted to use SoftwareSerial or Serial1 as needed.

...R

here is a picture that shows how to re-edit posts:

best regards Stefan

Here are the Master and Slave configuration in the attachment. Arduino Nano with HC-05 Bluetooth as master sending joystick data to an Arduino Micro via HC-05 Bluetooth. The slave Arduino Micro is connected to the PC via USB and will act as mouse emulator.
The Master code:

int horzPin = A1;
int vertPin = A0;
int selPin = 9;
int vertZero, horzZero;
int vertValue, horzValue;
const int sensitivity = 200;
int mouseClickFlag = 0;

#define tx 1
#define rx 0

void setup()
{
  Serial.begin(9600);
  pinMode(horzPin, INPUT);
  pinMode(vertPin, INPUT);
  pinMode(selPin, INPUT);
  digitalWrite(selPin, HIGH);
  delay(1000);
  vertZero = analogRead(vertPin);
  horzZero = analogRead(horzPin);
  pinMode(tx, OUTPUT);
  pinMode(rx, INPUT);
}

void loop()
{
  vertValue = analogRead(vertPin) - vertZero;
  horzValue = analogRead(horzPin) - horzZero;

  Serial.print('<');
  Serial.print(vertValue);
  Serial.print(',');
  Serial.print(horzValue);
  Serial.println('>');
}

The Slave code:

#include <Mouse.h>
const int sensitivity = 200;

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];

int vertValue = 0;
int horzValue = 0;

boolean newData = false;

//============

void setup() {
  Serial.begin(9600);
  delay(1000);
}

//============

void loop() {
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
    // this temporary copy is necessary to protect the original data
    //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    moveMouse();
    newData = false;
  }
}

//============

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

//============

void parseData() {      // split the data into its parts

  char * strtokIndx; // this is used by strtok() as an index

  strtokIndx = strtok(tempChars, ",");     // get the first part - the string
  vertValue = atoi(strtokIndx);     // convert this part to an integer

  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  horzValue = atoi(strtokIndx);     // convert this part to an integer
}

//============

void moveMouse() {
  Mouse.begin();
  if (vertValue != 0)
    Mouse.move(0, vertValue / sensitivity, 0);
  if (horzValue != 0)
    Mouse.move((horzValue / sensitivity) * -1, 0, 0);
  Mouse.end();
}

I am not using the joystick's click option. I removed it from the code to simplify it and focus only on the movement on X and Y axis for the moment. It still doesn't work and I have no idea what I'm doing wrong.

Have you established that the HC-05's are Pairing and Connecting ?

runaway_pancake:
Have you established that the HC-05's are Pairing and Connecting ?

Yes. I even used them in another test project where I used a switch with the master to turn on a LED at the slave part. I am sure the problem is with the code because I am new at coding. Most probably the problem is how I am sending the data because the slave isn't able to parse it right.

Another useful test is to remove the HC05s and make the connection between the Arduinos using wires - being careful to connect Tx to Rx and Rx to Tx and also to include a GND connection between the Arduinos.

jackjacob:
Most probably the problem is how I am sending the data because the slave isn't able to parse it right.

I think you are sending the data much to often. You are sending it in every iteration of loop() and the Serial system cannot keep up with that.

As a test add delay(1000); as the last thing in loop() in your TX program and see what happens.

...R

Nothing is working. There's a small mistake I'm doing and till now have no clue what it is. I better pay someone to do it for me.

jackjacob:
Nothing is working. There's a small mistake I'm doing and till now have no clue what it is. I better pay someone to do it for me.

by the way: that is the method any professional will use.
*best regards Stefan *

Who's in?

jackjacob:
Who's in?

be more specific than just "Who's in?"
Posting such short postings will just start to erode your potential helpers patience to help.
best regards Stefan

From the slave point of view, your original code is sending 6 random bytes, with nothing to sync them up.
At least add a start byte, like 0xAA, or as discussed.

Have the slave wait until it sees 0xAA, then do other processing (or just sit & wait) until Serial.available() is >=5, then read the 6 bytes of vert position, hor position, and selPin (why is that an int?) process them, then go back to waiting for 0xAA and 6 more bytes. At 9600, there is a lot of processing time available.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.