-1

I am working to create a joystick controlled platform using bluetooth to communicate, but am having several problems. The platform https://www.dfrobot.com/wiki/index.php/Cherokey_4WD_Mobile_Platform_(SKU:ROB0102) needs RX and TX to run, but so does the HC-05 module. I am attempting to use a software serial communication line, but it doesn't seem to read and won't connect between a master and slave device. Also, the joystick is connected to an arduino with the master HC-05, but won't read input correctly if the HC-05 is connected (using software serial). Below is my code, any suggestions would be appreciated.

Master:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

int xPin = A1;
int yPin = A0;
int buttonPin = 8;
int state = 0;

int xPosition = 0;
int yPosition = 0;
int buttonState = 0;

void setup() {
//-----------Initial standard setup----------------
  // initialize serial communications at 38400 bps:
  Serial.begin(9600); 

  pinMode(xPin, INPUT); //Pin A1
  pinMode(yPin, INPUT); //Pin A0

  //activate pull-up resistor on the push-button pin
  pinMode(buttonPin, INPUT_PULLUP); 


//------------software serial setup------------------
  while (!Serial) 
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  // set the data rate for the SoftwareSerial port
  mySerial.begin(38400);

}

void loop() 
{
//------------------Reading Joystick----------------------
  int xplus=0, yplus=0, append=0;
  xPosition = analogRead(xPin);
  yPosition = analogRead(yPin);
  buttonState = digitalRead(buttonPin);

  /*Serial.print("X: ");
  Serial.print(xPosition);
  Serial.print(" | Y: ");
  Serial.print(yPosition);
  Serial.print(" | Button: ");
  Serial.println(buttonState);*/
//----------------Packaging data----------------------------
  if(xPosition < 1000) //ensures 4 digits long
  {
    xplus = xPosition + 2000; //2000 will be canceled on slave side
  }else
xplus = xPosition;

  if(yPosition < 1000) //ensures 4 digits long
  {
    yplus = yPosition + 2000; //2000 will be canceled on slave side
  }else
    yplus = yPosition;

  append = (xplus * 10000) + yplus; //creates space for y to be appended, easy way to append this


//------------Information Passing-------------------------
  if(mySerial.available() > 0){ // Checks whether data is comming from the serial port
    state = mySerial.read(); // Reads the data from the serial port
 }
  mySerial.write(append); // Sends appended value to slave for motor control
  //Serial.write(xPosition);

  delay(100); // add some delay between reads
}

Slave:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX
int state = 0;
int xDir = 508, yDir = 508; //middle position for joystick

//Motor Definitions
int E1 = 5;     //M1 Speed Control
int E2 = 6;     //M2 Speed Control
int M1 = 4;     //M1 Direction Control
int M2 = 7;     //M2 Direction Control

// Motor Speed Values - Start at zero
int MotorSpeed1 = 0;
int MotorSpeed2 = 0;

void setup() 
{
  //Initial standard setup
  // initialize serial communications at 38400 bps:
  Serial.begin(9600);


//------software serial setup-----------
  while (!Serial) 
  {
  ; // wait for serial port to connect. Needed for native USB port only
  }

  // set the data rate for the SoftwareSerial port
  mySerial.begin(38400);
}

void loop() 
{
//-------------Information Passing----------------------
  if(mySerial.available() > 0)// Checks whether data is comming from the serial port
  { 
    state = mySerial.read(); // Reads the data from the serial port
  }
  xDir = state / 10000; //cuts off last 4 digits
  yDir = state % 10000; //cuts off first 4 digits
  if(xDir > 1999) //had 2000 added
  {
    xDir -= 2000;
  }
  if(yDir > 1999) //had 2000 added
  {
    yDir -= 2000;
  }


// -----------Motor Control---------------------

if (yDir < 460) // This is Backward
 {
 // Set Motor A backward
 digitalWrite(M1, LOW);

 // Set Motor B backward
 digitalWrite(M2, HIGH);

 // Determine Motor Speeds Next

 // Because we are going backwards we need to reverse readings

 yDir -= 460; // This produces a negative number
 yDir *= -1;  // Make the number positive

 MotorSpeed1 = map(yDir, 0, 460, 0, 255);
 MotorSpeed2 = map(yDir, 0, 460, 0, 255);

 }else if (yDir > 564)// This is Forward
 {
 // Set Motor A forward

 digitalWrite(M1, HIGH);

 // Set Motor B forward

 digitalWrite(M2, LOW);

 // Determine Motor Speeds

 MotorSpeed1 = map(yDir, 564, 1023, 0, 255);
 MotorSpeed2 = map(yDir, 564, 1023, 0, 255); 

 }else // This is Stopped
 {
 MotorSpeed1 = 0;
 MotorSpeed2 = 0; 
 }

 // Now do the steering
 // The Horizontal position will "weigh" the motor speed
 // Values for each motor

if (xDir >564)// Move Right
 {
   // Map the number to a value of 255 maximum
   xDir = map(xDir, 564, 1023, 0, 255);

   MotorSpeed1 += xDir;
   MotorSpeed2 -= xDir;

   // Don't exceed range of 0-255 for motor speeds
   if (MotorSpeed1 > 255)MotorSpeed1 = 255;
   if (MotorSpeed2 < 0)MotorSpeed2 = 0;  
 }else if (xDir < 460) // Move Left
 {
   // As we are going left we need to reverse readings
   xDir -= 460; // This produces a negative number
   xDir *= -1;  // Make the number positive

   // Map the number to a value of 255 maximum
   xDir = map(xDir, 0, 460, 0, 255);

   MotorSpeed1 -= xDir;
   MotorSpeed2 += xDir;

   // Don't exceed range of 0-255 for motor speeds
   if (MotorSpeed1 < 0)MotorSpeed1 = 0;
   if (MotorSpeed2 > 255)MotorSpeed2 = 255;

 }

 // Adjust to prevent "buzzing" at very low speed
 if (MotorSpeed1 < 8) MotorSpeed1 = 0;
 if (MotorSpeed2 < 8) MotorSpeed2 = 0;

 // Set the motor speeds - might need digitalWrite as not using analog pins
// analogWrite(E1, MotorSpeed1); //left motor
// analogWrite(E2, MotorSpeed2); //right motor
 digitalWrite(E1, MotorSpeed1); //left motor
 digitalWrite(E2, MotorSpeed2); //right motor



 delay(97); // add some delay between reads - not 100 to account for delay during program calculation
}

closed as unclear what you're asking by per1234, sempaiscuba, MatsK, Greenonline, Dmitry Grigoryev Jul 9 '18 at 13:05

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    Do you know how big a number an int can hold...? – Majenko Jul 3 '18 at 21:08
  • 1
    mySerial.read() will return 1 byte, which has a maximum value of 255. When you divide a 1 byte int like this by 10000, you will get always 0. You don't seem to understand, how serial communication works – chrisl Jul 3 '18 at 22:03
  • 1
    You don't have any code, that actually establishes a connection between the two HC-05 modules (Am I right in that you have HC-05s in both sides?) – chrisl Jul 3 '18 at 22:07
  • @Majenko Thank you for mentioning the data size error, easy fix. – Aruss Jul 5 '18 at 15:47
  • @chrisl I was unaware that serial only passed 1 byte at a time, I haven't used it much. Thank you for clarifying that. What sort of "code" do I need to establish a connection? I was using AT commands, but it doesn't seem to work once I change from an empty upload to my actual code. – Aruss Jul 5 '18 at 15:48
1

Well, as mentioned in the comments you seem to have a issue with sizes. Serial.read() (and presumable SoftwareSerial.read()) returns a single byte of data (8 bits) as an int (which is a type that has a size of 2 bytes?!). So in order to receive all the data that you are sending, you should read continually until you have received all that was expected. There is a problem with doing this, if there is an issue and the sender doesn't send all the bytes you expect the receiver gets stuck waiting for the missing byte. So it may be best to read until you receive a byte or series of bytes that would not normally be received.

To put it into your context:

You want to send the following data:

  • X value, between 0 and 1016(?) (we'll assume 1024 it makes the maths easier)
  • Y value, 0 to 1024.
  • B value, 0 not pressed, 1 pressed.

256 is the maximum value on byte can hold, 65,535 is the maximum for two bytes. So your data will fit in 5 bytes, if we use 0xFFFF as the end of data marker, an extra two bytes that can never occur in your data, each transmission should be 7 bytes.

Now change your Master(Tx) code so it sends 7 bytes of data, xxyybff.

Then change your receiver to read data from the serial line into an 'int' buffer until it sees the bytes 0xFF followed by 0xFF.

You won't need all of the additions you were doing, to extract the values you could use memcpy() or

int buffer[7] = {0x01, 0xFC, 0x01, 0xFC, 0x00, 0xFF, 0xFF}; // Data from serial port
int x = (buffer[0] << 8) + buffer[1];
int x = (buffer[2] << 8) + buffer[3];
int b = (buffer[3]);
  • Thank you for demonstrating some ways to fix a couple of the aforementioned errors. I am now using a similar strategy to what you have listed above, yet the two devices won't connect so I can't see if it works properly. One additional thing I've noticed is that when viewing the serial monitor on the master device it has a bunch of "???" and boxes while trying to view the joystick input. Is this normal? Will it interfere on the slave side with the data transfer? – Aruss Jul 5 '18 at 15:51
  • I solved the previously mentioned problem, they were getting stuck in AT mode. But now the data transfer is still not taking place. If using standard serial communication I should be able to use Serial.write() for however many bytes I'm sending. Is this correct? Is there a way to diagnose where the data loss is happening? – Aruss Jul 5 '18 at 16:52
  • The question marks and boxes are non printable characters (outside the range 32-127). Print them as number not characters. – Code Gorilla Jul 6 '18 at 11:30
  • Thanks, after playing around further it appears that my slave isn't actually receiving data. My master also appears to be writing lots a stuff to the serial port, but it isn't actually transmitting. I've tried software serial as well and it doesn't work. Any suggestions on what could be wrong with the transmission side? I have RX wired to RX and TX wired to TX. When I try to print the joystick readings, on the master, it also includes a lot of garbage that shouldn't be printing. – Aruss Jul 6 '18 at 15:30
  • Thats your problem. When wiring TX to TX both sides try to send in the same line. Wire RX to TX of the other side and vice versa – chrisl Jul 7 '18 at 10:14

Not the answer you're looking for? Browse other questions tagged or ask your own question.