I recently salvaged parts from a discarded Shimadzu laboratory spectrophotometer and was surprised that the diffraction grating was directly driven by a 5-phase, ten wire Vexta stepper motor. The optics were in perfect shape and useful for other projects, but there is little information on the web about how to drive a five phase stepper, and I could find no working Arduino examples.
Of course, you can buy a five phase driver from Oriental Motor Company (Vexta manufacturer) for about USD $200, but another option is to use an Arduino Pro Mini, and 3 cheap (USD $5) brushed DC dual motor drivers from Pololu.
Motor specs: Vexta PX33M-A-C6 0.21A, 33 Ohms per phase, 0.36 degrees/step.
The low current rating and moderate winding resistance means that direct drive from 5-6V is possible, avoiding the need for a chopper stepper driver. I decided to use 3 Pololu DRV8835 dual full bridge modules, and with dead simple code the motor is capable of executing 500 steps/sec from a dead stop, without skipping a single step. Half step drive is available, for 2000 steps/revolution, capable of better than 500 steps/second.
Click on the in_action.mpg link in attachments to see it move in real time.
Important information below, used as a guide in creating the working example.
- Winding information: there is confusion on the web about motor coil and wiring color code with lead assignment. I started with this diagram, which supposedly reveals the coil and winding start/finish order:
But the motor connector had white/yellow and grey/black reversed from the sequence above. The driver works with swapped connections (as long as both pairs of the two connections are reversed) but obeying the connector wire order resulted in the smoothest and presumably correct operation. That is, swap white/yellow and black/gray.
The decision to swap those leads is supported by this alternative assignment of wire colors and winding identifications. Evidently Oriental Motor is inconsistent with wire color codes.
-
Coil excitation sequence, half and full step. Used to create the excitation lookup tables.
-
Wiring diagram for two of the phases (micro used was the Pro Mini). The other three follow this pattern. Complete pin assignments and motor/driver connections are described in the code below. Image on Pololu product page: Pololu - DRV8835 Dual Motor Driver Carrier
-
TOTALLY UNOPTIMIZED but fully functional code. Note that the drive tables are cyclic permutations of each other, so only one is required (ten bytes of storage in the optimized version).
// five phase drive for Vexta PX33M-A-C6 0.21A, 33R per phase, 0.36 degrees/step
// S. J. Remington 10/2020
// 3x Pololu DRV8835 dual motor driver
// **IN/IN mode selected**
// IN1 IN2 OUT1 OUT2 Truth Table
// 0 0 open open
// 1 0 H L
// 0 1 L H
// Vexta models PK and PX, wire colors in order around the motor as provided by manufacturer
//A - blue > red
//B - white > yellow (swapped)
//C - brown > purple
//D - black > gray (swapped)
//E - orange > green
// drive sequences from 10_wire_sequence.png
// NOTE that these tables are cyclic permutations of each other, so only one is actually required.
//
// This is the simple, brute force RAM wasting version.
/*
// half step
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
int AB[20] = { 1, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 1, 1, 1, 1, 1, 1, 1, 1};
int CD[20] = {-1,-1,-1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,-1,-1,-1,-1,-1,-1};
int EF[20] = { 1, 1, 1, 1, 1, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 1, 1, 1, 1};
int GH[20] = {-1,-1,-1,-1,-1,-1,-1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,-1,-1};
int JK[20] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0};
*/
// full step (1000 steps/revolution)
int AB[10] = { 0, -1, -1, -1, -1, 0, 1, 1, 1, 1};
int CD[10] = { -1, 0, 1, 1, 1, 1, 0, -1, -1, -1};
int EF[10] = { 1, 1, 0, -1, -1, -1, -1, 0, 1, 1};
int GH[10] = { -1, -1, -1, 0, 1, 1, 1, 1, 0, -1};
int JK[10] = { 1, 1, 1, 1, 0, -1, -1, -1, -1, 0};
//
int index = 0;
int index_max = 10; //set to 10 or 20, depending on table selected above.
void setup() {
//pin -> motor phase, wire color, driver in/out pins & driver chip assignments
pinMode(2, OUTPUT); //A blue, I1, O1 MD1A
pinMode(3, OUTPUT); //A red, I2, O2, MD1A
pinMode(4, OUTPUT); //B yellow, I1, O1, MD1B
pinMode(5, OUTPUT); //B white, I2, O2, MD1B
pinMode(6, OUTPUT); //C brown, I1, O1, MD2A
pinMode(7, OUTPUT); //C purple, I2, O2, MD2A
pinMode(8, OUTPUT); //D grey, I1, O1, MD2B
pinMode(9, OUTPUT); //D black, I2, O2, MD2B
pinMode(11, OUTPUT); //E orange, I1, O1, MD3A
pinMode(12, OUTPUT); //E green, I2, O2, MD3A
}
void loop() { //execute 1000 steps at full speed, from dead stop
for (int i = 0; i < 1000; i++) {
if (AB[index] > 0) {
digitalWrite(2, 1);
digitalWrite(3, 0);
}
if (AB[index] == 0) {
digitalWrite(2, 0);
digitalWrite(3, 0);
}
if (AB[index] < 0) {
digitalWrite(2, 0);
digitalWrite(3, 1);
}
if (CD[index] > 0) {
digitalWrite(4, 1);
digitalWrite(5, 0);
}
if (CD[index] == 0) {
digitalWrite(4, 0);
digitalWrite(5, 0);
}
if (CD[index] < 0) {
digitalWrite(4, 0);
digitalWrite(5, 1);
}
if (EF[index] > 0) {
digitalWrite(6, 1);
digitalWrite(7, 0);
}
if (EF[index] == 0) {
digitalWrite(6, 0);
digitalWrite(7, 0);
}
if (EF[index] < 0) {
digitalWrite(6, 0);
digitalWrite(7, 1);
}
if (GH[index] > 0) {
digitalWrite(8, 1);
digitalWrite(9, 0);
}
if (GH[index] == 0) {
digitalWrite(8, 0);
digitalWrite(9, 0);
}
if (GH[index] < 0) {
digitalWrite(8, 0);
digitalWrite(9, 1);
}
if (JK[index] > 0) {
digitalWrite(11, 1);
digitalWrite(12, 0);
}
if (JK[index] == 0) {
digitalWrite(11, 0);
digitalWrite(12, 0);
}
if (JK[index] < 0) {
digitalWrite(11, 0);
digitalWrite(12, 1);
}
delay(2); //500 steps/second OK
index++; //forward motion.
// index--; //reverse motion
if (index >= index_max) index = 0;
if (index < 0) index = index_max - 1; //fixed
}
delay(500);
}
For the pentagon wiring option, five half bridge drivers are used. A couple of L298 drivers would work fine with this motor. Step sequences for the pentagon connection are appended in the PDF file from Oriental Motor.
vexta_pentagon_phase_sequence.pdf (59.2 KB)
in_action.mpg (1.59 MB)