Servo motors reading values in 'real time' form file

Hello, I’m developing a project, and although I already made some progress I don’t know If I’m going in the right direction.

So the project is simple, I have a log file with the position values that I want my servo motors (mg995) to ‘read’ and move accordingly at the rate of 1/8khz (0.008 seconds)

So far I’ve made a serial port connection and with a python shield I’m able to read the file and send it to the Arduino
In the Arduino I have to process the value and give a little adjust, and then write to the servos.

My difficulties right now is to make the motors act in ‘real time’. What is happening is that the Arduino is not reading the values at the same time that the python is sending it to him.
I want it to move at the speed of 0.008 seconds, but when I send the value at that speed the motors don-t even move, I have to slow it down to 0.8 seconds minimum so they can move accordingly .
I’m using a time.sleep() function in python to make the interval between the loop.

So, is my approach good or should I do it in some other way? what is blocking the speed of communication/reaction between reading the values and the servos movement ?

bellow is a sample of what i’m using to read and move the ‘X’ motor, although the idea is to do this for all 3 motors at the same time.

A sample of my arduino code to move ‘X’ motor

void loop()


void serialEvent()
{
   
 while(Serial.available()) {
 
 char ch = Serial.read();
 Serial.write(ch);

 if(index < MaxChars && ch != ",") {

            strValue[index++] = ch; 

      } else { 
        
            strValue[index] = 0; 
            
            newAngle=atoi(strValue)+90;

          
          X.write(newAngle);


 index = 0;
 angle = newAngle;
 angleX = newAngle;
 value = 0;   

    }
  }

a Sample of The Python code to read the file and send the values to arduino thru the serial port

file = open('Xvalues.txt')
while 1:
        line = file.readline()
        if not line:
                break
        ser.write(str.encode(line))
        time.sleep(0.8)
file.close

A sample of the file with the values for the X motor

22,
22,
22,
23,
24,
24,
24,
24,
25,

thank you all :wink:

RC systems typically update at a 50Hz rate.
(20ms frame time)

The signal which drives a servo operates at roughly 50Hz. So it updates every 20ms. Trying to update a servo position every 8 MICROSECONDS is a hopeless task.

Steve

slipstick:
The signal which drives a servo operates at roughly 50Hz. So it updates every 20ms. Trying to update a servo position every 8 MILLISECONDS is a hopeless task.

Steve

Well caught!

Steve

can a motor drive sheild help in any way ?

slipstick:
The signal which drives a servo operates at roughly 50Hz. So it updates every 20ms. Trying to update a servo position every 8 MICROSECONDS is a hopeless task.

Steve

ok but how can I get to those 20ms? If I go bellow the time.sleep(0.8) 'seconds' they wont move.

what's the best way to synchronize the reading of the file and the wringing of the servos position?

We can't see your code.

AWOL:
We can’t see your code.

the arduino code ?

right now i just want to know what is the fastest way to read the vale from a file and send it to arduino to make the servo spin, if i could get to the 20ms it would be good enough

i’ll post the code again but don’t mind the code too much

#include <Servo.h>

Servo Xmotor;

int angle = 0;
int newAngle = 0;
const int MaxChars = 4;
char strValue[MaxChars+1];
int index = 0;

 int value = 0;

void setup()
{
 Serial.begin(9600);
 Xmotor.attach(10);
 angle = 90;
 
}
void loop()
{}

void serialEvent()
{

while(Serial.available()) 
{
 char ch = Serial.read();
 Serial.write(ch);

if(index < MaxChars && ch != ",") {

            strValue[index++] = ch; 

      } else { 
        
            strValue[index] = 0; 
            
             newAngle=atoi(strValue)+90;
            
          
           Xmotor.write(newAngle);



 index = 0;
 angle = newAngle;
 value = 0;   

    }
  }
}

That code isn't doing what you described earlier. You have an empty loop() and a function serialEvent() which is never called. And if it was called the use of strValue sometimes as an array and sometimes not would produce some very odd results.

If you can't or won't post the actual code that does what you're describing and so demonstrates the problem you want solving it's going to be difficult to help.

Steve

Hi,
What is the application?
Why do you need to move the servos so fast?
Do you know if the servos can move as quick as you need?

Can you tell us your electronics, programming, arduino, hardware experience?

Thanks.. Tom... :slight_smile:

ok, let me put this in a simpler way

let’s forget my code for now

I have a flight log with recorded values of the 3 axis of the craft along the time (recorded at a speed of 1/8khz), I now want to reproduce those movements in the servos.

I extract the values from each axis to his own file
this a sample of the values that I want to input to each servo motor

this are the electronics

The speed rate of writing in the servos have to match with the readings so it reproduce the movements at the real speed, for now it should be at least under the 80ms.

So, what is the best aproach? have a python shield to read the file and input to arduino via Serial COM? have an SDCard reader? Am I missing somehting?

logfiles.png

any ideas ?

Well one way you might get the data in faster via Serial is to use a faster rate than 9600. All Arduinos can go way faster than that.

And if you use a PCA9685 you can certainly send signal to the servos at more than 50Hz. So then it's just down to how efficient your code is and if the servos you're using can actually respond at the rate you want to use. Some can, many can't.

Steve

Please give the really required speed. 1/8kHz is roughly 0.1s, not 0.008s.

How fast can your servos move at all? What’s the minimum time for a move from 0 to 180° and back to 0? If you cannot figure out this yourself, begin with a simpler project.

Hi,
The servos that you need are very expensive and power hungry to move at the rates you want.

Hobby servos are not designed to what you need.

Your circuit has a basic problem.


Where are you getting the input voltage for the LM7805 regulator?
Have you a DMM to measure your circuit voltages, especially the "5V" going to your servos?
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Tom... :slight_smile:

Summary
The project consists in reading the angle values from a file and writing them to the Arduino servos but with some constraints.

Recording the values
I have a flight log with recorded values of the 3 axis of the craft along the time (recorded at a speed of 1/8khz),
I now want to reproduce those movements in the servos. The speed rate of writing in the servos have to match with the readings so it reproduce the movements at the same speed , the movements are of the drone will be smooth so the motors spinning speed are not a problem
The recorded values as you can see are always change gradually, there is never the case where the angle will change from 20º to 50º for example, it will always increment from 20º, 21º, 22º, 23º, …

The overview of the graph with the values from a flight

The values of the angles of the three axis in a exact moment
The values in the log go from -180 to 180, but for now I just want to consider de values from -90 to 90 to write in the servos.
I have this value in a excel sheet where I can extract them and do whatever transformation is needed

Moving the motors

I have 3 servo motors, each one for each axle, and I want them to replicate the flight the most realistic way possible. The speed of reading the value or writing to the servos should be a variable so it can be changed. In this example the log was recording at 1/8khz so, the speed of writing to the servos should be the same as the readings, or at least something quick enough to make the movements seem continuous and smooth.

Schematics
I have an Arduino mega 2560 and 3 MG995 servos powered by a 9v battery.
The X, Y, Z correspond to the yaw, pitch and roll.

In the end
I need to make sure my schematics are good enough for the job, I need some guidance in which is best approach for this job, and I need help to develop the code.

Thank you ver much.

all images in the attachments.

3d model.JPG

gyros2.JPG

gyroslog.JPG

log excel 2.JPG

If you have problems with the software, split it up into basic tasks:

  • read the time interval at program start or data file change
  • timed execution from Blink, better BlinkWithoutDelay, and Interval as already determined
  • after each interval read the new angles and
  • pass the angles to the servos

The type of 9v battery depicted in your image is going to be completely inadequate for powering three servos.

Threads merged.