Pages: [1]   Go Down
Author Topic: Tracking System using 9dof Razor IMU and Servo  (Read 1866 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'm developing a simple tracking system using the Sparkfun 9dof Razor IMU and a servo motor. I have a C++ application that reads the IMU data and calculates the change that needs to be made so that the system is pointed at the set location. Now I need to implement the Servo to read this calculation and rotate as needed.

The 9dof Razor IMU is using a simple FTDI breakout board to connect via USB. I am using an Arduino Uno R3 to control the servo.

I want to implement the servo rotation in my C++ program so the Arduino rotation signals will be sent from that. Right now, I'm looking into using Firmata to do this.

So with Firmata, I upload the standard firmata code to the Arduino and then control it elsewhere. My problem is I'm not sure where to begin with controlling it in my C++ program. All the code needs to do is determine if the change needed is negative or positive. If the value is negative it rotates in one direction. If it is positive, it rotates in the other.

Any suggestions or help would be greatly appreciated. I am completely open to using something other than Firmata.

Thanks!
Logged

Offline Offline
Edison Member
*
Karma: 58
Posts: 2078
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please add links to the components you are using (paste the url in the text).
This is your sensor board, https://www.sparkfun.com/products/10736
That costs 124.95 dollars ?
Three sensors (accel + gyro + compass) can be bought for 20 dollars on Ebay, or 10 dollars for 10DOF board, or 8 dollars if the magnetometer is on a seperate board.

A 'normal' setup with Arduino would be:
- An sensor board with I2C digital interface.
- An Arduino as the main controller for the servos, sensor board, kalman filtering, PID control.

A library to control servos, http://arduino.cc/en/Reference/Servo
A library for PID, http://playground.arduino.cc/Code/PIDLibrary
A guide for Kalman filtering, http://arduino.cc/forum/index.php/topic,58048.0.html

But you have a PC somewhere in the middle......
Logged

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

Yes, that is my sensor board. I already have it set up and an application developed for it. That is not my concern, nor my question.

Thank you for the links but I have already gone over the Servo reference page. I also already have my algorithm set and I have no need for Kalman filtering.

I am simply looking for a way to communicate with the motor (controlled by an Arduino Uno) in my C++ application.

Thanks!  smiley
Logged

Offline Offline
Edison Member
*
Karma: 58
Posts: 2078
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I see, I was confused by the PC in the middle.

The Arduino has an (virtual) serial port via the USB bus. It is used to upload sketches and to show messages for debugging and also to control the Arduino.
Since the Arduino has some tasks to do (like the servos), I think you can not use firmata on top of that.
http://firmata.org/wiki/Main_Page

The program on the PC has to use the (virtual) serial port.
Some use Python, or Java, but you have to program it in the C++ code.
You can make your own communication protocol.
You can make the communication readable, so you can use any terminal program to check upon the Arduino.
The Arduino side of the Serial, start here, http://arduino.cc/en/Reference/serial

Is this the answer you were looking for ?
« Last Edit: March 06, 2013, 07:48:26 pm by Erdin » Logged

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

I understand that a virtual serial port is created via the USB port. The same thing is done with the IMU. However, after looking at the Serial reference, I have no idea how I would go about making my own communication protocol. The examples don't provide what I'm looking for, something to go off of.

I have spent a lot of time on Google and have read all relevant references on the Arduino websites. I am hoping for a relevant example or a detailed explanation of how I can accomplish this.

P.S. - Just a heads up, I am using OS X and my application is entirely Terminal based.

Thanks!
Logged

Offline Offline
Edison Member
*
Karma: 58
Posts: 2078
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just learned that Firmata can be combined with servos.
In the Arduino IDE is an example: File / Examples / Firmata / ServoFirmata

For your own protocol, go to the Serial page
http://arduino.cc/en/Reference/serial
On the right are some examples, click on ReadASCIIString
http://arduino.cc/en/Tutorial/ReadASCIIString
That show how to use it, with Serial.parseInt.

This is a tutorial with Serial and Servo
http://playground.arduino.cc/Learning/SingleServoExample
Logged

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

This still does not help me with implementing anything in C++.

Anyone else have any ideas? Thanks!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 614
Posts: 49372
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Right now, I'm looking into using Firmata to do this.
Don't. As has been at least hinted at, develop your own protocol. Using C++, you can write anything to the serial port. So, write something like "<n, pos>", where n is the servo to move and pos is the new position.

Then, on the Arduino, use some code like this:
Code:
#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}
Where it says "Process the packet", use strtok() and atoi() to get the servo number and servo position. Then, figure out how a servo number relates to a Servo instance, and set that instance's position.
Logged

Offline Offline
Edison Member
*
Karma: 58
Posts: 2078
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This still does not help me with implementing anything in C++.

I can find this, it has source code, http://www.w7ay.net/site/Applications/Serial%20Tools/index.html
Perhaps this uses a serial communication, http://inivent.com/ardrumo/
But I don't know anything about OS X. Perhaps you should start a new topic for it, or ask it on a OS X software development forum ?
Logged

Pages: [1]   Go Up
Jump to: