Stepper Motor Control with Serial communication between python and teensy 4.1

Dear all,

Currently, I am developing a project in controlling a stepper motor using leap motion which is a hand-tracking camera sensor. The project consists of two sections. The first section is using a python to get hand coordinate data from the hand-tracking sensor and send these data to the Arduino IDE through serial communication. Second part is the teensy 4.1 will receive the coordination data to control the stepper motor.

Part 1: Python code verification
The code is tested correct by looking into the message printed in cmd. The command is sent from python to teensy in this format "WSJ5stepPin:J5dirPin?value_to_write". For testing purpose, I only consider controlling one stepper motor, so the command will always be in this form "WS8:9?an integer value" for now.

Part 2: Teensy code verification
The code is tested correct when the command is observable from the cmd, the stepper motor rotates as expected. Else (hand is not tracked), the motor stops. However, the motor rotates very very slow (which is not as expected with the delay(1))

Problem: I am suspecting there is something wrong with my code written in arduino IDE (referring to Part 2). Below is the code. Appreciate for any suggestion and advice on solving this! Do let me know if more explanation is needed.

Thank you.

char operation; // Holds operation (R, W, ...)
char mode; // Holds the mode (D, A)
int pin_number; // Holds the pin number
int digital_value; // Holds the digital value
int value_to_write; // Holds the value that we want to write
int wait_for_transmission = 1; // Delay in ms in order to receive the serial data
int direction;

unsigned long currentTime = 0;
unsigned long previousTime = 0;
// create stepper motor object to control a servo
// a maximum of eight stepper objects can be created
const int J5stepPin = 8;
const int J5dirPin = 9;
const int J5calPin = 31;
int limit5 = 0;
int step5 = 1000;


void setup() {
  Serial.begin(9600); // Serial Port at 9600 baud
  Serial.setTimeout(100); // Instead of the default 1000ms, in order
  // to speed up the Serial.parseInt() 

  pinMode(J5stepPin, OUTPUT); 
  pinMode(J5dirPin, OUTPUT); //HIGH = GO TOWARDS LIMIT SWITCH
  pinMode(J5calPin, INPUT);
}

void stepper_write(int stepPin, int dirPin, int rotation_value){
     if (stepPin==J5stepPin)
     {
        digitalWrite(dirPin, LOW); //MOVE UP
        digitalWrite(stepPin, HIGH);
        delay(1);
        digitalWrite(stepPin, LOW);
        delay(1);
     }
     


}

void loop() {
    if (Serial.available() > 0) 
    {
        operation = Serial.read();
        delay(wait_for_transmission); // If not delayed, second character is not correctly read
        mode = Serial.read();
        pin_number = Serial.parseInt(); // Waits for an int to be transmitted
        if (Serial.read()==':')
        {
          direction = Serial.parseInt(); // Collects the value to be written

          if (Serial.read()== '?')
          {
            value_to_write = Serial.parseInt(); 
          }
        }

        if (operation == 'W'){
          if (mode == 'S'){
            stepper_write(pin_number, direction, value_to_write);
          }
        }
    }
}


Additional information:

I am using DM520T stepper driver. The code below is used to test the limit switch. Same pulse width is applied which is "delay(1)". The code below does not apply serial communication, it is used for testing the motor only. The motor are able to rotate with the expected speed.

//////////////////////////////////////////////////////////////////////////////////////
//Stepper Motor Pin Definition
//////////////////////////////////////////////////////////////////////////////////////

const int J1stepPin = 0; //unusable motor
const int J1dirPin = 1; //unusable motor
const int J2stepPin = 2;
const int J2dirPin = 3;
const int J3stepPin = 4;
const int J3dirPin = 5;
const int J4stepPin = 6;
const int J4dirPin = 7;
const int J5stepPin = 8;
const int J5dirPin = 9;
const int J6stepPin = 10; //unusable motor
const int J6dirPin = 11; //unusable motor

//AccelStepper stepper(AccelStepper::DRIVER, J2stepPin, J2dirPin);
//////////////////////////////////////////////////////////////////////////////////////
//Limit Switch Pin Definition
//1 = LIMIT SWITCH PRESSED
//0 = LIMIT SWTICH RELEASED
//////////////////////////////////////////////////////////////////////////////////////

const int J1calPin = 26;
const int J2calPin = 27;
const int J3calPin = 28;
const int J4calPin = 29;
const int J5calPin = 30;
const int J6calPin = 31;
const int J7calPin = 36;
const int J8calPin = 37;
const int J9calPin = 38;

int limit2 = 0;
int limit3 = 0;
int limit4 = 0;
int limit5 = 0;

void setup() {
  Serial.begin(9600);
  Serial.setTimeout(500); // Instead of the default 1000ms, in order
  // to speed up the Serial.parseInt() 

  pinMode(J1stepPin, OUTPUT);
  pinMode(J1dirPin, OUTPUT);
  pinMode(J2stepPin, OUTPUT);
  pinMode(J2dirPin, OUTPUT); //HIGH = GO TOWARDS LIMIT SWITCH
  pinMode(J3stepPin, OUTPUT);
  pinMode(J3dirPin, OUTPUT); //LOW = GO TOWARDS LIMIT SWITCH
  pinMode(J4stepPin, OUTPUT);
  pinMode(J4dirPin, OUTPUT); //LOW = GO TOWARDS LIMIT SWITCH
  pinMode(J5stepPin, OUTPUT); 
  pinMode(J5dirPin, OUTPUT); //HIGH = GO TOWARDS LIMIT SWITCH
  pinMode(J6stepPin, OUTPUT);
  pinMode(J6dirPin, OUTPUT);

  pinMode(J1calPin, INPUT);
  pinMode(J2calPin, INPUT);
  pinMode(J3calPin, INPUT);
  pinMode(J4calPin, INPUT);
  pinMode(J5calPin, INPUT);
  pinMode(J6calPin, INPUT);
  pinMode(J7calPin, INPUT);
  pinMode(J8calPin, INPUT);
  pinMode(J9calPin, INPUT);

  digitalWrite(J2dirPin, HIGH);
  digitalWrite(J3dirPin, LOW);
  digitalWrite(J4dirPin, LOW);
  digitalWrite(J5dirPin, HIGH);
  
  limit2 = digitalRead(J2calPin);
  limit5 = digitalRead(J5calPin);

  // while(limit5 == 0 and limit5 != 1){
  //   digitalWrite(J5stepPin, HIGH);
  //   delay(3);
  //   digitalWrite(J5stepPin, LOW);
  //   delay(3);
  //   limit5 = digitalRead(J5calPin);
  // }

  // while(limit2 == 0){
  //   digitalWrite(J2stepPin, HIGH);
  //   delay(2);
  //   digitalWrite(J2stepPin, LOW);
  //   delay(2);
  //   limit2 = digitalRead(J2calPin);
  // }
  // for(int i = 0; i<5625; i++){
  //   digitalWrite(J2dirPin, LOW);
  //   digitalWrite(J2stepPin, HIGH);
  //   delay(2);
  //   digitalWrite(J2stepPin, LOW);
  //   delay(2);
  // }

  // while(limit3 == 0){
  //   digitalWrite(J3stepPin, HIGH);
  //   delay(2);
  //   digitalWrite(J3stepPin, LOW);
  //   delay(2);
  //   limit3 = digitalRead(J3calPin);
  // }
  // for(int i = 0; i<8250; i++){
  //   digitalWrite(J3dirPin, HIGH);
  //   digitalWrite(J3stepPin, HIGH);
  //   delay(2);
  //   digitalWrite(J3stepPin, LOW);
  //   delay(2);
  // }

  // while(limit4 == 0){
  //   digitalWrite(J4stepPin, HIGH);
  //   delay(1);
  //   digitalWrite(J4stepPin, LOW);
  //   delay(1);
  //   limit4 = digitalRead(J4calPin);
  // }
  // for(int i = 0; i<8000; i++){
  //   digitalWrite(J4dirPin, HIGH);
  //   digitalWrite(J4stepPin, HIGH);
  //   delay(1);
  //   digitalWrite(J4stepPin, LOW);
  //   delay(1);
  // }
  while(limit2 == 0){
    digitalWrite(J2stepPin, HIGH);
    delay(1);
    digitalWrite(J2stepPin, LOW);
    delay(1);
    limit2 = digitalRead(J2calPin);
  }
  while(limit4 == 0){
    digitalWrite(J4stepPin, HIGH);
    delay(1);
    digitalWrite(J4stepPin, LOW);
    delay(1);
    limit4 = digitalRead(J4calPin);
  }
  while(limit3 == 0){
    digitalWrite(J3stepPin, HIGH);
    delay(1);
    digitalWrite(J3stepPin, LOW);
    delay(1);
    limit3 = digitalRead(J3calPin);
  }
  while(limit5 == 0 and limit5 != 1){
    digitalWrite(J5stepPin, HIGH);
    delay(1);
    digitalWrite(J5stepPin, LOW);
    delay(1);
    limit5 = digitalRead(J5calPin);
  }
}

void loop() {

}

After getting some hints from MarkT in Teensy forum, I am able to come out with the solution!!

Sharing these findings here, incase anyone needs a reference:

Part 1: Non-blocking Serial parsing (focus more on example 5)

Serial Input Basics - updated

Continued from previous Post Receiving numbers rather than text So far the examples have assumed you want to receive text. But perhaps you want to send a number or maybe a mix of text and numbers. Example 4 - Receiving a single number from the Serial Monitor The simplest case is where you...

forum.arduino.cc forum.arduino.cc

Part 2: Controlling stepper motor through serial monitor to a fix position

With some modification on Part 2 coding with the reference of Part 1, the response is significantly increased and stepper motor can rotate at a desired speed

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.