Hi!
We have project of which the goal is to turn a wheel on a car, as accurately as possible, and hopefully fast enough. We therefore have a closed loop stepper motor (Nema 23) on which a gear is connected. This furthermore turns a 4x bigger wheel, that rotates the shaft on the steering wheel of the car.
The problem is that we are not able to measure the position of the stepper motor while we are turning it, e.g. turn it 360 degrees one way, then 360 degrees the other way.
The stepper motor is a Nema 23 Closed Loop (link under), and we are using a Teensy 3.6 as micro controller board, and Arduino IDE as code-platform.
The stepper motor has four output cables, (A+,A-,B+,B-) of which tall are connected to a stepper driver, that again is connected to the controller Teensy.
The stepper motor has an incremental encoder on the back of it, of which has 6 cables ( GRD, VCC, EA+, EA-,EB+, EB-). We put 5v on VCC, EA+ and EB+ as output ( pin5 and 6), and all the rest to ground. (maybe wrong here, what to with EA- and EB-?)
To read from the encoder we have created an interrupt-function that gets called every time EA+ rises from 0 til 1, and then we increase a global counting-variable that is supposed to measure actual rotation.
We have been successful in rotating the stepper motor, and successful in reading the position from the encoder, as we were rotating the stepper by hand, without voltage on the stepper.
The problem is that we are not able to do both things at the same time. As we are trying to Serial.print() the value of the position variable while rotating, the stepper lags at speeds it easy handles without the code for reading the encoder. In addition, the value of position sky-rockets at seemingly random places, an becomes way more negative than positive.
We have tried increasing the baud rate to 115200, inserted some delays here and there. We are thinking it might as well be rooted in the fact that we do not use a closed loop stepper driver, only a normal stepper driver. We also only use two of the outputs of the encoder, not all four( use VCC and ground as well tho).
Stepper Motor (Nema 23)
Stepper Driver (Digital Stepper Driver DM542S)
Development board is a Teensy 3.6
Code:
int Pul = 8; // PUL+ from driver
int Dir = 9; // DIR+ from driver
int Ena = 10; // ENA+ from driver
int ENCB = 6; //EB+ from encoder
int ENCA = 5; //EA+ from encoder
int a = 0;
int b = 0;
bool CCW = true;
volatile int pos = 0;
void setup() {
Serial.begin(115200); //Baudrate of 115200 or 9600
pinMode(Pul, OUTPUT);
pinMode(Dir, OUTPUT);
pinMode(Ena, OUTPUT);
pinMode(ENCA,INPUT);
pinMode(ENCB,INPUT);
attachInterrupt(digitalPinToInterrupt(ENCA),readEncoder,RISING);
digitalWrite(Dir,LOW);// dir LOW - clockwise direction of roation (HIGH - CCW)
delay(900); //Delay to let program start before printing values
pos = 0; //to ensure that pos is zero when start, sometimes it increases before start?
Serial.print("Start. Pos: "); //To print and track the position per step
Serial.println(pos);
Serial.println("----------");
for (int i=0; i <= 400; i++){ //This loop will perform one revolution
digitalWrite(Ena, LOW); // optimize values in the for loop to get the highest torque possible
digitalWrite(Pul, HIGH);
delayMicroseconds(1000);
digitalWrite(Pul, LOW);
delayMicroseconds(1000); //original value 15000, min value 2000 ca.
Serial.print(i); //print and track step compared to measured rotation
Serial.print(" : ");
Serial.println(pos);
}
digitalWrite(Dir,HIGH); // change direction, now rotate CCW
Serial.print("Pause. Pos: ");
Serial.println(pos);
Serial.println("----------");
//delay(1000);
for (int i=0; i <= 400; i++){ // This loop will perform one revolution CCW
digitalWrite(Pul, HIGH);
delayMicroseconds(1000);
digitalWrite(Pul, LOW);
delayMicroseconds(1000);
Serial.print(i); //print and track step compared to measured rotation
Serial.print(" : ");
Serial.println(pos);
}
}
// Nothing needed in loop, just want to measure simple rotation back and forth for now
void loop() {
}
void readEncoder(){ //Interrupt function that gets called everytime EA+ rises
b = digitalRead(ENCB); //If EB+ already has risen, increase pos-value by 1, else decrease
if(b > 0){
pos++;
}
else{
pos--;
}
}