Plan is to build a driver for a 5 phase 10 wire stepper motor, according to attached diagram, with constant current limitation for each winding.
No problem with the code to step through each sequence.
Unless you suggest it should be done differently?
I'm a little unsure about how to code the current limitation? I have been unable to find a suitable code for the purpose. Any suggestions?
Clock input is max. 50kHz.
Would the Arduino DUE be fast enough to do the job, with current limitation?
/*
Driver for a 5 phase 10 wire stepper motor,
with constant current limitation for each widing.
*/
const int AH = 22;
const int AL = 2; // PWM
const int BH = 23;
const int BL = 3; // PWM
const int CH = 24;
const int CL = 4; // PWM
const int DH = 25;
const int DL = 5; // PWM
const int EH = 26;
const int EL = 6; // PWM
const int FH = 27;
const int FL = 7; // PWM
const int GH = 28;
const int GL = 8; // PWM
const int HH = 29;
const int HL = 9; // PWM
const int JH = 30;
const int JL = 10; // PWM
const int KH = 31;
const int KL = 11; // PWM
const int ICW1 = A1; // Input measured current winding 1
const int ICW2 = A2; // Input measured current winding 2
const int ICW3 = A3; // Input measured current winding 3
const int ICW4 = A4; // Input measured current winding 4
const int ICW5 = A5; // Input measured current winding 5
const int ClockInput = 32; // Clock input
const int DirectionInput = 33; // Direction input
int ClockCounter = 1; // Counter for the number of clock pulses
int ClockState = 0; // Current state of clock input
int LastClockState = 0; // Previous state of the clock input state
int DirectionState = 0; // Direction
int SCW1 = 0; // Set current winding 1
int SCW2 = 0; // Set current winding 2
int SCW3 = 0; // Set current winding 3
int SCW4 = 0; // Set current winding 4
int SCW5 = 0; // Set current winding 5
int CurrentSetPoint = 123; // Setpoint for current. 123 = 2.8A
void setup() {
pinMode(AH, OUTPUT);
pinMode(AL, OUTPUT);
pinMode(BH, OUTPUT);
pinMode(BL, OUTPUT);
pinMode(CH, OUTPUT);
pinMode(CL, OUTPUT);
pinMode(DH, OUTPUT);
pinMode(DL, OUTPUT);
pinMode(EH, OUTPUT);
pinMode(EL, OUTPUT);
pinMode(FH, OUTPUT);
pinMode(FL, OUTPUT);
pinMode(GH, OUTPUT);
pinMode(GL, OUTPUT);
pinMode(HH, OUTPUT);
pinMode(HL, OUTPUT);
pinMode(JH, OUTPUT);
pinMode(JL, OUTPUT);
pinMode(KH, OUTPUT);
pinMode(KL, OUTPUT);
pinMode(ICW1, INPUT);
pinMode(ICW2, INPUT);
pinMode(ICW3, INPUT);
pinMode(ICW4, INPUT);
pinMode(ICW5, INPUT);
pinMode(ClockInput, INPUT);
pinMode(DirectionInput, INPUT);
}
void loop() {
ClockState = digitalRead(ClockInput);
if (ClockState != LastClockState) {
DirectionState = digitalRead(DirectionInput);
if (ClockState == HIGH) {
if (DirectionState == HIGH)
{
ClockCounter++;
if (ClockCounter == 21){
ClockCounter=1;
}
}
else
{
ClockCounter--;
if (ClockCounter == -1){
ClockCounter=20;
}
}
}
LastClockState = ClockState;
}
SetOutput(ClockCounter);
}
void SetOutput(int i){
SetCurrent(); // set current for each winding
switch (i) {
case 1: // Step 1
digitalWrite(AH, HIGH);
analogWrite(AL, 0);
digitalWrite(BH, LOW);
analogWrite(BL, SCW1);
digitalWrite(CH, LOW);
analogWrite(CL, SCW2);
digitalWrite(DH, HIGH);
analogWrite(DL, 0);
digitalWrite(EH, HIGH);
analogWrite(EL, 0);
digitalWrite(FH, LOW);
analogWrite(FL, SCW3);
digitalWrite(GH, LOW);
analogWrite(GL, SCW4);
digitalWrite(HH, LOW);
analogWrite(HL, 0);
digitalWrite(JH, HIGH);
analogWrite(JL, 0);
digitalWrite(KH, LOW);
analogWrite(KL, SCW5);
break;
case 2: // Step 2
digitalWrite(AH, LOW);
analogWrite(AL, 0);
digitalWrite(BH, LOW);
analogWrite(BL, 0);
digitalWrite(CH, LOW);
analogWrite(CL, SCW2);
digitalWrite(DH, LOW);
analogWrite(DL, 0);
digitalWrite(EH, LOW);
analogWrite(EL, 0);
digitalWrite(FH, LOW);
analogWrite(FL, SCW3);
digitalWrite(GH, LOW);
analogWrite(GL, SCW4);
digitalWrite(HH, LOW);
analogWrite(HL, 0);
digitalWrite(JH, LOW);
analogWrite(JL, 0);
digitalWrite(KH, LOW);
analogWrite(KL, SCW5);
break;
// Etc. for step 3-20
}
}
void SetCurrent(){
// Measure and set current for each winding
// Perhaps some PID regulating?
// Any suggestions?
if (ICW1 < CurrentSetPoint){
SCW1 == ICW1 - 5; // If measured current is to high, reduce current
}
if (ICW1 > CurrentSetPoint){
SCW1 == ICW1 + 5; // If measured current is to low, increase current
}
}
driver5phase10wire.pdf (415 KB)