Usb Native Port for pulsing Stepper?!

Hi there,

Got a question, as i am getting closer to the programming and controlling my motors i have to think about controlling the motors. The first thing i did is making a program to build up the accelleration curve for starting and stopping the motor, that was realy a **** job, but it works. The next thing i need to do is controlling the stepper by pc. I did some research about the native port on the Due, Zero and the Teensy 3.6 and if im understanding it correct it can handle over the 400mbit/s, thats great!

But...

Is this direct usb or is this a serial usb connection by using the com (virtual)port?!

The thing is to drive the motors i need to send 3 bytes for doing one step at the time, why? becourse i have to control more than one moter. 2 bytes for the pulse speed and one packet as indentifier. (0-256*256 and 0-256).

The lowest pulse speed is 12uS the largest 37500uS. The problem what i have is can it be done to send a data train to the arduino and can it handle the speed?! Or should i use something like ethernet to send the data stream.

An example of the data

12us motor 1 0x01000C
12us motor 1 0x01000C
12us motor 1 0x01000C etc...

that means that the arduino must handle a HIGH and delay from 12uS en then the next so on so on. And the best language for the pc is in this case #C? or can it be done with something like Perl. I know that Perl is not able to pulse data higher than 180khz. So i dont know if it is even possible to use Perl/PHP for direct data to the motors. But #C must do!

So im not shure what the best thing is to use for direct pc control for controlling the steppers.

Pfff im a bit out of options.

Ok the arduino side,

The only thing the arduino must do is collecting 3 bytes each time, use 2 bytes for the delaytime in microSeconds. And the 3th byte for the digital port handling. thats everything the arduino must do and of course the native port handling/handshake etc...

Are there any samples to look for or is there someone who have done this?! PC -> Arduino -> Stepper?!

Motors that i user are 7x 3Nm Nema 24 Closed Loop from Leadshine running at 48-75 volt. Speeds to archive 1 to 3000rpm. (37500us -> 12us) Running on 1/8 microstepping and the greatest reduction 50:1. So the pulse train is quite large. 1 revolution = 80,000 pulses.

Thanks,

Nena

PS or should i first upload the data to an SD card and then handle it all on the arduino?! What is faster Native USB, Ethernet or SD card?!

And a New Photo from the machine im building :slight_smile: Its taking form :smiley:

It would be completely impractical to send individual step instructions over a USB link. There is too much latency in the system.

You should design your system to tell the Arduino to move (say) 150 steps and let the Arduino deal with the timing etc for the individual steps.

Alternatively you could load the GRBL program onto your Arduino and have the PC send it lines from a GCode file.

...R

Thnx!

But how about the micro sd or networking?! Everything calculated by the arduino is oke, but with 7 axis?! if i want to turn one motor one revolution that about 16kb on data.

Nena

NenaGirl:
if i want to turn one motor one revolution that about 16kb on data.

I don't understand that at all.

If I want to move a motor 1 revolution I would do it something like this

for (int n = 0; n < 200; n++) {
   moveMotor1Step();
}

You need to explain in a lot more detail what you have in your mind.

...R

Well.

I use Nema 24 stepper motors 1.8 degrees at microstepping 1/8th and a Harmonic Drive 50:1 so thats 80.000 steps per revolution. So if i turn the motors at a speed of 3000 rpm the output speed is max 60 rpms.

Becourse the motor must have a acceleration and a deaccelleration and that i need to controll more than one axis. I need to combine several pulses together like a cnc router. But this time for max 7 axis.

If i use 3 bytes for each step thats 80.000 * 3 bytes is 240000 bytes for one axis for one revolution. Also the cuttinghead has 128000 pulses per rev. So i need to calculate everything before the arduino is even moving the motors. Due the multi axis.

Ive made an de/accelleration scheme for the motors (i attached a image from my program i've written in Perl and in Javascript/Canvas.


If im going to use multi axis on the arduino i think the arduino cant handle all axis with those speeds but when i can upload a pre generated list to the arduino it should be no problem at all.

Mayby i should give it a try with loading a list on a microSD and just test.

Nena

NenaGirl:
If i use 3 bytes for each step thats 80.000 * 3 bytes is 240000 bytes for one axis for one revolution. Also the cuttinghead has 128000 pulses per rev. So i need to calculate everything before the arduino is even moving the motors. Due the multi axis.

Where are you going to do those calculations?
Why are you doing those calculations? You have still not provided the information necessary to understand what you are talking about.

Even supposing you do have that data, how do you plan to get it to the Arduino? And what exactly do you expect the Arduino to do with it?

Post a link to the stepper motor driver that you are using? It sounds to me as if you are trying to do calculations that are normally carried out within a stepper motor driver.

...R

Im using these: http://www.leadshine.com/UploadFile/Down/ES-D808d_V0.1.1.pdf

The calculations probbebly on the pc, generating in a map and then send it to the arduino/teensy. The arduino should run the pulse list and give each motor the needed pulses.

I think the data is to large for the arduino to calculate and handle multi axis.

Motor settings is 1/8th microstepping 200p/rev and a harmonic drive.

200 * 8 * 50 = 80000 pulses per revelution. Why becourse i need to work precies. Also the callibration on the machine will be done with the pc. The only thing the arduino must do is executing the pulses. With a high/low.
timing is depending on the data also witch motor the pulse is getting.

The high stepping rate is only for accuracy of the machine. Ill measure everything just under the one micron. So also every position is placed in a mysql database for correcting the steps. I use a 3d laser scanner from Optimet for measuring.

4 axis have a Harmonic Drive 3 axis 50:1, 1 axis 80:1

3 axis have an absolute encoder with a resolution of 0.22 micrometer
the rest have proximity switches for homing.

The last thing i can think of is uploading a complete list with all steps to the arduino on a sd card and then run the list with the arduino to do all steps. I hoped it would work with direct communication but as you said it has to much latency.

The axis with the harmonic drives need to be driven up to 3000rpm otherwise i need to wait a minute to get even 80 cm. becourse the reduction is 50 times. Thats 3000/50 = 60rmp max.

Greets,

Nena

NenaGirl:
Motor settings is 1/8th microstepping 200p/rev and a harmonic drive.

What exactly is this thing you call "harmonic drive"?

The datasheet does not have the word harmonic in it.

...R

See below for an old benchmark on native USB port transfer speeds. I think the maximum wire speed is 12 Mbits/s, not 480, on Arduino boards with native USB hardware.

https://www.pjrc.com/teensy/benchmark_usb_serial_receive.html

What exactly is this thing you call "harmonic drive"?

It's a type of gearbox, frequently used in robotic applications.

Zero backlash, high reduction ratios, somewhat expensive.

The axis with the harmonic drives need to be driven up to 3000rpm

That's at the higher end of rpm range, for a stepper. You can do it, but there won't be too much torque.

Ok, it looks like you've done it. :slight_smile:

Daenerys:
It's a type of gearbox, frequently used in robotic applications.
Strain wave gearing - Wikipedia

Zero backlash, high reduction ratios, somewhat expensive.

Thanks for that.

It would have been nice if the OP had taken the same trouble that you have.

@NenaGirl, this sounds like a job for DC motors with encoders rather than stepper motors.

...R

this sounds like a job for DC motors with encoders rather than stepper motors.

The steppers are fine, got rit of the vibrations by using microstepping. Also dont need mutch torq on those high speed even the harmonic drives gives inaf torq to move the ballscrews.

dc/ac servo's are too expensive and dont have the desired torq with full stand still. These steppers are good for the project. The only thing that i have a problem with is get it all running under a arduino/teensy.

Controlling one stepper by the arduino/teensy is not a problem. But controlling more than one is. I need to keep me on the accelleration schemes...

So i need to upload the data from pc to the arduino but im still not knowing what is best.

Greets,

Nena.

NenaGirl:
So i need to upload the data from pc to the arduino but im still not knowing what is best.

I just don't see how that can be a solution - there would be too much data to load and too much risk of interruptions and latency problems.

Let's focus for a moment on a single motor (which you say can be controlled with an Arduino). If that was all you were using how would you control things with a PC?

...R

If i used one motor to get it to the max speed i would use my schematic code to drive the motor. I normaly dont upload my work but here it is. Still need to rewrite it to C for the arduino. I would send only to desired steps to the arduino and the curve table (@__x). Also for speed calculate the number of steps before running the motor by the arduino.

#!/usr/bin/perl
use CGI::Carp qw(fatalsToBrowser);
use strict;

my ($__l, $__i, $__o, $__x, $__y, $__z, $__a, $__b, $__c, $__d)=
   (   0,    0,    0,    0,    0,    0,    0,    0,    0,    0);

my ($x_i, $x_l, $x_o, $x_x, $x_y, $x_z, $x_a, $x_b, $x_c, $x_d)=
   (   0,    0,    0,    0,    0,    0,    0,    0,    0,    0);

my @__o = (0, 0, 0, 0);
my @__x = (
	[  0,   1],
	[1e6,   1],
	[1e6, 3e3],
	[2e6, 3e3]
);

	$__l = 1000; # Points
	$__o = 5; # Start RPM

for ($__i=0; $__i<$__l + 1; $__i++){
	($__x, $__y) = &Generate_Data($__i / $__l);

		$__o[2] = $__x;
		$__o[3] = $__y;

	while (1) {
		$__a = int(60 / ((200 * 8) * $__o) * 1e6);

		last if (($__a + $__d) > $__o[2]);

			$__b += ($__a / ($__o[2] - $__z));

		$__x = ((1 - $__b) * $__o[0] + $__b * $__o[2]);
		$__y = ((1 - $__b) * $__o[1] + $__b * $__o[3]);

		$__o = $__y;

		print "$__a (Motor Pulse)\n" if ($__c >= 1);

		$__c += 1;
		$__d += $__a;

		last if ($__x >= $__o[2]);
	}

	$__z = $__d;

	$__o[0] = $__x;
	$__o[1] = $__y;

	$__b = 0;

}

	print "Pulses: $__c - 1\n";

sub Generate_Data () {
	my ($x_i, $x_l, $x_o, $x_x, $x_y, $x_z, $x_a, $x_b, $x_c, $x_d)=
	   (   0,    0,    0,    0,    0,    0,    0,    0,    0,    0);

		$x_o = $_[0];

	$x_x = ((1 - $x_o) ** 3) * $__x[0][0] + 3 * ((1 - $x_o) ** 2) * $x_o * $__x[1][0] + 3 * (1 - $x_o) * ($x_o ** 2) * $__x[2][0] + ($x_o ** 3) * $__x[3][0];
	$x_y = ((1 - $x_o) ** 3) * $__x[0][1] + 3 * ((1 - $x_o) ** 2) * $x_o * $__x[1][1] + 3 * (1 - $x_o) * ($x_o ** 2) * $__x[2][1] + ($x_o ** 3) * $__x[3][1];

	return $x_x, $x_y;
}

Output:
...
141 (Motor Pulse)
141 (Motor Pulse)
141 (Motor Pulse)
140 (Motor Pulse)
140 (Motor Pulse)
...
140 (Motor Pulse)
139 (Motor Pulse)... etc

Pulses: 82824 - 1

Nena

I don't know Perl and it is too different from other languages to make a useful guess. What does that program do and how does it control your stepper motor?

What does the output that you have posted represent?

Maybe it would help to explain how I have written a Python program that interprets GCode and sends signals to an Uno to drive 3 motors on a small lathe.

My Python program does all the complex calculations for a single line of GCode and then sends 4 pieces of data to the Arduino. These are the total duration for the movement (in microsecs) and the interval between steps (also in microsecs) for each of the 3 motors. This is very easy for the Arduino to implement. And while the Arduino is giving effect to one movement the PC sends the data for the next movement which then sits in the Arduino Serial Input Buffer to be retreived when the current movement finishes. The amount of data going from the PC to the Arduino is very small.

...R

var x = total_number_of_steps;

for (int i= 0; i< x; i++) {
   digitalWrite(motor_pin, HIGH);
   delayMicroseconds(input_pulse_length);
   digitalWrite(motor_pin, LOW);
   delayMicroseconds(input_pulse_length);
}

Only to get (input_pulse_length). for the acceleration.

The program does the calculation for how long (microSeconds) each step needs to be HIGH and LOW.

Is your program time based or full calculatet motor positions. How do both motors run lets say on a x/y axis from 100x100u (units) if you want a diagonal do you fully calculate both axis and let them work together!? Or is this all time based?!

Nena

NenaGirl:
Only to get (input_pulse_length). for the acceleration.

I'm not sure what this is, but it does not seem to be a reply to my questions in Reply #14. If you are not prepared to answer questions as fully as possible I can't see how I can help. And feel free to offer even more information than that which I requested.

The program does the calculation for how long (microSeconds) each step needs to be HIGH and LOW.

There is no need to calculate how long the pulse needs to be HIGH. That should be a fixed value and long enough to be detected by the stepper driver. All that needs to be calculated is the interval between steps.

...R

The program calculates the delay time for the next step. These cannot be a fixed param. becourse you cant pulse a stepper from 1 rpm at once to 3000rpm. The motor would be directly in error mode.

1 rpm needs an delay of 37500 microseconds. 3000 rpm needs a delay time of 12 microseconds (official 12.5 microseconds) so you cant use a static number for the delay time. So i made a curve to run the motor on a soft start and soft stop. Thats what the program does, only calculating the delays for the motor pulse.

And it looks like that your program is running on a time based schematic not fully calculated. But can i get a copy of your program and take a look what your doing with the multi axis?

We are getting there :slight_smile:

Nena

NenaGirl:
The program calculates the delay time for the next step. These cannot be a fixed param.

I never suggested that the interval between steps would be fixed - that would be ridiculous.

Where I remain lost is that you posted a Perl program in Reply #13 which I don't understand but which, as I understand, you have used to control a stepper motor. If I can know how you used that program and how it controls the stepper driver I think I would have a much better understanding of what way your mind is working.

it looks like that your program is running on a time based schematic not fully calculated

I don't know what you had in mind when you wrote that. Can you explain further so I can be sure we understand each other.

...R

The program is just a program to generate the step delays to get a smooth acceleration nothing more. Its a algorithm for the delay times.

it looks like that your program is running on a time based schematic not fully calculated

Uhm, if you have two axis x and y. if you start on 0,0 and you must go to 100,100 do you calculate al interpolated steps or do you calculate only the time for both axis to get to 100,100.

Do you say the x axis needs 100ms to get to 100 and the y axis needs 50ms to get to 100 to get 100,100 or do you something like x = 1 step and y needs 2 steps then the next etc...

Nevertheless...

I still need to figure out how i can controll more than one axis at once.