Go Down

Topic: Changing Servo Speed/Angle  (Read 1 time) previous topic - next topic

agm4xb

I am trying to use an arduino to run a dynamixel mx-64 servo. Right now I am able to prompt the user for two inputs, speed and angle sweep and then the servo starts running. I am having a hard time now being able to keep the servo running and then prompt again for a new speed/angle. How would you guys go about doing this if it is even possible? 

MarkT

Sounds like you need to do two things at once.  Google "arduino two things at once" and probably
"state machine" too.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Robin2

I am having a hard time now being able to keep the servo running and then prompt again for a new speed/angle.
Without seeing your program and a link to the datasheet for the servo you are using how can we know what you are doing.

There may be some ideas in Several Things at a Time

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

vinceherman

I have to say this.
WOW!  That is a $300 servo!  :o

Oh, on topic - read the Several Things at a Time tutorial.

agm4xb

I will try to get my code in here today, it's been pretty hectic. But I have looked at the "Multiple things at a time" code for arduino. What they do is just use separate functions for all of their actions. I created a function for asking the user for two inputs to control the servo, and then I had another function that took those two inputs and ran the servo so it would look like


void loop {

  askInput();
  runServo(input1,input2);

}


what ends up happening is it will ask for input and then only run the servo once through the sweep before asking for another input. I want the servo to keep running while it is asking for the next inputs.
 

Robin2

what ends up happening is it will ask for input and then only run the servo once through the sweep before asking for another input. I want the servo to keep running while it is asking for the next inputs.
It is a waste of time asking that sort of  question without posting your complete program.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

agm4xb

Code: [Select]
#include <Dynamixel_Serial.h>       // Library needed to control Dynamixal servo

#define SERVO_ID 0x01               // ID of which we will set Dynamixel too
#define SERVO_ControlPin 0x02       // Control pin of buffer chip, NOTE: this does not matter becasue we are not using a half to full contorl buffer.
#define SERVO_SET_Baudrate 9600    // Baud rate speed which the Dynamixel will be set too (57600)
#define CW_LIMIT_ANGLE 0x001        // lowest clockwise angle is 1, as when set to 0 it set servo to wheel mode
#define CCW_LIMIT_ANGLE 0xFFF       // Highest anit-clockwise angle is 0XFFF, as when set to 0 it set servo to wheel mode

float fs;
float anglePassed;
float newFS;
float newAnglePassed;
float sensorValue;
float sensorValue2;


void setup(){
 delay(1000);                                                           // Give time for Dynamixel to start on power-up

    Dynamixel.begin(SERVO_SET_Baudrate, SERVO_ControlPin);              // We now need to set Ardiuno to the new Baudrate speed
    Dynamixel.setMode(SERVO_ID, WHEEL, CW_LIMIT_ANGLE, CCW_LIMIT_ANGLE);    // set mode to SERVO and set angle limits
   
    initialize();

}



void loop(){
  runServo(fs,anglePassed);
  initialize();
 

}

 

void initialize() {
  Serial.println("Give value for freq");
  while(Serial.available() == 0) {}
  fs = Serial.parseFloat();*/
  Serial.println("Give the angle you want");
  while(Serial.available() == 0){}
  anglePassed = Serial.parseFloat();
 
}

void runServo(fs, angle){
 
     
      float avgRPS = ((0.25 * fs) + (0.68 * fs) + (fs)) * 0.114 / 180;
      float angleFrac = angle / 360;
      float totalTime = angleFrac * (1 / avgRPS) * 1000;
      float del = totalTime / 6;
   
      Dynamixel.wheel(SERVO_ID, RIGHT, fs/4);
      delay(del);
      Dynamixel.wheel(SERVO_ID, RIGHT, fs*0.68);
      delay(del);
      Dynamixel.wheel(SERVO_ID, RIGHT, fs);
      delay(del);
      Dynamixel.wheel(SERVO_ID, RIGHT, fs);
      delay(del);
      Dynamixel.wheel(SERVO_ID, RIGHT, fs*0.68);
      delay(del);
      Dynamixel.wheel(SERVO_ID, RIGHT, fs/4);
      delay(del);
      Dynamixel.wheel(SERVO_ID, LEFT, fs/4);
      delay(del);
      Dynamixel.wheel(SERVO_ID, LEFT, fs*0.68);
      delay(del);
      Dynamixel.wheel(SERVO_ID, LEFT, fs);
      delay(del);
      Dynamixel.wheel(SERVO_ID, LEFT, fs);
      delay(del);
      Dynamixel.wheel(SERVO_ID, LEFT, fs*0.68);
      delay(del);
      Dynamixel.wheel(SERVO_ID, LEFT, fs/4);
      delay(del);
       
}

vinceherman

I think you are missing the main point in Several Things at the Same Time.
Don't use delay() if you are trying to do several things at the same time.

You have many delay() calls in your servo routine.  Don't do that.  Go back and see how the tutorial handles multiple tasks at the same time.


agm4xb

In Several things at the same time, they use  the millis function to time everything so that all of these actions run together. I don't necessarily see how this helps what I'm trying to accomplish where the input can change the servo speed without having the servo stop running.

vinceherman

#9
Jun 28, 2017, 08:30 pm Last Edit: Jun 28, 2017, 08:30 pm by vinceherman
I don't necessarily see how this helps what I'm trying to accomplish where the input can change the servo speed without having the servo stop running.
But you do not allow the user to enter anything while the servo is running, because you sit locked inside the runServo() routine until the servo is done moving.

You need to change how you are managing the servo.
Use millis().
Every time you enter the runServo routine, check to see if enough time has elapsed to tell the servo to enter a new state (different speed for a different duration)  If not, bail out so that the user can interact.
If so, send the new data to the servo and bail out so the user can interact.

This also means that you user interaction has to be able to be non-blocking.  Serial Input Basics can show you how that is done.

agm4xb

Thanks! i'm pretty new if you can't tell. It's definitely frustrating having to use such a complicated servo for this project

vinceherman

#11
Jun 28, 2017, 10:22 pm Last Edit: Jun 28, 2017, 10:22 pm by vinceherman
:)
I have a fix for you.
Send that complicated servo to me.  I will trade it for any 3 of the zillion servos I have laying around.  :-P

Actually, I do not think that the interface to your servo is the complicating factor.  A servo sweep with yours will be nearly identical to the standard.

Understanding state machine programming (MarkT in Reply#1), Several Things at the Same Time, and serial basics are adding up to a bit more work.

But doable.  And there are a lot of people here who will help you get there.

agm4xb

Honestly the hardest part was scouring github for a library that worked correctly haha

Go Up