Arduino write data - serial

Hello,

Can someone help me with processing serial code.
I have a txt file with gcode, what I need is to open that file,
( for example positions.txt )
read line by line ( array ) and using timer ( delay ) send
line by line to arduino.
I have searched forum but I didn’t find something that can help me.

gcode txt file looks like this

1,0,-60,-109,0,160,100,500,500,0
1,0,-60,-109,-97,160,100,500,500,0
1,0,44,38,100,120,100,500,500,0
1,0,4,100,-143,120,100,500,500,0
1,0,-48,0,0,100,100,500,500,0
1,1,-48,0,0,100,100,500,500,0

And what code have you got already?

Your task breaks down into several parts - even you’ve described them!

First you will need to read the data from the file. You can do this using readStrings().

Then you want to loop over all the data line by line. You can do this with a for loop.

For each line of data, you probably want to split it into numbers. You can use the split() function to do this.

Finally, you will want to write the numbers to a serial port. You probably don’t want to use the delay() function! Instead, you will probably want to use millis(), or a check to see if your serial port is ready for more data.


Develop your code one step at a time.
Start with the step that reads the data from the file.
Make sure you have the data read correctly before moving on!

Or maybe you already have the data being read and parsed properly? WE CAN’T TELL BECAUSE YOU HAVEN’T POSTED ANY CODE. Show us what you already have working so we can help you specifically with the parts that AREN’T working.

You did not search hard enough.

The Processing website has resources (tutorials, references and examples) as well.

I would start with reading the text file and extracting a line as a string.
Check out the data tutorial and take a look at the related references.

Then decide how you want to send the data.
Check out the serial library and related references.

Fist thing that comes to mind is:
loadStrings()
serial.write()

You can write an entire string (check out the serial library) and receive it with the Arduino, parse it and convert the data back to integers (in this case). There are other ways to do this as well.

Do you already have Arduino code to receive this? You will have to send the data from Processing in a format that it will understand.

And your journey begins…

:)

This is my code

import processing.serial.*;
Serial myPort;
String aString = "HOMING_DONE";
String bString = "POSITION_REACHED_OK";
String testString;
String inPort;

void setup()
{
  println("Setup() is running........");
  println("Arduino found on Port: "+Serial.list());

  println("Serial Port Assigning Started........");
  myPort = new Serial(this , Serial.list()[0] , 115200);
  println("Serial Port Assigning Ended........OK");
 
  myPort.clear();
}

void draw() {
  
}

void serialEvent(Serial p) 
  {
  inPort = p.readStringUntil('\n');
  if(inPort != null) //this check is the key to making code in draw work
    {
    testString = inPort.trim();
    print(testString);  
    if(testString.equals(aString) == true)
      {
      println(" <-- COMMAND_FOUND_OK");
      // now send first line from txt file in format like  ( 0,0,0,0,0,100,100,500,500,0 )
      //myPort.write("0,0,0,0,0,100,100,500,500,0");
      //wait for bString = "POSITION_REACHED_OK" and then next line  ( repeat process until last line )
      }
    
    else if(testString.equals(bString) == true)
    {
      //problem is -> as soon I start code, this bString comes up ( I need to wait first for aString 
      // and then before sending each line need to wait for bString. 
    println(" <-- READY_TO_SEND");
    }
    
    else
    {
      println(" <-- CHECKING...");
    }
  }
}

and here is console output

Setup() is running…
Arduino found on Port: [Ljava.lang.String;@417b5e46
Serial Port Assigning Started…
Serial Port Assigning Ended…OK
POSITED_OK ← CHECKING…
POSITION_REACHED_OK ← READY_TO_SEND
HOMING_START ← CHECKING…
Z_HOME_OK ← CHECKING…
J3_HOME_OK ← CHECKING…
J2_HOME_OK ← CHECKING…
HOMING_DONE ← COMMAND_FOUND_OK
POSITION_REACHED_OK ← READY_TO_SEND
POSITION_REACHED_OK ← READY_TO_SEND
POSITION_REACHED_OK ← READY_TO_SEND
POSITION_REACHED_OK ← READY_TO_SEND
POSITION_REACHED_OK ← READY_TO_SEND
POSITION_REACHED_OK ← READY_TO_SEND

console

Hi @HITman, I think you need to post your Arduino code as well. Can we confirm something re serial ports? How many serial devices are there? and Serial.list[0] finds the right one? Look in device manager and try these 2 lines instead of your 1 line.

  print("Arduino found on Port:");
  println(Serial.list());

The code you have prints gobledegoop and assumes the one Ard is the only serial device. I prefer to name the device I want: (and keep to 9600 everywhere until you need more speed.)

new Serial(this , "COM1", 9600);

What Arduino are you using? It’s good to have other output from the Ard to help you see what’s going on. Do you have ttl-to-usb adaptor? lcd/oled screen?

Keep to a strict sequence. Processing sketch stopped. Connect Arduino (if CH340 use the same usb socket each time.) Start and stop Processing sketch as many times as you like.

It’s arduino uno with cnc shield.
There is nothing wrong with serial communication.
I have modified arduino sketch so now is ok from start ( no more POSITION_REACHED_OK on start )

I need to send now line by line gcode from txt file and wait untill position is reached before sending next line

here is arduino sketch

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

#define limitSwitch1 11
#define limitSwitch2 10
#define limitSwitch3 9
#define limitSwitch4 A3

// 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);

Servo gripperServo;  // create servo object to control a servo
// enablePIN
const byte enablePin = 8;

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 gripperArray[100];
int positionsCounter = 0;

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

  //enable motors
  pinMode(enablePin, OUTPUT);
  digitalWrite(enablePin, LOW);
  

  pinMode(limitSwitch1, INPUT_PULLUP);
  pinMode(limitSwitch2, INPUT_PULLUP);
  pinMode(limitSwitch3, INPUT_PULLUP);
  pinMode(limitSwitch4, INPUT_PULLUP);

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

  gripperServo.attach(A0, 600, 2500);
  // initial servo value - open gripper
  data[6] = 100;   //180
  gripperServo.write(data[6]);
  delay(1000);
  data[5] = 100;   //100
  homing();
}

void homing() {
  
  while (digitalRead(limitSwitch4) != 1) {
    stepper4.setSpeed(500);   //1500  Z
    stepper4.runSpeed();
    stepper4.setCurrentPosition(17000); // When limit switch pressed set position to 0 steps
  }
  delay(20);
  stepper4.moveTo(10000);
  while (stepper4.currentPosition() != 10000) {
    
    stepper4.run();
  }
  
  Serial.println("Z_HOME_OK");
  Serial.flush();
  
  // Homing Stepper3
  while (digitalRead(limitSwitch3) != 1) {
    stepper3.setSpeed(-500);   //-1100   J3
    stepper3.runSpeed();
    stepper3.setCurrentPosition(-1680); // When limit switch pressed set position to 0 steps  (-1662)
  }
  delay(20);

  stepper3.moveTo(0);
  while (stepper3.currentPosition() != 0) {
    
    stepper3.run();
  }

   Serial.println("J3_HOME_OK");
   Serial.flush();
 
  // Homing Stepper2
  while (digitalRead(limitSwitch2) != 1) {
    stepper2.setSpeed(-800);   //-1300 J2
    stepper2.runSpeed();
    stepper2.setCurrentPosition(-5650); // When limit switch pressed set position to -5440 steps  (-5420)
  }
  delay(20);

  stepper2.moveTo(0);
  while (stepper2.currentPosition() != 0) {
    
    stepper2.run();
  }

   Serial.println("J2_HOME_OK");
   Serial.flush();

  // Homing Stepper1
  while (digitalRead(limitSwitch1) != 1) {
    stepper1.setSpeed(-500);   //-1200   J1
    stepper1.runSpeed();
    stepper1.setCurrentPosition(-3600); // When limit switch pressed set position to 0 steps  (-3955)
  }
  delay(20);
  
  stepper1.moveTo(0);
  while (stepper1.currentPosition() != 0) {
    
    stepper1.run();
    //stepper1.disableOutputs();
    
  }
  //Serial.println("J1_HOME_OK");
   Serial.println("HOMING_DONE");
   Serial.flush();
}

void loop() {

  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++) {    //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
    }
    /*
     data[0] - SAVE button status
     data[1] - RUN button status
     data[2] - Joint 1 angle
     data[3] - Joint 2 angle
     data[4] - Joint 3 angle
     data[5] - Z position
     data[6] - Gripper value
     data[7] - Speed value
     data[8] - Acceleration value
     data[9] - Disable stepper
     data[10] - Homing
    */
    // If SAVE button is pressed, store the data into the appropriate arrays
    if (data[0] == 1) {
      theta1Array[positionsCounter] = data[2] * theta1AngleToSteps; //store the values in steps = angles * angleToSteps variable
      theta2Array[positionsCounter] = data[3] * theta2AngleToSteps;
      phiArray[positionsCounter] = data[4] * phiAngleToSteps;
      zArray[positionsCounter] = data[5] * zDistanceToSteps;
      gripperArray[positionsCounter] = data[6];
      positionsCounter++;
      Serial.println("POSITION_SAVED_OK");
      Serial.flush();
    }
    // Clear data
    if (data[0] == 2) {
      // Clear the array data to 0
      memset(theta1Array, 0, sizeof(theta1Array));
      memset(theta2Array, 0, sizeof(theta2Array));
      memset(phiArray, 0, sizeof(phiArray));
      memset(zArray, 0, sizeof(zArray));
      memset(gripperArray, 0, sizeof(gripperArray));
      positionsCounter = 0;
      Serial.println("DATA_ERASED");
      Serial.flush();
    }
  }

  // Enable/Disable Stepper Motors
    if (data[9] == 1) {
      digitalWrite(enablePin, HIGH);
      //Motors OFF
        }
         else{
           digitalWrite(enablePin, LOW);
             //Motors ON
        }

  
  // If RUN button is pressed
  while (data[1] == 1) {
    Serial.println("AUTO_RUN_ON_POSITION_X_START");
    Serial.flush();
    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]);

    // execute the stored steps
    for (int i = 0; i <= positionsCounter - 1; i++) {
      if (data[1] == 0) {
        //Serial.println("AUTO_RUN_OFF_1");
        break;
      }
      stepper1.moveTo(theta1Array[i]);
      
      stepper2.moveTo(theta2Array[i]);
      
      stepper3.moveTo(phiArray[i]);
      
      stepper4.moveTo(zArray[i]);
      
      while (stepper1.currentPosition() != theta1Array[i] || stepper2.currentPosition() != theta2Array[i] || stepper3.currentPosition() != phiArray[i] || stepper4.currentPosition() != zArray[i]) {
        stepper1.run();
        stepper2.run();
        stepper3.run();
        stepper4.run();
      }
      if (i == 0) {
        gripperServo.write(gripperArray[i]);
      }
      else if (gripperArray[i] != gripperArray[i - 1]) {
        
        gripperServo.write(gripperArray[i]);
        
        delay(800); // wait 0.8 sec for the servo to grab or drop - the servo is slow
        //Serial.println("AUTO_MODE_ON");
        Serial.flush();
      }

      //Check for change in speed and acceleration or program stop
      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
        }

        if (data[1] == 0) {
          Serial.println("AUTO_RUN_OFF");
          break;
        }
        // change speed and acceleration while running the program
        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]);
      }
    }
    /*
      // execute the stored steps in reverse
      for (int i = positionsCounter - 2; i >= 0; i--) {
      if (data[1] == 0) {
        break;
      }
      stepper1.moveTo(theta1Array[i]);
      stepper2.moveTo(theta2Array[i]);
      stepper3.moveTo(phiArray[i]);
      stepper4.moveTo(zArray[i]);
      while (stepper1.currentPosition() != theta1Array[i] || stepper2.currentPosition() != theta2Array[i] || stepper3.currentPosition() != phiArray[i] || stepper4.currentPosition() != zArray[i]) {
        stepper1.run();
        stepper2.run();
        stepper3.run();
        stepper4.run();
      }
      gripperServo.write(gripperArray[i]);

      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
        }
        if (data[1] == 0) {
          break;
        }
      }
      }
    */
  Serial.println("AUTO_RUN_ON_POSITION_X_DONE");
  Serial.flush();
  }

  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();
  }
  delay(500);   //100
  gripperServo.write(data[6]);
  delay(500);   //300
  Serial.println("POSITION_REACHED_OK");
  Serial.flush();
}

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

here is now console output

Setup() is running........
Arduino found on Port: [Ljava.lang.String;@19ff7cf8
Serial Port Assigning Started........
Serial Port Assigning Ended........OK
ControlP5 2.2.6 infos, comments, questions at http://www.sojamo.de/libraries/controlP5
Z_HOME_OK <-- CHECKING...
J3_HOME_OK <-- CHECKING...
J2_HOME_OK <-- CHECKING...
HOMING_DONE <-- COMMAND_FOUND_OK
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND
POSITION_REACHED_OK <-- READY_TO_SEND

Looks like you are almost there?

Above Processing setup, declare an array of Strings, and an int to keep track of which one you’ve sent.
In your Processing setup(), copy in the loadStrings example, and load your file into that array.
In draw() where you detect ‘position_reached_ok’ write one of the array strings to the Ard.

Does that do it?

I took the simple example from the data tutorial and was able to send the strings to the Arduino.
I sent the string received by the Arduino back to Processing to display it; I usually have a second serial port to monitor data but it (serial to USB adaptor) was not available at the moment.

It helps to be able to monitor the data received on the Arduino.

  • another serial port with a USB to serial adaptor
  • LCD
  • network
  • other

Note:
I did add a myPort.write('\n'); to terminate the string on the Processing side.
Arduino side:
Serial.readStringUntil() - Arduino Reference

Have fun!

:)

chick this