Reality Check

I stand on the shoulders of giants, at least that's my excuse for being uncreative and lazy!

Hardware:

500 Watt step up/step down transformer supplying ~ 60 volts A/C to

MA860h
http://www.leadshine.com/UploadFile/Down/MA860Hm.pdf

To drive:
a NEMA 34 stepper motor like this:

https://tinyurl.com/ybcv7sj7

The application is to drive the headstock spindle on a Sherline Lathe driving 1:1 desired maximum 1000 rpm with a stretch goal of 2000 rpm. I have checked that the setup is working using this code which I "borrowed" from someone else:

/*
driver MA860H
Pul+ goes to +5V
Pul- goes to Arduino Pin 9
Dir+ goes to +5V
Dir- goes to to Arduino Pin 8
Enable+ to nothing
Enable- to nothing
*/

int sensorPin = A3;
int sensorValue = 0;

void setup() {
pinMode(8, OUTPUT); //direction pin
pinMode(9, OUTPUT); //step pin
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
//Serial.begin(9600);
}

void loop() {
sensorValue = analogRead(sensorPin);
sensorValue = map(sensorValue,0,1023,0,200);
digitalWrite(9, HIGH);
delayMicroseconds(sensorValue);
digitalWrite(9, LOW);
delayMicroseconds(sensorValue);
//Serial.println(sensorValue);
}

This will produce a speed of around 420 rpm when the pot on A3 gets to zero. The motor is 200 steps per revolution and the driver was 1/4 stepping when this was achieved.

So I did a little research and found this:

http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Stepper_Drive_Timing

entry #46 down, or 10 up from the bottom if that's easier

Note these times are in nanoseconds. This is an empirical list, but a good starting place for a reality check. This project has been done before (told you I wasn't original) using a PIC 16F1719. I happen to have an Arduino Duemilanove (ATmega328 version) and so I thought I would try that before investing in anything else.

So, a 16mhz clock cycles at 62.5 nanoseconds, I need 1500 nanoseconds-so 24 clock cycles high and 24 cycles low. Assuming 1/4 stepping that will be 800 of those per revolution and that must be multiplied by 17 (per second) to reach 1000rpm and 34 (per second) to reach 2000rpm. Am I math numb, or are there ways to do this? So far I have briefly looked at stepper.h and AccelStepper and I don't think they will help. I'm looking at TimerOne and direct port switching right now.

Should I stop wasting time and move on, or is this possible with some patience?

Thanks,

Fats

24 clock cycles is a little short to do anything useful such as analogRead(). Fortunately your Arduino has dedicated hardware to do this for you.

TimerOne is one way that might get you there. If not, it will be close. As you work on that method, you will gain understanding that should help you find the ultimate solution.

Why would anyone want to use a stepper to drive a lathe headstock?

It must be an art project, to put little random grooves in the finished piece.

The original setup was for testing purposes only. With the original sketch the hardware should have come to a screetching halt when the pot reached zero (zero on time, zero off time) yet the motor was till running. So, other things in the sketch must be causing the delays. The analog read on A3? The two digital writes in the loop? The two delays in the loop?

I want to keep the analog read for now for testing of ramp up and ramp down numbers and data to help with timers.

I managed to eliminate the digital writes, although it makes the code less portable:

int sensorPin = A3;
int sensorValue = 0;
const byte outPin = 9;

void setup() {
pinMode(8, OUTPUT); //direction pin
pinMode(outPin, OUTPUT); //step pin
digitalWrite(8, HIGH);
//Serial.begin(9600);
}

void loop() {
sensorValue = analogRead(sensorPin);
sensorValue = map(sensorValue,0,1023,6,1000); //300=99, 350=86, 400=75, 500=64, 550=50
PORTB = PORTB | B00000010; // turn on bit 1 port B (pin 9) must use OR because bit 0 (pin 8, direction) is already on
delayMicroseconds(sensorValue);
PORTB = PORTB & B11111101; // turn off bit 1 only
delayMicroseconds(sensorValue);
//Serial.println(sensorValue);
}

This fixes the hidden delays and the hardware now comes to a stop when the pot hits 0. There is still something going on with default interrupts that is affecting the signal.

ref: Julian Investigates: How Slow is Arduino? - YouTube

I suppose I could switch some timers off to stop that (further research required). I suspect that an oscilloscope would make this project a lot easier (if I had the faintest idea how to use one), any recommendations on which to look at?

Fats

What Arduino are you using?

You probably should NOT be changing all the bits of PORTB because some of them probably have a special purpose. Use &= and |= (or equals) to change the bit you need to change.
For example PORTB &= 0b11111110; clears bit 0 and PORTB |= 0b00000001; sets bit 0

You may find that the digitalWriteFast library is fast enough and it is used the same way as the regular digitalWrite()

...R

Arduino Duemilanove (ATmega328 version)

I would prefer to use digital write as opposed to bitwise port manipulation in case I need to move the project to a different platform, thanks for the heads up on digitalWriteFast. When I next work on the project I will compare that to the current sketch

Actually I am changing none of the bits on Port B except the target bit, but your method is much more elegant, thanks

Fats

Fats:
Actually I am changing none of the bits on Port B except the target bit, but your method is much more elegant, thanks

Apologies. I did not read your code sufficiently carefully.

...R

Fats:
The original setup was for testing purposes only. With the original sketch the hardware should have come to a screetching halt when the pot reached zero (zero on time, zero off time) yet the motor was till running. So, other things in the sketch must be causing the delays. The analog read on A3? The two digital writes in the loop? The two delays in the loop?

From what I can read you want to what is called VECTOR CONTROL of the motor, that is constant and instantaneous control of motor speed.
This is heavy duty servo type control.
To get the hardware to **come to a screetching halt when the pot reached zero (zero on time, zero off time) **you are going to have to dissipate all the kinetic energy in the motor spindle load, this is done with brake resistors and advanced PWM control.

What is the total motor load, are you aware of how much kinetic energy you are trying to control.
Kinetic energy means amps of load current, and amps of breaking current if you want full speed control.
I don't think that controller you have is capable of dynamic braking.

I service and setup such systems, in packaging equipment, and they are very complex control systems due to motor inductance and peak currents involved, with PID control.

I cannot see any feedback in your sketch, so precision control will not be possible.

Can you please tell us your electronics, programming, Arduino, hardware experience?

Tom.... :slight_smile:

A poor choice of words on my part.

I should perhaps have said that I would have expected that, if delay was set to zero microseconds, the motor would do nothing at all. Since the motor was still turning, I wondered why that was happening.

This is a hobby project, the intention is to have a stepper motor that ramps smoothly and safely up to a set speed. The sketches I have posted so far are tests and so far from final yet.

This project has been done by others, example here:

They have all used PIC 16F1719, I thought I might try with Arduino since I have one on hand. It's fun trying to work out how to do it, if I stop having fun I'll just go the PIC route.

Fats

Hi,
If you listen to the musical start up that the YouTube shows.
That is because more than just H-Bridge stepper switching is going on.
Possibly 2kHz PWM modulation with each step output from the controller to limit current.

Mr Dan Barber seems reluctant to describe how his PIC controller and power handling work.

Tom... :slight_smile: