Speech Controlled Quadropod

Picture of Speech Controlled Quadropod

This is my first post on Instructables and I am super excited to share my knowledge!

My original robot post is here: Spryo SpoonTail which is just my robot showing some tricks but with a tethered control.

In this Instructable I am going to show you how to make a quadrapod of your own and using speech recognition via bluetooth to control your bot.

Gotta thank Oddbot for introducing me to robotics and helping me on a lot of projects. I am gonna reference his Instructable in certain stages to make this one shorter (with his permission ofcourse!).

Step 1: Understanding The Project

Picture of Understanding The Project

This project is not simple, in fact if you haven’t worked with Arduino and python, this project would be quite challenging, but trust me the end product is completely worth it. Additionally, you will discover how simple and powerful both Arduino and python really are.

It is worth mentioning that the main reason I am making this Instructable is to show that remote control via Bluetooth using speech recognition is quite possible and ain’t that hard. Also if you already have a robot of your own or even an RC car you have hacked, you can use this tutorial just for the speech recognition – control part.
Acknowledgements:

Step 2: Getting Started

Picture of Getting Started
software_required.jpg

Hardware Required:

Software Required:

  • Arduino – programming the quadropod
  • Python 3.4 – communication
  • Eclipse or Geany – python interface
  • Bitvoicer ($5) – speech recognition or Google Speech Recognition via python (free but involves more coding)

Skills Recommended:

  • Arduino knowledge
  • Python language
  • Patience (a lot required)

Note:

I am not advertising anything here, I am just linking you the products that I have used for my project, you are free to use tools/software/products of your liking or even make some on your own (think 3D printing).

Step 3: Chassis Assembly

Picture of Chassis Assembly
DSCF0527[1].jpg
DSCF0541[1].jpg

If you choose to use your own robot like an RC car, teddy bear or even a home automation device, feel free to skip this step.

Remember Oddbot who I mentioned before? He’s basically my virtual mentor. What you are going to do now is follow steps 1 to 7 from his Instructable – Playful Puppy Robot or you could use this PDF Manual to assemble to chassis of the quadrapod.

That’s it for this step.

Step 4: Wiring

Picture of Wiring
photo 2 (1).JPG
board[1].jpg
wiring_hc_board.jpg
photo 1 (2).JPG

Lets connect the servos first, they go in like this:

  • Front Left Hip servo – pin 46
  • Front Right Hip servo – pin 52
  • Rear Left Hip servo – pin 28
  • Rear Right Hip servo – pin 13
  • Front Left Knee servo – pin 47
  • Front Right Knee servo – pin 53
  • Rear Left Knee servo – pin 29
  • Rear Right Knee servo – pin 12

Note: The servos can be connected to which ever pins you find convenient, you just have to change the code to correspond to that changed pin.

Then the HC-06 bluetooth module (figure 4):

  • GND – GND
  • VCC – +5V
  • TXD – RX0 / D0 (Signal)
  • RXD – TX0 / D1 (Signal)

Figure 1: Shows the layout of the majestic DAGU Spider Board (note I drew the GND, 5V and Signal regions on the board for those of you who are slightly lazy to go through the manuals which I anyway really really recommend you to do).

Figure 2: Shows the splendid HC 06 Bluetooth module which will be our “RC” for this project. For this specific project, we will only be using the module to receive messages.

Figure 3: Wiring of the HC 06 to an Arduino UNO (in cause you just want to test it with an UNO or similar board for your specific project).

Figure 4: Plugging the HC 06 module to the Spider Board (GND and VCC connections are upto you as long as they are in that same line).

Figure 5: What it should kind of look like with everything plugged it (don’t worry about the shinny two ‘eyes’ in the front part of my bot, its just for show, and the servo on the back is for controlling his tail but the tail broke 😦 will fix it soon).

Step 5: Coding

Arduino:

Launch Arduino and open a new sketch. Unfortunately I do not have sufficient time to teach you the basics of Arduino. You can look up some tutorials if you feel like. So this is what we are going to do, once you opened a new sketch: File >> New or Ctrl + N.

Copy Paste the following code (or just download the attached file). I owe Oddbot again for helping me out with the motion part of the code looooong looong back.

The code:

/*  Title: Speech Controlled Quadropod
    Author: Adith Jagadish Boloor
    Comments: This code is free for you to use, modify or simply stare at when you are really bored.
*/

#include <Servo.h> // Servo Library

// Starting positions of the servos
#define FLHcenter      1500
#define FRHcenter      1500
#define RLHcenter      1520
#define RRHcenter      1450

#define FLKcenter      1150
#define FRKcenter      1220
#define RLKcenter      1220
#define RRKcenter      1210

// Here you can change servo pin numbers corresponding
// to your specific connections
#define FLHpin 46      // Front Left  Hip  servo pin
#define FRHpin 52      // Front Right Hip  servo pin
#define RLHpin 28      // Rear  Left  Hip  servo pin
#define RRHpin 13      // Rear  Right Hip  servo pin

#define FLKpin 47      // Front Left  Knee servo pin
#define FRKpin 53      // Front Right Knee servo pin
#define RLKpin 29      // Rear  Left  Knee servo pin
#define RRKpin 12      // Rear  Right Knee servo pin

// Buffer for the speech message
char INBYTE;

// LEDs!!!!! If you choose to use 'em
int led1 = 27;
int led2 = 11;
int led3 = 45;
int led4 = 26;

// Some constants for the bot's motions, yes you may
// play with them to get the best performance
int Time = 90;
int LShift = 280;
int RShift = 280;
int Raise = 550;

// Define servos
Servo FLHservo;                                               
Servo FRHservo;
Servo RLHservo;
Servo RRHservo;
Servo FLKservo;
Servo FRKservo;
Servo RLKservo;
Servo RRKservo;

void setup()
{
  // Attach servos (digitally)
  FLHservo.attach(FLHpin); 
  FRHservo.attach(FRHpin);  
  RLHservo.attach(RLHpin);  
  RRHservo.attach(RRHpin);  
  FLKservo.attach(FLKpin);  
  FRKservo.attach(FRKpin);  
  RLKservo.attach(RLKpin);  
  RRKservo.attach(RRKpin); 
  
  // Attach LEDs (digitally)
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  
   
  Serial.begin(9600);
  
  // Center servos
  FLHservo.writeMicroseconds(FLHcenter);
  FRHservo.writeMicroseconds(FRHcenter);  
  RLHservo.writeMicroseconds(RLHcenter);  
  RRHservo.writeMicroseconds(RRHcenter);  
  FLKservo.writeMicroseconds(FLKcenter+700);  
  FRKservo.writeMicroseconds(FRKcenter+700);  
  RLKservo.writeMicroseconds(RLKcenter+700);  
  RRKservo.writeMicroseconds(RRKcenter+700);
  delay(500);
  
  // Prints out the controls mapped to different letters
  Serial.println("wasd - movement");
  Serial.println("z - sleep");
  Serial.println("x - play dead");
  Serial.println("i - sit");
  Serial.println("u - stand");
  Serial.println("q - wake up");
}

void loop() {
  Serial.println("Ready to accept command");
  while (!Serial.available());   // stay here so long as COM port is empty   
  INBYTE = Serial.read();        // read next available byte
  delay(50);

  if (INBYTE == 'q') // wake up - flashes LEDs if you used them
  { 
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    delay(200);
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    delay(200);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    delay(200);
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    delay(200);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    delay(200);
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    delay(200);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    delay(200);
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
  }
  else if (INBYTE == 'z') //Sleeps
  {
    FLHservo.writeMicroseconds(FLHcenter); 
    FRHservo.writeMicroseconds(FRHcenter);  
    RLHservo.writeMicroseconds(RLHcenter);  
    RRHservo.writeMicroseconds(RRHcenter);  
    FLKservo.writeMicroseconds(FLKcenter+700);  
    FRKservo.writeMicroseconds(FRKcenter+700);  
    RLKservo.writeMicroseconds(RLKcenter+700);  
    RRKservo.writeMicroseconds(RRKcenter+700);
    delay(1000);
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    delay(200);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    delay(200);
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    delay(200);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    delay(200);
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    digitalWrite(led4, HIGH);
    delay(200);
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    delay(200);
  }
  else if (INBYTE == 'u') // stand Up
  {
    // Center servos
    FLHservo.writeMicroseconds(FLHcenter); 
    FRHservo.writeMicroseconds(FRHcenter);  
    RLHservo.writeMicroseconds(RLHcenter);  
    RRHservo.writeMicroseconds(RRHcenter);  
    FLKservo.writeMicroseconds(FLKcenter);  
    FRKservo.writeMicroseconds(FRKcenter);  
    RLKservo.writeMicroseconds(RLKcenter);  
    RRKservo.writeMicroseconds(RRKcenter); 
    delay(1000);
  }
  else if (INBYTE == 'x') // plays dead X
  {
    FLHservo.writeMicroseconds(FLHcenter);
    FRHservo.writeMicroseconds(FRHcenter);  
    RLHservo.writeMicroseconds(RLHcenter);  
    RRHservo.writeMicroseconds(RRHcenter);  
    FLKservo.writeMicroseconds(FLKcenter+700);  
    FRKservo.writeMicroseconds(FRKcenter+700);  
    RLKservo.writeMicroseconds(RLKcenter+700);  
    RRKservo.writeMicroseconds(RRKcenter+700);
    delay(1000);
  }
  else if (INBYTE == 'i') //sits
  {
    FLHservo.writeMicroseconds(FLHcenter);
    FRHservo.writeMicroseconds(FRHcenter);  
    RLHservo.writeMicroseconds(RLHcenter-600);  
    RRHservo.writeMicroseconds(RRHcenter+600);  
    FLKservo.writeMicroseconds(FLKcenter);  
    FRKservo.writeMicroseconds(FRKcenter);  
    RLKservo.writeMicroseconds(RLKcenter+700);  
    RRKservo.writeMicroseconds(RRKcenter+700);
  }
  else if (INBYTE == 'h') //shake Hands
  {
  FLHservo.writeMicroseconds(FLHcenter-600);
  FRHservo.writeMicroseconds(FRHcenter);  
  RLHservo.writeMicroseconds(RLHcenter-600);  
  RRHservo.writeMicroseconds(RRHcenter+600);  
  FLKservo.writeMicroseconds(FLKcenter+600);  
  FRKservo.writeMicroseconds(FRKcenter);  
  RLKservo.writeMicroseconds(RLKcenter-700);  
  RRKservo.writeMicroseconds(RRKcenter+700);
  delay(1000);
  FLKservo.writeMicroseconds(FLKcenter+300);
  delay(200);
  FLKservo.writeMicroseconds(FLKcenter+600);
  delay(200);
  FLKservo.writeMicroseconds(FLKcenter+300);
  delay(200);
  FLKservo.writeMicroseconds(FLKcenter+600);
  delay(200);
  }
  else if(INBYTE == 'w') // run forward
  {
  LShift=300;
  RShift=300;
  for(int i=0;i<5;i++)
  {
    Run();
  }
  }
  else if(INBYTE == 'a') // turn left
  {
  LShift=-300;
  RShift=300;
  for(int i=0;i<3;i++)
  {
    Run();
  }
  }
  else if(INBYTE == 'd') // turn right
  {
  LShift=300;
  RShift=-300;
  for(int i=0;i<3;i++)
  {
    Run();
  }
  }
  else if(INBYTE == 's') // run back
  {
  LShift=-300;
  RShift=-300;
  for(int i=0;i<5;i++)
  {
    Run();
  }
  }
}

void Run()
{
  FRKservo.writeMicroseconds(FRKcenter+Raise);         // raise front right leg 
  RLKservo.writeMicroseconds(RLKcenter+Raise-10);      // raise rear  left  leg
  FLHservo.writeMicroseconds(FLHcenter+LShift);        // move  front left  leg backward
  RRHservo.writeMicroseconds(RRHcenter-RShift);        // move  rear  right leg backward
  delay(Time/2);
  FRHservo.writeMicroseconds(FRHcenter+RShift);        // move  front right leg forward
  RLHservo.writeMicroseconds(RLHcenter-LShift);        // move  rear  left  leg forward
  delay(Time);
  FRKservo.writeMicroseconds(FRKcenter);               // lower front right leg 
  RLKservo.writeMicroseconds(RLKcenter);               // lower rear  left  leg
  delay(Time);
  
  FLKservo.writeMicroseconds(FLKcenter+Raise);         // raise front left  leg
  RRKservo.writeMicroseconds(RRKcenter+Raise);         // raise rear  right leg
  FRHservo.writeMicroseconds(FRHcenter-RShift);        // move  front right leg backward
  RLHservo.writeMicroseconds(RLHcenter+LShift);        // move  rear  left  leg backward
  delay(Time/2);
  FLHservo.writeMicroseconds(FLHcenter-LShift);        // move  front left  leg forward
  RRHservo.writeMicroseconds(RRHcenter+RShift);        // move  rear  right leg forward
  delay(Time);
  FLKservo.writeMicroseconds(FLKcenter);               // lower front left  leg
  RRKservo.writeMicroseconds(RRKcenter);               // lower rear  right leg
  delay(Time);  
}

Just before you can upload the code, do the following:

Open device manager and look up Ports (COM & LPT). Note the active port for your Arduino. It might say USB Serial Port (COM3) so for me the COM port is 3, THIS MIGHT BE DIFFERENT FOR YOU.

Tools >> Board >> Arduino Mega or Mega 2560 (image 2)

Tools >> Processor >> ATMega 1280 (image 3)

Tools >> Port >> COM3 (3 for my case only!!) (image 4)

Now you can hit the upload button and if all goes smooth, it should upload successfully and the robot should be on its belly with four legs stretched out symmetrically with a steady LED blinking from the HC 06.

If you get this error while uploading:

avrdude: stk500_getsync(): not in sync: resp=0xe0

Just disconnect the HC06 module, upload the code and hook it back on.

Ok I realized something while I was testing and writing this tutorial. You don’t need both BitVoicer and Python, you just need either of them. BitVoicer does everything for you and its speech recognition engine is quite powerful but it costs $5 while python’s speech recognition uses Google Speech API so it can sometimes give some really weird results and has some more coding, so the choice is yours.

Bluetooth

Okay just before we move on to the speech recognition bit via BitVoicer or Python, lets link the bluetooth of your PC to the HC 06 of your bot. Make sure the bluetooth on your PC works before proceeding because it took me 5 hours to realize that my laptop didn’t come with an inbuilt bluetooth and I had to order a module.

Now power up your bot either through USB or the battery pack. OMG when does this tutorial end!!!! Patience! You’re almost there.

  1. Right Click on Bluetooth Devices icon in the tray bar and click add new device.
  2. Let it search and search and search until HC – 06 pops up
    If it doesn’t show up after sometime try checking if you can find the device using your mobile phone (every phone except Apple phones should be able to detect it). If you don’t you know that there’s something wrong with your HC-06 and you need to fix it by checking the connections.
  3. Double click it.
  4. On the next dialogue box select Enter the device’s pairing code and type in 1234. It should then install the HC 06 to your computer.
  5. Now this part is important open up device manager (Start >> Device Manager)
  6. Go to Ports (COM & LPT) and note down the COM ports used by the Bluetooth. COM10 and COM21 for my case.

BitVoicer (Option 1)

You can download BitVoicer from here.

First things first, if you are not a American English speaker you might want to change the language/accent that BitVoicer will try to recognize. To do this go to File >> Additional Languages and go on install your preferred language/accent.

Now we are ready to add some commands. For starters we are going to add just two commands namely stand up and sit down. You can edit them or add more commands later. The steps are as follows:

  1. Create a new Schema by going to File >> New.
  2. Change the default command data type to char.
  3. Click Add New Sentence
  4. Type in “stand up” (no quotes)
  5. Click Add New Sentence
  6. Type in “sit down” (again no quotes)
  7. Now below in Sentence Anagrams, change the data types of both commands to char if its not already char.
  8. For stand up type the command as u and for sit down type i.
  9. Your screen should look like Image 5.
  10. Save your schema in a directory that is convenient for you.
  11. Now open up preferences by File >> Preferences and fill in the stuff using. The only three things that will be different for you will be the Default Output Folder, Speech Recognition Language and the Port Name.
  12. Your Port Name will correspond to your COM Port that YOUR Bluetooth uses that you found out in step 6 in Bluetooth. Try the lower number first.
  13. Hit Save.
  14. Go to the next step.

Python (Option 2)

First download Python (for this tutorial I am going to use version 3.4) which can be downloaded from https://www.python.org/download/releases/3.4.1/ Why 3.4 and the not the 2.7 version? Well the speech recognition which we are using works only on the 3.4 version of python (ya I know that sucks but hey 3.4 > 2.7 right?)

Install it into C:\Python34 for convenience sake. Next thing you need to do is download and install eclipse which is an interface for writing your code via Python. You can download it from http://www.eclipse.org/downloads/ Install it into C:\eclipse

If you get this error while running it…

A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. No Java virtual machine was found after searching the following locations:
C:\eclipse\jre\bin\javaw.exe
javaw.exe in your current PATH

Go to the first answer in http://stackoverflow.com/questions/2030434/eclipse-no-java-jre-jdk-no-virtual-machine

www.stackoverflow.com is the best place to find help for any issues in python

Use this tutorial to install python into eclipse except instead of python 2.6 you should choose python 3.4. Alternatively use this tutorial to install python into Geanyif you chose to use Geany which I hear is much nicer than eclipse but I haven’t had enough time to migrate to it. There are something called ‘libraries’ that you will need to access the different functionality of python. Now lets go ahead and install some libraries that we need for this project. For those of you who already know how to install libraries just go ahead install the listed ones and go on to the code.

Libraries Required:

  • PyBluez 0.20 – Bluetooth (setup)
  • PyAudio 0.2.8 – provides bindings for speech recognition (setup)
  • SpeechRecognition 1.1.0 – speech recognition (download)

PyBluez and PyAudio can be installed by downloading the “….win32-py3.4.exe” versions from the link and simply running the executable (setup) file.

SpeechRecognition library is a bit tricky if you’re new to python. Open the ‘download’ link above and click downloads. Download “SpeechRecognition-1.1.0.tar.gz (md5)”. Extract all the CONTENTS (not the folder that says SpeechRecognition-1.1.0 but whats in it) of the downloaded folder (via winRAR or any extractor you feel like using) to the python 3.4 directory (C:\Python34). If a dialogue box appears asking whether to replace existing files, click yes to all. Now navigate to C: drive and while holding Shift, right click on the folder that says Python34 and click “Open command window here”. Type in “python setup.py install” without quotes and hit Enter. Now you should have all the required libraries installed. Yay!

Open eclipse.

Under the folder PythonTest from the tutorial create a new file called Speech_Controlled_Quadrapod.py similar to how you created the pytest.py file you created in the tutorial. Now paste or download…

The code:

# Title: Speech Controlled Quadrapod
# Author: Adith Jagadish
# Description: Uses Google's Speech Recognition API and python bluetooth library to control a quadrapod 
# How to: Say "stand up" to make bot stand up and say "sit down" to make it sit. 
# Say "stop listening to terminate the program"

import bluetooth
import speech_recognition as sr
   
port = 1
bd_addr = "xx:xx:xx:xx:xx:xx"
sock = bluetooth.BluetoothSocket( bluetooth.RFCOMM )
sock.connect((bd_addr, port))
r = sr.Recognizer()
r.pause_threshold = 0.6
r.energy_threshold = 400
MESSAGE = "continue"
print("Ready to accept command...\n")
while (MESSAGE != "stop listening"):
    while (MESSAGE == "continue"):
        try:
            # use the default microphone as the audio source
            with sr.Microphone() as source:
                # listen for the first phrase and extract it into audio data
                audio = r.listen(source,timeout = None)
            # recognize speech using Google Speech Recognition                   
            print("Me: " + r.recognize(audio))    
            MESSAGE = str(r.recognize(audio))
        except LookupError:
            # speech is unintelligible                            
            MESSAGE = "continue"
            print("Could not understand audio")
        if(MESSAGE == "sit down"):
            sock.send("i")
        elif(MESSAGE == "stand up"):
            sock.send("u")
        elif(MESSAGE == "stop listening"):
            break;
        MESSAGE = "continue"
sock.close()
print("\nProgram terminated.")

The only change you need to do is in the line:

bd_addr = "xx:xx:xx:xx:xx:xx"

Right click on the bluetooth icon on the tray and click on “Show Bluetooth Devices”. Right click on HC-06 and click on properties. Go to the Bluetooth tab and copy the Unique identifier number and paste that in the place of xx:xx:xx:xx:xx:xx.
You are good to go on to testing.

Step 6: Testing and Debugging

Picture of Testing and Debugging

Well there’s nothing much to say here than what you expect.

Testing:

  1. Power up the quadropod or your robot.
  2. Turn on your Bluetooth if you haven’t done so already on your computer.
  3. Make sure your microphone is working.
  4. Launch BitVoicer or Python which ever you decided to use.
  5. Run the program.
  6. Say “stand up” or “sit down” as clearly as you can and see the magic unfold!
  7. Voila!

Now that you know the basics you can add more lines of code to make your bot do even more cool stuff!

If you weren’t lucky enough to get it working in the first go, its okay! It happens to the best of us.

Debugging:

  1. Try Googling your issue
  2. Make sure your wiring is correct
  3. Your code is copied correctly
  4. If it still doesn’t work, post a comment here and I’ll try my best to help you out!
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s