Go Down

Topic: Problems sending data with two eb301 bluetooth modules and two arduinos (Read 3035 times) previous topic - next topic

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

Code: [Select]
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

Code: [Select]
#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


zoomkat

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
Code: [Select]

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


with

Code: [Select]

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

Serial.print(newval2);
Serial.print("b,");



Code: [Select]

//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
    }
  }
}


Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.


zoomkat

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?
Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

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


pico

For your receive code, instead of this:

Code: [Select]

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:

Code: [Select]

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
Code: [Select]

   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. :-)
WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)

#8
Oct 30, 2013, 05:52 pm Last Edit: Oct 30, 2013, 06:08 pm by jeremybgilbert Reason: 1
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.

pico


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.


WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)

pico

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:
Code: [Select]


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:

Code: [Select]

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:

Code: [Select]

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);
}

WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)


pico


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


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

Code: [Select]

 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.


WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)

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

pico

Try this for your receive code:

Code: [Select]

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;
   }
  }
}

WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)

Go Up