Linking Stepper Motor to Processing GUI

Hello! I am currently using an Arduino UNO along with a Stepper Motor driver to control a NEMA 17 4 wire stepper motor. The stepper motor controls the position of a spray gun using a timing belt.
I currently have a version of the code that does what I need:

Void startup() homes the position of the spray gun to the center of the rack, then bring it to the left edge of the spray range
Void movemotor() subsequently bounces the spray gun left and right. (In this section I abandoned accelstepper because it does not move fast enough)
Void shutdown() brings the spray gun back to the limit switch and stops the gun from moving by aborting the code.

The system is currently controlled by a single limit switch, and a button connected to the reset pin of my arduino.

My struggle comes when I am trying to upgrade the system. I want to integrate a GUI using processing. I currently have three sliders on the GUI that I would like to correlate to three variables in my code:
runSpeed (the maximum speed of the motor during normal operation)
Sweep (the distance traveled by the motor during normal operation)
And center (the center position of the motor)

My current attempt has the serial monitor communicate. The codes upload and the motor runs, however when it gets to the void loop portion of the code, the motor vibrates violently and does not react to changes in the GUI slider.
I am relatively new to arduino, especially using serial inputs, so any advice would be greatly appreciated.

Arduino Code:

#include <AccelStepper.h>

byte directionPin = 6;  //Set Direction pin
byte stepPin = 10;      //Set Step Pin

AccelStepper myStepper(AccelStepper::DRIVER, 10, 6);  //Defines pins on stepper

#define home_switch 9  //Set Limit Switch Pin


//USER INPUTS:

float runSpeed = 200;  //mm per second, top speed during normal operation. User adjustable
int center = 547;      //Set center position
float sweep = 139.7;   //Define Distance belt should travel when spray is vertical, mm



int incomingData;

int stepsToGo;
byte direction = 1;

long maxSpeed = 4000;
long motorAccel = 2000;

int move_finished = 1;     //Used to check if the move is completed
long initial_homing = -1;  //Used to home stepper at startup

float pitch = 5.080;                  //gear pitch (mm)
float diameter = 19.25;               //Pulley Diameter
float pteeth = 10;                    //number of teeth on pulley
float circum = pitch * pteeth;        //circumference of pulley
int maxsteps = 200;                   //steps for full rotation of motor
float steppermm = maxsteps / circum;  // steps per millimeter of pulley


float steppersec = runSpeed * steppermm;
float secperstep = 1 / steppersec;

unsigned long curMicros;
unsigned long prevStepMicros = 0;
unsigned long slowMicrosBetweenSteps = 4500;  // microseconds
unsigned long fastMicrosBetweenSteps = secperstep * 1000000;
unsigned long stepIntervalMicros;
unsigned long stepAdjustmentMicros;
int numAccelSteps = 100;  // 100 is a half turn of a 200 step mmotor


int numSteps = sweep * steppermm;

int left_edge = numSteps / 2;



void setup() {

  Serial.begin(9600);


  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);


  pinMode(home_switch, INPUT_PULLUP);

  delay(5);

  //Homing Sequence:
  myStepper.setMaxSpeed(1000);      //Defines Max Speed of motor
  myStepper.setAcceleration(1000);  //Sets acceleration of motor, necessary when const speed not desired

  startUp();

  stepAdjustmentMicros = (slowMicrosBetweenSteps - fastMicrosBetweenSteps) / numAccelSteps;
  stepIntervalMicros = slowMicrosBetweenSteps;
  stepsToGo = numSteps;
  digitalWrite(directionPin, direction);
}

void loop() {

  while (!digitalRead(home_switch)) {
    moveMotor();
  }
  while (digitalRead(home_switch)) {
    myStepper.moveTo(initial_homing);
    myStepper.run();
    initial_homing++;
    delay(5);
  }
  myStepper.setCurrentPosition(0);

  shutDown();
}


void moveMotor() {
  if (Serial.available() > 0) {
    incomingData = Serial.read();
    analogWrite(runSpeed, incomingData);
    analogWrite(sweep, incomingData);
  }

  if (stepsToGo > 0) {
    if (micros() - prevStepMicros >= stepIntervalMicros) {
      prevStepMicros += stepIntervalMicros;
      singleStep();
      stepsToGo--;
      if (stepsToGo <= numAccelSteps) {
        if (stepIntervalMicros < slowMicrosBetweenSteps) {
          stepIntervalMicros += stepAdjustmentMicros;
        }
      } else {
        if (stepIntervalMicros > fastMicrosBetweenSteps) {
          stepIntervalMicros -= stepAdjustmentMicros;
        }
      }
    }
  } else {
    direction = !direction;
    digitalWrite(directionPin, direction);
    stepsToGo = numSteps;
    prevStepMicros = micros();
  }
}

void singleStep() {

  digitalWrite(stepPin, HIGH);
  digitalWrite(stepPin, LOW);
}

void startUp() {
  //Start Homing Procedure

  if (Serial.available()) {
    incomingData = Serial.read();
    analogWrite(center, incomingData);
  }

  while (digitalRead(home_switch)) {   //Make the Stepper move CW until the switch is activated
    myStepper.moveTo(initial_homing);  // Set the position to move to
    initial_homing--;                  //Decrease by 1 for the next move until switch is hit
    myStepper.run();                   //Start moving the stepper
    delay(5);
  }
  myStepper.setCurrentPosition(0);  //Set current position as 0 for now
  myStepper.setMaxSpeed(4000);
  myStepper.setAcceleration(1000);

  initial_homing = 1;

  while (!digitalRead(home_switch)) {  //Make Stepper move CCW until switch is deactivated

    myStepper.moveTo(initial_homing);
    myStepper.run();
    initial_homing++;
    delay(5);
  }
  myStepper.setCurrentPosition(0);

  myStepper.move(center);  //moves Stepper to center
  while ((myStepper.distanceToGo() != 0)) {
    myStepper.run();
    delay(5);
  }

  delay(1000);
  myStepper.setCurrentPosition(0);  //Sets center as 0 position

  myStepper.move(left_edge);  //moves Stepper to left edge of spray width
  while ((myStepper.distanceToGo() != 0)) {
    myStepper.run();
    delay(5);
  }
  myStepper.setCurrentPosition(0);  //Sets Left Edge as 0 position
  delay(1000);
}

void shutDown() {
  while (digitalRead(home_switch)) {   //Make the Stepper move CW until the switch is activated
    myStepper.moveTo(initial_homing);  // Set the position to move to
    initial_homing--;                  //Decrease by 1 for the next move until switch is hit
    myStepper.run();                   //Start moving the stepper
    delay(5);
  }
  myStepper.setCurrentPosition(0);  //Set current position as 0 for now
  myStepper.setMaxSpeed(4000);
  myStepper.setAcceleration(1000);

  initial_homing = 1;

  while (!digitalRead(home_switch)) {  //Make Stepper move CCW until switch is deactivated

    myStepper.moveTo(initial_homing);
    myStepper.run();
    initial_homing++;
    delay(5);
  }
  myStepper.setCurrentPosition(0);


  myStepper.move(225);  //moves Stepper off switch
  while ((myStepper.distanceToGo() != 0)) {
    myStepper.run();
    delay(5);
  }

  delay(1000);
  myStepper.setCurrentPosition(0);  //Sets center as 0 position

  myStepper.stop();
}


Processing Code:

import controlP5.*;
import processing.serial.*;
Serial port;
ControlP5 cp5;


//int sizeX = 700;
//int sizeY = 400;

int RunSpeed = 100;
int Sweep = 100;
int Center = 100;
Slider abc;

void setup() {
  size(700,600);
  port = new Serial(this, "COM6", 9600);
  noStroke();
  cp5 = new ControlP5(this);
  
  // add a horizontal sliders, the value of this slider will be linked
  // to variable 'sliderValue' 
  cp5.addSlider("RunSpeed")
     .setPosition(150,100)
     .setSize(400,20)
     .setRange(0,250)
     .setLabel("Run Speed (mm/sec)");
     ;

cp5.getController("RunSpeed").getCaptionLabel().align(ControlP5.CENTER, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);

  
  // create another slider with tick marks, now without
  // default value, the initial value will be set according to
  // the value of variable sliderTicks2 then.
  cp5.addSlider("Sweep")
     .setPosition(150,300)
     .setSize(400,20)
     .setRange(0,250)
     .setLabel("Sweep (mm)");
     ;
     
     cp5.getController("Sweep").getCaptionLabel().align(ControlP5.CENTER, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);
     
     
  cp5.addSlider("Center")
     .setPosition(150,500)
     .setSize(400, 20)
     .setRange(255,0) // values can range from big to small as well
     .setLabel("Center Position");
     ;
     cp5.getController("Center").getCaptionLabel().align(ControlP5.CENTER, ControlP5.BOTTOM_OUTSIDE).setPaddingX(0);


}

void draw() {
  background(Sweep);

  fill(RunSpeed);
  rect(0,0,width,200);
  
  fill(Sweep);
  rect(0,200,width,200);
  
  fill(Center);
  rect(0,400,width,200);
}



void RunSpeed(int RunSpeed){
  port.write(RunSpeed);
}

void Sweep(int Sweep){
  port.write(Sweep);
}

void Center(int Center){
  port.write(Center);
}


so you read one byte and automagically it becomes both the speed and sweep?

I would suggest to study Serial Input Basics to handle this and think about how you send stuff from Processing over.

Thank you, I will take a look

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