Help Combining 2-Two Working Codes (Arduino+Processing)

Hello, I have 2-Two separate codes and I am having difficulty combining them. Maybe someone could pinpoit me into a right direction. General idea is to control 4-Nema 17 Stepper Motors and 1-Servo using Arduino Uno+CNC Shield, etc. Both arduino codes and processing codes work individually. Already tested. Hardware is no issue either.

1st Arduino Code (4 Steppers):

*/
#include <AccelStepper.h>
#include <Servo.h>
#include <math.h>


// Define the stepper motors and the pins the will use
AccelStepper stepper1(1, 2, 5); // (Type:driver, STEP, DIR)
AccelStepper stepper2(1, 3, 6);
AccelStepper stepper3(1, 4, 7);
AccelStepper stepper4(1, 12, 13);


double x = 10.0;
double y = 10.0;
double L1 = 228; // L1 = 228mm
double L2 = 136.5; // L2 = 136.5mm
double theta1, theta2, phi, z;

int stepper1Position, stepper2Position, stepper3Position, stepper4Position;

const float theta1AngleToSteps = 44.444444;
const float theta2AngleToSteps = 35.555555;
const float phiAngleToSteps = 10;
const float zDistanceToSteps = 100;

byte inputValue[5];
int k = 0;

String content = "";
int data[10];

int theta1Array[100];
int theta2Array[100];
int phiArray[100];
int zArray[100];
int positionsCounter = 0;

void setup() {
  Serial.begin(115200);

  // Stepper motors max speed
  stepper1.setMaxSpeed(4000);
  stepper1.setAcceleration(2000);
  stepper2.setMaxSpeed(4000);
  stepper2.setAcceleration(2000);
  stepper3.setMaxSpeed(4000);
  stepper3.setAcceleration(2000);
  stepper4.setMaxSpeed(4000);
  stepper4.setAcceleration(2000);

  data[5] = 0;

}

void loop() {
    static int v = 0;

  if (Serial.available()) {
    content = Serial.readString(); // Read the incomding data from Processing
    // Extract the data from the string and put into separate integer variables (data[] array)
    for (int i = 0; i < 10; i++) {
      int index = content.indexOf(","); // locate the first ","
      data[i] = atol(content.substring(0, index).c_str()); //Extract the number from start to the ","
      content = content.substring(index + 1); //Remove the number from the string
    }
   
    
  stepper1Position = data[2] * theta1AngleToSteps;
  stepper2Position = data[3] * theta2AngleToSteps;
  stepper3Position = data[4] * phiAngleToSteps;
  stepper4Position = data[5] * zDistanceToSteps;

  stepper1.setSpeed(data[7]);
  stepper2.setSpeed(data[7]);
  stepper3.setSpeed(data[7]);
  stepper4.setSpeed(data[7]);

  stepper1.setAcceleration(data[8]);
  stepper2.setAcceleration(data[8]);
  stepper3.setAcceleration(data[8]);
  stepper4.setAcceleration(data[8]);

  stepper1.moveTo(stepper1Position);
  stepper2.moveTo(stepper2Position);
  stepper3.moveTo(stepper3Position);
  stepper4.moveTo(stepper4Position);

  while (stepper1.currentPosition() != stepper1Position || stepper2.currentPosition() != stepper2Position || stepper3.currentPosition() != stepper3Position || stepper4.currentPosition() != stepper4Position) 
  {
    stepper1.run();
    stepper2.run();
    stepper3.run();
    stepper4.run();
  }
  
    }
    }
      

void serialFlush() {
  while (Serial.available() > 0) {  //while there are characters in the serial buffer, because Serial.available is >0
    Serial.read();         // get one character
  }
}

 /*
    
    
     data[2] - Joint 1 angle
     data[3] - Joint 2 angle
     data[4] - Joint 3 angle
     data[5] - Z position
     data[7] - Speed value
     data[8] - Acceleration value
    */

1st Processing Code (4 Steppers):

//Processing Code:
import processing.serial.*;
import controlP5.*; 
import static processing.core.PApplet.*;

Serial myPort;
ControlP5 cp5; // controlP5 object

int j1Slider = 0;
int j2Slider = 0;
int j3Slider = 0;
int zSlider = 0;
int j1JogValue = 0;
int j2JogValue = 0;
int j3JogValue = 0;
int zJogValue = 0;
int speedSlider = 500;
int accelerationSlider = 500;
int positionsCounter = 0;

int saveStatus = 0;
int runStatus = 0;

int slider1Previous = 0;
int slider2Previous = 0;
int slider3Previous = 0;
int sliderzPrevious = 100;
int speedSliderPrevious = 500;
int accelerationSliderPrevious = 500;

boolean activeIK = false;

int xP=0;
int yP=0;
int zP=0;
float L1 = 228; // L1 = 228mm
float L2 = 136.5; // L2 = 136.5mm
float theta1, theta2, phi, z;

String[] positions = new String[100];

String data;

void setup() {

  size(900, 900);
  myPort = new Serial(this, "COM6", 115200);
  cp5 = new ControlP5(this);

  PFont pfont = createFont("Arial", 25, true); // use true/false for smooth/no-smooth
  ControlFont font = new ControlFont(pfont, 22);
  ControlFont font2 = new ControlFont(pfont, 25);

  //J1 controls
  cp5.addSlider("j1Slider")
    .setPosition(80, 222)
    .setSize(270, 30)
    .setRange(-90, 266) // Slider range, corresponds to Joint 1 or theta1 angle that the robot can move to
    .setColorLabel(#3269c2)
    .setFont(font)
    .setCaptionLabel("")
    ;
  cp5.addButton("j1JogMinus")
    .setPosition(80, 275)
    .setSize(90, 40)
    .setFont(font)
    .setCaptionLabel("JOG-")
    ;
  cp5.addButton("j1JogPlus")
    .setPosition(260, 275)
    .setSize(90, 40)
    .setFont(font)
    .setCaptionLabel("JOG+")
    ;
  cp5.addNumberbox("j1JogValue")
    .setPosition(190, 275)
    .setSize(50, 30)
    .setRange(0, 20)
    .setFont(font)
    .setMultiplier(0.1)
    .setValue(1)
    .setDirection(Controller.HORIZONTAL) // change the control direction to left/right
    .setCaptionLabel("")
    ;

  //J2 controls
  cp5.addSlider("j2Slider")
    .setPosition(80, 400)
    .setSize(270, 30)
    .setRange(-150, 150)
    .setColorLabel(#3269c2)
    .setFont(font)
    .setCaptionLabel("")
    ;
  cp5.addButton("j2JogMinus")
    .setPosition(80, 450)
    .setSize(90, 40)
    .setFont(font)
    .setCaptionLabel("JOG-")
    ;
  cp5.addButton("j2JogPlus")
    .setPosition(260, 450)
    .setSize(90, 40)
    .setFont(font)
    .setCaptionLabel("JOG+")
    ;
  cp5.addNumberbox("j2JogValue")
    .setPosition(190, 450)
    .setSize(50, 30)
    .setRange(0, 20)
    .setFont(font)
    .setMultiplier(0.1)
    .setValue(1)
    .setDirection(Controller.HORIZONTAL) // change the control direction to left/right
    .setCaptionLabel("")
    ;
  //J3 controls
  cp5.addSlider("j3Slider")
    .setPosition(80, 575)
    .setSize(270, 30)
    .setRange(-162, 162)
    .setColorLabel(#3269c2)
    .setFont(font)
    .setCaptionLabel("")
    ;
  cp5.addButton("j3JogMinus")
    .setPosition(80, 625)
    .setSize(90, 40)
    .setFont(font)
    .setCaptionLabel("JOG-")
    ;
  cp5.addButton("j3JogPlus")
    .setPosition(260, 625)
    .setSize(90, 40)
    .setFont(font)
    .setCaptionLabel("JOG+")
    ;
  cp5.addNumberbox("j3JogValue")
    .setPosition(190, 625)
    .setSize(50, 30)
    .setRange(0, 20)
    .setFont(font)
    .setMultiplier(0.1)
    .setValue(1)
    .setDirection(Controller.HORIZONTAL) // change the control direction to left/right
    .setCaptionLabel("")
    ;

  //Z controls
  cp5.addSlider("zSlider")
    .setPosition(80, 750)
    .setSize(270, 30)
    .setRange(-150, 150)
    .setColorLabel(#3269c2)
    .setFont(font)
    .setCaptionLabel("")
    ;
  cp5.addButton("zJogMinus")
    .setPosition(80, 800)
    .setSize(90, 40)
    .setFont(font)
    .setCaptionLabel("JOG-")
    ;
  cp5.addButton("zJogPlus")
    .setPosition(260, 800)
    .setSize(90, 40)
    .setFont(font)
    .setCaptionLabel("JOG+")
    ;
  cp5.addNumberbox("zJogValue")
    .setPosition(190, 800)
    .setSize(50, 30)
    .setRange(0, 20)
    .setFont(font)
    .setMultiplier(0.1)
    .setValue(1)
    .setDirection(Controller.HORIZONTAL) // change the control direction to left/right
    .setCaptionLabel("")
    ;


  cp5.addTextfield("xTextfield")
    .setPosition(460, 340)
    .setSize(70, 40)
    .setFont(font)
    .setColor(255)
    .setCaptionLabel("")
    ;
  cp5.addTextfield("yTextfield")
    .setPosition(610, 340)
    .setSize(70, 40)
    .setFont(font)
    .setColor(255)
    .setCaptionLabel("")
    ;
  cp5.addTextfield("zTextfield")
    .setPosition(760, 340)
    .setSize(70, 40)
    .setFont(font)
    .setColor(255)
    .setCaptionLabel("")
    ;

  //Z controls
  cp5.addSlider("speedSlider")
    .setPosition(450, 550)
    .setSize(180, 30)
    .setRange(500, 4000)
    .setColorLabel(#3269c2)
    .setFont(font)
    .setCaptionLabel("")
    ;

  cp5.addSlider("accelerationSlider")
    .setPosition(675, 550)
    .setSize(180, 30)
    .setRange(500, 4000)
    .setColorLabel(#3269c2)
    .setFont(font)
    .setCaptionLabel("")
    ;
    
  //Servo Slider
   cp5.addSlider("Tilt")
  .setPosition(500,200)
  .setSize(300,30)
  .setRange(-180,180)
  .setValue(0)
  ;

}

void draw() { 
  background(#F2F2F2); // background black
  textSize(35);
  fill(33);
  text("Stepper Control", 85, 150); 
  text("Servo Control", 550, 150); 
  text("Location", 580, 320);
  text("Speed Control", 540, 490); 
  textSize(40);
  text("USER INTERFACE", 330, 60); 
  textSize(22);
  text("Stepper #1  (Base-Axis)", 60, 210); 
  text("Stepper #2  (Arm-Axis)", 60, 385);
  text("Stepper #3  (Gripper Axis)", 60, 560);
  text("Stepper #4 (Z-Axis)", 60, 735);
  textSize(22);
  text("Velocity", 500, 535);
  text("Acceleration", 700, 535);

  //println("PREV: "+accelerationSlider);
  fill(speedSlider);
  fill(accelerationSlider);
  fill(j1Slider);
  fill(j2Slider);
  fill(j3Slider);
  fill(zSlider);
  fill(j1JogValue);
  fill(j2JogValue);
  fill(j3JogValue);
  fill(zJogValue);


  updateData();



  saveStatus=0; // keep savePosition variable 0 or false. See, when button SAVE pressed it makes the value 1, which indicates to store the value in the arduino code

  // If slider moved, calculate new position of X,Y and Z with forward kinematics
  if (slider1Previous != j1Slider) {
    if (activeIK == false) {     // Check whether the inverseKinematics mode is active, Executre Forward kinematics only if inverseKinematics mode is off or false
      theta1 = round(cp5.getController("j1Slider").getValue()); // get the value from the slider1
      theta2 = round(cp5.getController("j2Slider").getValue());
      forwardKinematics();
      myPort.write(data);
    }
  }
  slider1Previous = j1Slider;

  if (slider2Previous != j2Slider) {
    if (activeIK == false) {     // Check whether the inverseKinematics mode is active, Executre Forward kinematics only if inverseKinematics mode is off or false
      theta1 = round(cp5.getController("j1Slider").getValue()); // get the value from the slider1
      theta2 = round(cp5.getController("j2Slider").getValue());
      forwardKinematics();
      myPort.write(data);
    }
  }
  slider2Previous = j2Slider;

  if (slider3Previous != j3Slider) {
    if (activeIK == false) {     // Check whether the inverseKinematics mode is active, Executre Forward kinematics only if inverseKinematics mode is off or false
      theta1 = round(cp5.getController("j1Slider").getValue()); // get the value from the slider1
      theta2 = round(cp5.getController("j2Slider").getValue());
      forwardKinematics();
      myPort.write(data);
    }
  }
  slider3Previous = j3Slider;

  if (sliderzPrevious != zSlider) {
    if (activeIK == false) {     // Check whether the inverseKinematics mode is active, Executre Forward kinematics only if inverseKinematics mode is off or false
      zP = round(cp5.getController("zSlider").getValue());
      updateData();
      println(data);
      myPort.write(data);
    }
  }
  sliderzPrevious = zSlider;
  activeIK = false; // deactivate inverseKinematics so the above if statements can be executed the next interation

  fill(33);
  textSize(32);
  text("X: ", 460, 420);
  text(xP, 513, 420);
  text("Y: ", 610, 420);
  text(yP, 665, 420);
  text("Z: ", 760, 420);
  text(zP, 815, 420);
  textSize(26);
  textSize(18);


} //END VOID DRAW

 // FORWARD KINEMATICS
void forwardKinematics() {
  float theta1F = theta1 * PI / 180;   // degrees to radians
  float theta2F = theta2 * PI / 180;
  xP = round(L1 * cos(theta1F) + L2 * cos(theta1F + theta2F));
  yP = round(L1 * sin(theta1F) + L2 * sin(theta1F + theta2F));
}

void controlEvent(ControlEvent theEvent) {  

  if (theEvent.isController()) { 
    println(theEvent.getController().getName());
  }
}

public void j1JogMinus() {
  int a = round(cp5.getController("j1Slider").getValue());
  a=a-j1JogValue;
  cp5.getController("j1Slider").setValue(a);
}
//J1 control
public void j1JogPlus() {
  int a = round(cp5.getController("j1Slider").getValue());
  a=a+j1JogValue;
  cp5.getController("j1Slider").setValue(a);
}
//J2 control
public void j2JogMinus() {
  int a = round(cp5.getController("j2Slider").getValue());
  a=a-j2JogValue;
  cp5.getController("j2Slider").setValue(a);
}
public void j2JogPlus() {
  int a = round(cp5.getController("j2Slider").getValue());
  a=a+j2JogValue;
  cp5.getController("j2Slider").setValue(a);
}
//J3 control
public void j3JogMinus() {
  int a = round(cp5.getController("j3Slider").getValue());
  a=a-j3JogValue;
  cp5.getController("j3Slider").setValue(a);
}
public void j3JogPlus() {
  int a = round(cp5.getController("j3Slider").getValue());
  a=a+j3JogValue;
  cp5.getController("j3Slider").setValue(a);
}
//J3 control
public void zJogMinus() {
  int a = round(cp5.getController("zSlider").getValue());
  a=a-zJogValue;
  cp5.getController("zSlider").setValue(a);
}
public void zJogPlus() {
  int a = round(cp5.getController("zSlider").getValue());
  a=a+zJogValue;
  ;
  cp5.getController("zSlider").setValue(a);
}


public void updateData() {
  data = str(saveStatus)
    +","+str(runStatus)
    +","+str(round(cp5.getController("j1Slider").getValue())) 
    +","+str(round(cp5.getController("j2Slider").getValue()))
    +","+str(round(cp5.getController("j3Slider").getValue()))
    +","+str(round(cp5.getController("zSlider").getValue()))
    +","+str(speedSlider)
    +","+str(accelerationSlider);
}

2nd Arduino Code (Servo):

#include <Servo.h>
Servo servo1;

void setup()
{
  servo1.attach(A0);  //The Tilt servo is attached to pin 9.
  Serial.begin(115200);  //Set up a serial connection for 57600 bps.
  Serial.println("Ready");
}


void loop() {
  static int v = 0;

  if (Serial.available()){
    
    char ch = Serial.read();

    switch (ch) {
      case '0'...'9':
        v = v * 10 + ch - '0';
        break;

      case 'a':
        servo1.write(v);
        Serial.println(v);
        v = 0;
        break; }
  }
}

2nd Processing Code (Servo):

//Processing code:
import processing.serial.*;       
import controlP5.*;

ControlP5 cp5;

int tilt = 1;

Serial myPort;

void setup()  {
  size(500, 250);
  myPort = new Serial(this, "COM6", 115200);
  cp5 = new ControlP5(this);

cp5.addSlider("pan")
.setPosition(50,70)
.setSize(300,30)
.setRange(0,180)
.setValue(158)
;

cp5.addSlider("tilt")
.setPosition(50,130)
.setSize(300,30)
.setRange(0,180)
.setValue(158)
;
}

void draw()  {
myPort.write("a"+tilt);
}

"import" ???

Show us what you have tried and what problems you get.

To give you an impression what kind of information is needed I will post a first answer:

"Check if there are colliding IO-port-numbers or colliding variable-names"

"define the combination how the exchanged data shall be look like and make sure that the receiving side is able to devide the data in the right way"

"combine the initialisations of setup"

"combine the interactions of loop"

I'm pretty sure such a short text does not help much.

You are the one that wants help. So help your potential helpers by providing all the information you can give

You are working on an informatic project and what is most needed in an informatic project is information imagine: do the other users here in the forum have a clear picture of what you are trying to do and what your knowledge is?

it is good that you posted the all source-codes that are involved in your project but you should add a normal-word description what the code does. Without a normal words-description you force your potential helpers to analyse the code on a very deep detail-level and to conclude from there what the code is doing.

I haven't done anything with processing yet. I don't know how many Arduino-Users here have experience and knowledge about the software processing.

The software processing is sending a data over the serial interface to your microcontroller. You should provide an example-string how this data is looking like.
For the stepper-motors and for the servo.

You should give an overview about the project you want to do. It looks like you want to control a robot-arm which has 4 stepper-motors and a RC-servo for the gripper.

but

the more assumptions your potential helpers make without knowing if the assumptions are right the more the suggested solution might not fit to your project!

I'm unsure what should I assume about you:

  • lazy guy that has almost no experience in programming and wants somebody else to do his (school) work

  • newcomer pretty young and therefore naturally unexperienced in how to do such a task starting to ask for guidance and help. Beeing even unexperienced how to ask

It is totally OK to be a real newcomer. You can ask any super-basic question that you like.
If you show some own effort in walking up the learning-curve you will receive answers

So I second what user SteveMann said:
"Show us what you have tried and what problems you get"
or if you are completely stumped on where to start any kind of a specific question

best regards Stefan

Hi, @matt1330

Does that mean the Servo Arduino code and the Processing Servo code work together as expected.
And
Stepper Arduino code and Processing Stepper code work together as expected.
And
That when you try and combine them all to one project you have problems?

If so what are the problems?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Hi, TomGeorge. Thank you for response. That is exactly the case. Individually when ran, they work as they should. I am new to this and I already tried couple of ways into combining them, but when I do nothing is working. I do understand that the issue is because each of the code has a different way of reading and sending data between arduino and processing. Also, I would rather have to use one arduino instead of two arduinos to have this working. So, any help showing how to combine these is greatly appreciated.

There are a few basic things that you can do yourself
https://www.google.de/search?as_q=arduino+combining+sketches

As soon as you post your first attempt how you tried to combine your two codes answers will rush in.

Your generalised sentence

is very general and in combination with after you have been asked twice to post your code and describing the problems you encounter and you refused to post your code and asking specific questions
this it could be interpreted as:
"can somebody do the work for me"?

nobody here will write down a 100 pages tutorial for you to cover all eventualities that might be a problem to understand for you.
But you will receive even more than 300 answers if you ask specific questions.

Take a look at the thread-overview. Some threads have more than 300 postings.
I estimate after 30 to 50 postings your job will be done but if it shuld requiere more the community is here
best regards Stefan