Pages: [1]   Go Down
Author Topic: Problems Controlling robot via Bluetooth and Android  (Read 534 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've recently completed building my hexapod robot. I've been testing its walking motions by just programming in a set path for it to walk over and over. This was good for getting the kinks out but now I want to be able to control it. I've been doing extensive reading online about how to communicated with Arduino via bluetooth and android. I found a nice library for Processing that allows for just such communication and makes the code much shorter.

The bluetooth module I'm using in an HC-06 slave module. It is attached to my arduino based Spider controller. I believe the phone is pairing with the device ok. The phone finds the robot and after I put in the pin it says it's paired. The red LED on the HC-06 then stops blinking and turns solid. I assume this means it's paired.

The problem I'm having now is that the arduino does not seem to be receiving any data from my phone when I press the buttons. I'm right now using a simple sketch to just blink the on board LED attached to pin 13 but it doesnt seem to work. If anyone has any experience with this I'd appreciate your input. Here is my arduino and processing code.

Arduino Code
Code:
#include <SoftwareSerial.h>

char INBYTE;

int  LED = 13; // LED on pin 13

#define rxPin 30
#define txPin 31

SoftwareSerial BTSerial(rxPin, txPin);

void setup()
{
  BTSerial.begin(9600);
  pinMode(LED, OUTPUT);
}



void loop()
{
  BTSerial.println("Press 1 to turn Arduino pin 13 LED ON or 0 to turn it OFF:");

  while (!BTSerial.available());   // stay here so long as COM port is empty   

  INBYTE = BTSerial.read();        // read next available byte
  if( INBYTE == 'd' ) digitalWrite(LED, LOW);  // if it's a 0 (zero) tun LED off
  if( INBYTE == 'w' ) digitalWrite(LED, HIGH); // if it's a 1 (one) turn LED on

  delay(50);
}

Processing Code
Code:
import android.content.Intent;
import android.os.Bundle;
import ketai.net.bluetooth.*;
import ketai.ui.*;
import ketai.net.*;

PFont myFont;                                   
boolean bReleased = true;       //no permament sending
KetaiBluetooth bt;                  // Create object from BtSerial class
boolean isConfiguring = true;
String info = "";
KetaiList klist;
ArrayList devicesDiscovered = new ArrayList(); //stores the discovered devices


// The following code is required to enable bluetooth at startup.
void onCreate(Bundle savedInstanceState)
{
  super.onCreate(savedInstanceState);
  bt = new KetaiBluetooth(this);//create the BtSerial object that will handle the connection
}

void onActivityResult(int requestCode, int resultCode, Intent data)
{
  bt.onActivityResult(requestCode, resultCode, data);
}//to show the discovered device

color background, buttons, text, pressed;
color spdu, spdd, stp, up, lft, rgt, dwn, rlt, rrt;

void setup()
{
  orientation(PORTRAIT);        //vertical
  bt.start();                                 //start listening for BT connections
  isConfiguring = true;               //at my phone start select device…

  rectMode(CORNER);
  textAlign(CENTER, CENTER);
  textSize(30);

  background = color(44, 62, 80);
  buttons = color(149, 165, 166);
  text = color(0, 0, 0);
  pressed = color(41, 128, 85);

  spdu = buttons;
  spdd = buttons;
  stp = buttons;
  up = buttons;
  lft = buttons;
  rgt = buttons;
  dwn = buttons;
  dwn = buttons;
  rlt = buttons;
  rrt = buttons;
}

void draw()
{
  //at app start select device
  if (isConfiguring)

  {
    ArrayList names;

    //create the BtSerial object that will handle the connection
    //with the list of paired devices
    klist = new KetaiList(this, bt.getPairedDeviceNames());

    isConfiguring = false;                         //stop selecting device
  }

  else
  {
    background(background);
    mousePos();

    if (mousePressed)
    {
      if (mouseX >= 218 && mouseX <= 503 &&
        mouseY >= 450 && mouseY <= 536)
      {
        up = pressed;
        byte[] data = {'w'};           
        bt.broadcast(data);             
        bReleased = false;               
      }
      else if (mouseX >= 123 && mouseX <= 218 &&
        mouseY >= 536 && mouseY <= 664)
      {
        lft = pressed;
        byte[] data = {'s'};           
        bt.broadcast(data);             
        bReleased = false;
      }
      else if (mouseX >= 218 && mouseX <= 503 &&
        mouseY >= 664 && mouseY <= 753)
      {
        dwn = pressed;
        byte[] data = {'a'};           
        bt.broadcast(data);             
        bReleased = false;
      }
      else if (mouseX >= 503 && mouseX <= 596 &&
        mouseY >= 535 && mouseY <= 664)
      {
        rgt = pressed;
        byte[] data = {'d'};           
        bt.broadcast(data);             
        bReleased = false;
      }
      else if (mouseX >= 240 && mouseX <= 480 &&
        mouseY >= 555 && mouseY <= 655)
      {
        stp = pressed;
        byte[] data = {'l'};           
        bt.broadcast(data);             
        bReleased = false;
      }

      else if (mouseX >= 0 && mouseX <= 180 &&
        mouseY >= 0 && mouseY <= 175)
      {
        spdu = pressed;
        byte[] data = {'k'};           
        bt.broadcast(data);             
        bReleased = false;
      }
      else if (mouseX >= 540 && mouseX <= 720 &&
        mouseY >= 0 && mouseY <= 175)
      {
        spdd = pressed;
        byte[] data = {'q'};           
        bt.broadcast(data);             
        bReleased = false;
      }
      else if (mouseX >= 0 && mouseX <= 345 &&
        mouseY >= 1025&& mouseY <= 1180)
      {
        rlt = pressed;
        byte[] data = {'e'};           
        bt.broadcast(data);             
        bReleased = false;
      }
      else if (mouseX >= 375 && mouseX <= 720 &&
        mouseY >= 1025 && mouseY <= 1180)
      {
        rrt = pressed;
        byte[] data = {'z'};           
        bt.broadcast(data);             
        bReleased = false;
      }
    }

    fill(spdu);
    rect(0, 0, 75*2.4, 75*2.28);
    fill(text);
    text("Speed Up", 0, 0, 75*2.4, 75*2.28);

    fill(spdd);
    rect(225*2.4, 0, 75*2.4, 75*2.28);
    fill(text);
    text("Slow Down", 225*2.4, 0, 75*2.4, 75*2.28);

    fill(rlt);
    rect(0, 450*2.28, 145*2.4, 75*2.28);
    fill(text);
    text("Rotate Left", 0, 450*2.28, 150*2.4, 75*2.28);

    fill(rrt);
    rect(155*2.4, 450*2.28, 155*2.4, 75*2.28);
    fill(text);
    text("Rotate Right", 155*2.4, 450*2.28, 150*2.4, 75*2.28);

    drawArrows();

    fill(stp);
    ellipse(150*2.4, 263*2.28, 100*2.4, 50*2.28);
    fill(text);
    text("Stop", 100*2.4, 235*2.28, 100*2.4, 50*2.28);
  }
}

void onKetaiListSelection(KetaiList klist)
{
  String selection = klist.getSelection();            //select the device to connect
  bt.connectToDeviceByName(selection);        //connect to the device
  klist = null;                                                      //dispose of bluetooth list for now
}

void drawArrows()
{
  fill(rgt);
  triangle(210*2.4, 235*2.28, 210*2.4, 292*2.28, 250*2.4, 262*2.28);//right
  fill(lft);
  triangle(90*2.4, 235*2.28, 90*2.4, 292*2.28, 50*2.4, 262*2.28);//left
  fill(up);
  triangle(210*2.4, 235*2.28, 90*2.4, 235*2.28, 150*2.4, 197*2.28);//dwn
  fill(dwn);
  triangle(210*2.4, 292*2.28, 90*2.4, 292*2.28, 150*2.4, 330*2.28);//up
}

void mousePos()
{
  fill(255, 0, 0);
  text("(" + mouseX + "," + mouseY +")", 150*2.5, 10*2.28);
}

void mouseReleased()
{
  spdu = buttons;
  spdd = buttons;
  stp = buttons;
  up = buttons;
  lft = buttons;
  rgt = buttons;
  dwn = buttons;
  dwn = buttons;
  rlt = buttons;
  rrt = buttons;
  bReleased = true;
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nevermind I figured it out. For anyone with a similar issue to this the solution for me was quite simple. My baude rate was not fast enough to get the data being sent. I changed it from 9600 to 19200 and it worked a bit better (NOTE: it had to be changed both in the arduino sketch and on the HC-06 module its self). Then it worked flawlessly when I switched from software serial to hardware serial. For anyone interested here is my code. It's a modified version of the sample code given on the Sparkfun product page for the hexapod chassis.

Code:
#include <Servo.h>   

int svc[12]={                                             
  1500,1550,1650,1450,                                     // D29 knee1, D46 Hip1, D47 knee2, D48 Hip2
  2200,1400,1700,1550,                                     // D49 knee3, D50 Hip3, D51 knee4, D24 Hip4
  1700,1500,1600,1400                                      // D25 knee5, D26 Hip5, D27 knee6, D28 Hip6
};

Servo sv[12];                                             

int angle;                                                 // determines the direction/angle (0°-360°) that the robot will walk in
int rotate;                                                // rotate mode: -1 = anticlockwise, +1 = clockwise, 0 = no rotation
int Speed;                                                 // walking speed: -15 to +15
int Stride;                                                // size of step: exceeding 400 may cause the legs to hit each other

boolean walkMode = false;

void setup()
{

  sv[0].attach(29,800,2200);                               // knee 1
  delay(40);
  sv[1].attach(46,800,2200);                               // Hip  1
  delay(40);
  sv[2].attach(47,800,2200);                               // knee 2
  delay(40);
  sv[3].attach(48,800,2200);                               // Hip  2
  delay(40);
  sv[4].attach(49,800,2200);                               // knee 3
  delay(40);
  sv[5].attach(50,800,2200);                               // Hip  3
  delay(40);
  sv[6].attach(51,800,2200);                               // knee 4
  delay(40);
  sv[7].attach(52,800,2200);                               // Hip  4
  delay(40);
  sv[8].attach(53,800,2200);                               // knee 5
  delay(40);
  sv[9].attach(28,800,2200);                               // Hip  5
  delay(40);
  sv[10].attach(27,800,2200);                              // knee 6
  delay(40);
  sv[11].attach(26,800,2200);                              // Hip  6
  delay(40);

  for(int i=0;i<12;i++)
  {
    sv[i].writeMicroseconds(svc[i]);                       // initialize servos
  }
 
  angle = rotate = 0;
  Speed = 8;
  Serial.begin(19200);
 
  delay(3000);     


void loop()
{
  if(Serial.available() > 0)
  {
    char remoteBit = (char)Serial.read();
    if(remoteBit == 'l')                              // STOP
    {
      walkMode = false;
    }

    if(remoteBit == 'w')                             // FORWARD
    {
      walkMode = true;
    }
    if(remoteBit == 'a')                             // REVERSE   
    {
      angle=180;
    }
    if(remoteBit == 'z')                                          // ROTATE CLOCKWISE 
    {
      rotate=1;
      angle=0;
    }
    if(remoteBit == 'e')                                          // ROTATE COUNTER CLOCKWISE 
    {
      rotate=-1;
      angle=0;
    }
    if(remoteBit == 'd')                                          //INCREASE WALK ANGLE   
    {
      rotate=0;
      angle+=30;
    }
    if(remoteBit == 's')                                          // DECREASE WALK ANGLE
    {
      rotate=0;
      angle-=30;
    }
    if(remoteBit == 'k')                                        // SPEED UP
    {
      if(Speed < 15)
        Speed += 1;
    }
    if(remoteBit == 'q')                                     //SLOW DOWN
    {
      if(Speed > 8)
        Speed -= 1;
    }
  }

  if(walkMode == true)
    Walk();                                                  // move legs to generate walking gait
  delay(15);
}


void Walk()                                                // all legs move in a circular motion
{
  if(Speed==0)                                             // return all legs to default position when stopped
  {
    Stride-=25;                                            // as Stride aproaches 0, all servos return to center position
    if(Stride<0) Stride=0;                                 // do not allow negative values, this would reverse movements
  }
  else                                                     // this only affects the robot if it was stopped
  {
    Stride+=25;                                            // slowly increase Stride value so that servos start up smoothly
    if(Stride>450) Stride=450;                             // maximum value reached, prevents legs from colliding.
  }

  float A;                                                 // temporary value for angle calculations
  double Xa,Knee,Hip;                                      // results of trigometric functions
  static int Step;                                         // position of legs in circular motion from 0° to 360°                               

  for(int i=0;i<6;i+=2)                                    // calculate positions for odd numbered legs 1,3,5
  {
    A=float(60*i+angle);                                   // angle of leg on the body + angle of travel
    if(A>359) A-=360;                                      // keep value within 0°-360°

    A=A*PI/180;                                            // convert degrees to radians for SIN function

    Xa=Stride*rotate;                                      // Xa value for rotation
    if(rotate==0)                                          // hip movement affected by walking angle
    {
      Xa=sin(A)*-Stride;                                   // Xa hip position multiplier for walking at an angle
    }

    A=float(Step);                                         // angle of leg
    A=A*PI/180;                                            // convert degrees to radians for SIN function
    Knee=sin(A)*Stride;
    Hip=cos(A)*Xa;

    sv[i*2].writeMicroseconds(svc[i*2]+int(Knee));         // update knee  servos 1,3,5
    sv[i*2+1].writeMicroseconds(svc[i*2+1]+int(Hip));      // update hip servos 1,3,5
  }

  for(int i=1;i<6;i+=2)                                    // calculate positions for even numbered legs 2,4,6
  {
    A=float(60*i+angle);                                   // angle of leg on the body + angle of travel
    if(A>359) A-=360;                                      // keep value within 0°-360°

    A=A*PI/180;                                            // convert degrees to radians for SIN function
    Xa=Stride*rotate;                                      // Xa value for rotation
    if(rotate==0)                                          // hip movement affected by walking angle
    {
      Xa=sin(A)*-Stride;                                   // Xa hip position multiplier for walking at an angle
    }

    A=float(Step+180);                                     // angle of leg
    if(A>359) A-=360;                                      // keep value within 0°-360°
    A=A*PI/180;                                            // convert degrees to radians for SIN function
    Knee=sin(A)*Stride;
    Hip=cos(A)*Xa;

    sv[i*2].writeMicroseconds(svc[i*2]+int(Knee));         // update knee  servos 2,4,6
    sv[i*2+1].writeMicroseconds(svc[i*2+1]+int(Hip));      // update hip servos 2,4,6
  }

  Step+=Speed;                                             // cycle through circular motion of gait
  if (Step>359) Step-=360;                                 // keep value within 0°-360°
  if (Step<0) Step+=360;                                   // keep value within 0°-360°
}

Logged

Pages: [1]   Go Up
Jump to: