Problems sending data with two eb301 bluetooth modules and two arduinos

I apologize ahead of time if i'm posting in the wrong place or if this has already been discussed. This is my first post.

ok, so i have two arduinos with an eb301 bluetooth module attached to each. one arduino has a joystick connected to pins A0 and A1 and it seems to be working right. i see the values change in the serial port and i can connect it to my pc via bluetooth and also see the values change in putty. but on my receiver arduino with the two servos attached, i cant get them to move. the bluetooth modules seem to be paired but what should i change in my code to get it to read the values coming from arduino 1.
here are the codes im using:

Joystick transmitter: arduino 1

int potpin1 = 0;
int potpin2 = 1;

int newval1, oldval1;
int newval2, oldval2;

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

void loop() 
{ 
  newval1 = analogRead(potpin1);           
  newval1 = map(newval1, 0, 1023, 0, 179); 
  if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){ 
    Serial.println(newval1);
    oldval1=newval1;
  }
  
  newval2 = analogRead(potpin2);
  newval2 = map(newval2, 0, 1023, 0, 179);
  if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){    
    Serial.println(newval2);
    oldval2=newval2;
  }
  delay(50);
}

Joystick receiver: Arduino 2

#include <SoftwareServo.h>  
SoftwareServo myservo1;
SoftwareServo myservo2;

int newval1, oldval1;
int newval2, oldval2;

void setup() 
{
  Serial.begin(9600);  
  myservo1.attach(12);  
  myservo2.attach(13);
}

void loop() 
{ 
  if( Serial.available() )       
  {;}
  newval1 = Serial.read();            
  newval1 = map(newval1, 0, 1023, 0, 179); 
  if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){  
    myservo1.write(newval1);
    oldval1=newval1;
  }

  newval2 = Serial.read();
  newval2 = map(newval2, 0, 1023, 0, 179);
  if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){  
    myservo2.write(newval2);
    oldval2=newval2;
  }
  delay(50);
}

Thank you in advance for any replies and help

anyone? i really need this fixed before halloween.

Well, the first issue might be that you appear to be trying to receive with your transmit code. For testing you might start just using wires between the tx/rx/ground pins to rule out Bluetooth issues. You might modify your transmit code to include a servo identifier and delimiter (like a, and b,), and then try the bottom code as the receiving code.

replace

Serial.println(newval1);
Serial.println(newval2);

with

Serial.print(newval1);
Serial.print("a,");

Serial.print(newval2);
Serial.print("b,");
//zoomkat 11-22-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added 

String readString;
#include <Servo.h> 
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control 
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or combined like 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

hmm.. must be something else. thats still not working

You should be able to test the receiving code and servos using the serial monitor. Does the transmit code send the expected servo commands to the serial monitor?

yes, i do see the values changing in the serial monitor. also, the TX light flashes every time i move the joystick. my guess, it has to be something in the receive code

help? ive got two more days to get this going

For your receive code, instead of this:

void loop() 
{ 
  if( Serial.available() )       
  {;}
  newval1 = Serial.read();            
  newval1 = map(newval1, 0, 1023, 0, 179); 
  if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){  
    myservo1.write(newval1);
    oldval1=newval1;
  }

  newval2 = Serial.read();
  newval2 = map(newval2, 0, 1023, 0, 179);
  if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){  
    myservo2.write(newval2);
    oldval2=newval2;
  }
  delay(50);
}

try this:

void loop() 
{ 
  if( Serial.available() >= 2) {       
   newval1 = Serial.read();            
   newval1 = map(newval1, 0, 1023, 0, 179); 
   if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){  
     myservo1.write(newval1);
     oldval1=newval1;
   }

   newval2 = Serial.read();
   newval2 = map(newval2, 0, 1023, 0, 179);
   if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){  
     myservo2.write(newval2);
     oldval2=newval2;
   }
  }
  delay(50);
}

The code that follows the "Serial.available()" test assumes there are two bytes available to read, so that should be what you are testing for at the top of that "if" block.

The

    if( Serial.available() )       
  {;}

really doesn't make any sense -- it just tests to see if a byte is available, and if so, executes an empty code block. I would expect the compiler simply optimises this away, since regardless of the outcome of the test, the same instructions that follow will be executed.

Good luck. Don't let the vampires byte. :slight_smile:

Thanks for the reply! just in time too lol i'm about to try it out. ill post results
update: still no response from the servos. and i did away with the bluetooth modules for the test. i just hooked tx on the transmitter code to the rx on the receiver code. i still see the rx light blink when i move the joystick but still nothing on the receiving end.

jeremybgilbert:
Thanks for the reply! just in time too lol i'm about to try it out. ill post results
update: still no response from the servos. and i did away with the bluetooth modules for the test. i just hooked tx on the transmitter code to the rx on the receiver code. i still see the rx light blink when i move the joystick but still nothing on the receiving end.

Directly wiring up tx to rx is a good debugging idea -- make sure you connect the ground pins on the boards as well so they have a common signal voltage reference.

I've found another problem in your code, tx side this time: try replacing the Serial.println() statements in your transmit code with Serial.write() statements.

A write() statement will send a single byte that encodes an integer value with a value between 0-255, whereas a println() sends the value encoded as an ascii string of bytes, which would have to be decoded and converted back to an integer value at the receiving end. But since you are dealing with values < 255, sending as a single byte using e.g. Serial.write(newval1) should be fine.

Edit: Also, get rid of the delay(50) in the receiver code: not necessary, and you want your receiver polling faster than the transmitter is sending.

Finally, you want to send two new values to your receiver, or none at all. The way your transmitter is set-up now it is possible to send just one value but not the other. So instead of this:

void loop() 
{ 
  newval1 = analogRead(potpin1);           
  newval1 = map(newval1, 0, 1023, 0, 179); 
  if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){ 
    Serial.println(newval1);
    oldval1=newval1;
  }
  
  newval2 = analogRead(potpin2);
  newval2 = map(newval2, 0, 1023, 0, 179);
  if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){    
    Serial.println(newval2);
    oldval2=newval2;
  }
  delay(50);
}

try this:

void loop() 
{ 
  newval1 = analogRead(potpin1);           
  newval1 = map(newval1, 0, 1023, 0, 179); 

  newval2 = analogRead(potpin2);
  newval2 = map(newval2, 0, 1023, 0, 179);

  if  ((newval1 < (oldval1-2) || newval1 > (oldval1+2)) || (newval2 < (oldval2-2) || newval2 > (oldval2+2))) { 
    Serial.write(newval1);
    oldval1=newval1;
 
    Serial.write(newval2);
    oldval2=newval2;
  }
  delay(50);
}

That says if either joystick value has changed, send both values as a pair to the receiver.

The code can (and should) be be tidied up to make it more readable, but that's the quick cut'n'paste rearrangement of your logic.

This is a bit more readable, for example:

void loop() 
{ 
  newval1 = analogRead(potpin1);           
  newval1 = map(newval1, 0, 1023, 0, 179); 

  newval2 = analogRead(potpin2);
  newval2 = map(newval2, 0, 1023, 0, 179);

  bool changed1 = (newval1 < (oldval1-2) || newval1 > (oldval1+2));
  bool changed2 = (newval2 < (oldval2-2) || newval2 > (oldval2+2));

  if  ( changed1 || changed2 ) { 
    Serial.write(newval1);
    oldval1=newval1;
 
    Serial.write(newval2);
    oldval2=newval2;
  }
  delay(50);
}

I made changes but still no movement from the servos. :confused:

jeremybgilbert:
I made changes but still no movement from the servos. :confused:

I just spotted something else: Do you need to send you servos values in the range 0-179, or 0-1023?

Because if the former, you want to get rid of the map() fn lines on the receive side

  newval1 = map(newval1, 0, 1023, 0, 179);

Otherwise what you are doing is taking the raw analog read value (0-1023), converting to a smaller range (0-179) on the transmit side, then restoring it (with some loss of precision) back to the range 0-1023 again on the receive side. Which I suspect is not what you intend doing. Or is it?

Edit: It's even worse than that! I see you are effectively mapping from 0-1023 -> 0-179 not once, but twice. The second operation is the same as the first, not the inverse mapping! That will lead to a range something in the order 0-30, rather than 0-179, or 0-1023.

these are bits and pieces of sample codes so im not really sure honestly lol

Try this for your receive code:

void loop() 
{ 
  if( Serial.available() >= 2) {       
   newval1 = Serial.read();            
   //newval1 = map(newval1, 0, 1023, 0, 179); 
   if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){  
     myservo1.write(newval1);
     oldval1=newval1;
   }

   newval2 = Serial.read();
   //newval2 = map(newval2, 0, 1023, 0, 179);
   if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){  
     myservo2.write(newval2);
     oldval2=newval2;
   }
  }
}

still nothing. im starting to think this is a bigger pain than it's worth...

Have you tested the servos work if they are sent values in the range 0-179, as in your receive code?

You are either not getting the joystick values to your receiver, or the receiver is getting the values, but isn't able to control the servos with those values.

A simple test sketch in place of the actual receive sketch would allow you to determine what's what.

[OK, finished editing.]

Try this in place of your receive sketch and see if your servos move progressively through their expected range.

void loop() 
{ 
  delay(1000);

   newval1 += 2;
   if  ((newval1 > 179) ||  (newval1 < 0)) newval1 = 0;

   //newval1 = map(newval1, 0, 1023, 0, 179); 
   if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){  
     myservo1.write(newval1);
     oldval1=newval1;
   }

   newval2 += 2;
   if  ((newval2 > 179) ||  (newval2 < 0)) newval2 = 0;

   //newval2 = map(newval2, 0, 1023, 0, 179);
   if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){  
     myservo2.write(newval2);
     oldval2=newval2;
   }
 
}

jeremybgilbert:
im starting to think this is a bigger pain than it's worth...

Sod what you think, I want to get this going! :wink:

the servos work, but just not with this code for some reason. i just checked the serial monitor again and now the transmit sketch is messed up because im not getting the same values i was to begin with. im getting random stuff like this

jeremybgilbert:
the servos work, but just not with this code for some reason. i just checked the serial monitor again and now the transmit sketch is messed up because im not getting the same values i was to begin with. im getting random stuff like this

That's to be expected. You are sending integer values now, not strings, so they will look like nonsense when you try to print them as strings.

Is your serial monitor attached to your transmit sketch or your receive sketch?

In any case, try the test loop() for the receive sketch to check your servos are working as expected with the range of values you are sending. DIvide and conquer, it's the only way.