ASTM D6862 Peel Test Machine. Using Arduino for load cell and stepper motor

First much thanks for anyone willing to give me some general guidance.

I am trying to make an ASTM D6862 peel test machine. I am a machinist an therefore have completed the hardware design and fabricated the physical machine. Now I am working on the programming.

I need to control a stepper motor which will drive the physical "peeling" of the test samples via a ballscrew while simultaneously reporting back the force measured by the load cell.

I have successfully controlled the stepper using the accelstepper library. I can set a "speed" and therefore run the linear motion actuator at a specified rate.

I have also successfully measured the force using a load cell amp and load cell.

What an ASTM D6862 requires is a plot of the load vs distance (I can calculate the distance using steps and pitch of the lead-screw). I figure i can derive a plot using MS excel easily so really what I need is a CSV file of the force at each step (or the force at every 50 or 100 steps).

The issue I am having is that when I serial print out the force and number of steps the stepper motor cuts out. I believe that this is because it takes too long to measure the force from the load cell amp and also print out the number of steps thus causing a delay of the actually driving of the stepper.

I now think I may need to use two micro controllers. One to drive the stepper and one to measure the force but I am unsure how I could ensure that the force being measured was in sync with the number of steps.

Any general advice is greatly appreciated!

Must be in the code you didn't think was important. If you are using a stepper motor controller and it is running properly, as you stated, then we can eliminate that as a source of the problem.

That indicates something in your Serial print/write code. How many time do you have a loop that takes a long time to exit? Do you have delays?

Paul

How much data is being written each time? At what baud rate?

Well as soon as I read "baud rate" I realized that was my glitch. I set the baud to 20000000 and it fixed the delay issues.

Now on to other issues. I cannot set an acceleration for some reason. See my code below with comments. Also I think there is a better way to only print steps and force at every 1000 steps.

Thanks

// chad herrick peel test prelim code

#include <AccelStepper.h>

#include "HX711.h"

#define DOUT 4
#define CLK 5

HX711 scale(DOUT, CLK);

float calibration_factor = -7050; //-7050 worked for my 440lb max scale setup

AccelStepper stepper(1,2,3);
int sign = 1; // Either 1, 0 or -1
int spd = 1000; // The current speed in steps/second
int x = 0;
int y = 0;

void setup()
{
Serial.begin(2000000);
stepper.setMaxSpeed(5000);
stepper.setSpeed(10000);
stepper.setCurrentPosition(0);
stepper.setAcceleration(50);

scale.set_scale();
scale.tare(); //Reset the scale to 0

long zero_factor = scale.read_average(); //Get a baseline reading
Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
Serial.println(zero_factor);

}

void loop()
{
char c;
if(Serial.available()) {
c = Serial.read();
if (c == 'f') { // forward
sign = 1;
}
if (c == 'r') { // reverse
sign = -1;
}
if (c == 's') { // stop
sign = 0;
}
if (c == '1') { // super slow
spd = 10;
}
if (c == '2') { // medium
spd = 1000;
}
if (c == '3') { // fast
spd = 5000;
}
stepper.setSpeed(sign * spd);
}
stepper.setAcceleration(50);// for some reason the acceleration is not working
stepper.runSpeed();

x=stepper.currentPosition();
if (x > abs(y+1000)) { //read steps and force at every 1000 steps, serial print. This only works in the positive direction.
Serial.print(x);
Serial.println(" ");
Serial.print("Reading: ");
Serial.print(scale.get_units()*-1, 1);
Serial.println();
y=x ;
}
}

According to the accelstepper reference runSpeed() does not do acceleration. If you want acceleration use run().

Ok well I have the stepper control and load cell now working properly.

I now am in the process of coding a GUI to input the stepper speed and direction. I am using processing and I can definitely make a GUI to input the stepper parameters. I think I can also use processing to make a file name to store the stepper position and force measured by the load cell.

Is it possible to also use processing to simultaneously view a plot of the position vs force? Basically I am asking if processing can send data via the serial port then receive it all in the same program or would I need to have one program to input the stepper parameters and another program to view the data coming the other direction?

You can send data from Arduino to Processing and plot the data and send data from Processing at the same time. I have done this with accelerometer and rate gyro data. The same techniques in Robin2's serial input basics are used. Build a packet in the Arduino a and sent to the PC. Use the split() function (instead of strtok) to separate the packet data.

groundFungus thanks for your help.

I have my arduino program working but I have to manually input the code via the serial monitor.

I wrote the processing sketch below to have a nicer way to enter the stepper motor parameters. I have one small glitch that I cannot figure out. I want to be able to use the toggle, slider and text box to set the motor speed, motor direction and output file name only when the "submit" button is selected. For some reason when I call the "speed" and "direction" functions within the "submit" button loop it returns values of 1 or 0.

Here is my code. Make sure to upload the ControlP5 library.

Thanks again!

import controlP5.; //import ControlP5 library
import processing.serial.
;

Serial port;

ControlP5 cp5; //create ControlP5 object
PFont font;
String url1;
int n, speed;

void setup(){ //same as arduino program

size(1000, 1000); //window size, (width, height)

// printArray(Serial.list()); //prints all available serial ports

// port = new Serial(this, "COM5", 74880); //i have connected arduino to com3, it would be different in linux and mac os

//lets add buton to empty window

cp5 = new ControlP5(this);
font = createFont("calibri light bold", 20); // custom fonts for buttons and title

cp5.addSlider("Speed")
.setPosition(50,100)
.setWidth(400)
.setRange(10,1700) // values can range from big to small as well
.setValue(1200)
;

ButtonBar b = cp5.addButtonBar("Direction")
.setPosition(50, 175)
.setSize(400, 100)
.addItems(split("a b"," "))
;
println(b.getItem("a"));
b.changeItem("a","text","Forward");
b.changeItem("b","text","Reverse");

cp5.addTextfield("Test File Name").setPosition(140, 350).setSize(200, 40).setAutoClear(false);

cp5.addBang("Submit").setPosition(200, 450).setSize(80, 40).setColorForeground(color(125,0, 0));
}

void draw(){ //same as loop in arduino

background(137); // background color of window (r, g, b) or (0 to 255)

//lets give title to our window
fill(17, 2, 13); //text color (r, g, b)
textFont(font);
text("MOTOR CONTROL", 170, 30); // ("text", x coordinate, y coordinat)

//lets give title to our window
fill(1, 1, 5); //text color (r, g, b)
textFont(font,20);
text("Motor Speed", 200, 80); // ("text", x coordinate, y coordinat)

//lets give title to our window
fill(19, 19, 36); //text color (r, g, b)
textFont(font,20);
text("Motor Direction", 180, 165); // ("text", x coordinate, y coordinat)

//lets give title to our window
fill(19, 19, 36); //text color (r, g, b)
textFont(font,20);
text("Test File Name", 180, 340); // ("text", x coordinate, y coordinat)
}

//lets add some functions to our buttons
//so whe you press any button, it sends perticular char over serial port

void Speed(int speed){
println("Speed",speed);
}

void Direction(int n) {
if(n == 0) n=-1;
if(n == 0) n=1;
println("Direction", n);

}

void Submit() {
print("the following text was submitted :");
url1 = cp5.get(Textfield.class,"Test File Name").getText();
println(" Test File Name = " + url1);
Speed(speed);
Direction(n);

}

I have not used the ControlP5 library so it will take a bit of study on my part to get up to speed, time permitting.

As this has turned into a Processing problem (not so much Arduino) you may want to have a Mod move it to the Interfacing w/ Software on the Computer section where there are likely more people familiar with Processing who can help you.

Please post code in code tags as described in the "How to use the forum-please read" stickies.

I fixed your code so that it outputs the data to the console (Edit: and serial port). The problem was in the button and slider event handlers. Now it should be easy to build a data packet to send to the Arduino using the url1, speed and direction variables. See the serial input basics thread to see how to format the packet(s), receive and parse your data (example 5 is very close to what you need for receiving).

Edit: Added serial output of data packet to submit function. Make sure to finish setting up your serial port (in setup()). Tested with an Uno using a slightly modified serial input basics example #5 code (printing to LCD as serial monitor is not available when Arduino connected to Processing).

import controlP5.*; //import ControlP5 library
import processing.serial.*;

Serial port;

ControlP5 cp5; //create ControlP5 object
PFont font;
String url1;
int n, speed, direction;  // ********  added a varaibe for dir

void setup() { //same as arduino program

//*******  set up serial port Make sure the right port is selected (Arduino port).
    port = new Serial(this, "COM8", 9600);


  size(800, 600);    //window size, (width, height)

  cp5 = new ControlP5(this);
  font = createFont("calibri light bold", 20);    // custom fonts for buttons and title

  cp5.addSlider("Speed")
    .setPosition(50, 100)
    .setWidth(400)
    .setRange(10, 1700) // values can range from big to small as well
    .setValue(1200)
    ;

  ButtonBar b = cp5.addButtonBar("Direction")
    .setPosition(50, 175)
    .setSize(400, 100)
    .addItems(split("a b", " "))
    ;
  println(b.getItem("a"));
  b.changeItem("a", "text", "Forward");
  b.changeItem("b", "text", "Reverse");

  cp5.addTextfield("Test File Name").setPosition(140, 350).setSize(200, 40).setAutoClear(false);

  cp5.addBang("Submit").setPosition(200, 450).setSize(80, 40).setColorForeground(color(125, 0, 0));
}

void draw() {  //same as loop in arduino

  background(137); // background color of window (r, g, b) or (0 to 255)

  //lets give title to our window
  fill(17, 2, 13);               //text color (r, g, b)
  textFont(font);
  text("MOTOR CONTROL", 170, 30);  // ("text", x coordinate, y coordinat)

  //lets give title to our window
  fill(1, 1, 5);               //text color (r, g, b)
  textFont(font, 20);
  text("Motor Speed", 200, 80);  // ("text", x coordinate, y coordinat)

  //lets give title to our window
  fill(19, 19, 36);               //text color (r, g, b)
  textFont(font, 20);
  text("Motor Direction", 180, 165);  // ("text", x coordinate, y coordinat)

  //lets give title to our window
  fill(19, 19, 36);               //text color (r, g, b)
  textFont(font, 20);
  text("Test File Name", 180, 340);  // ("text", x coordinate, y coordinat)
}

//lets add some functions to our buttons
//so whe you press any button, it sends perticular char over serial port



public void Speed(int theValue) {
  speed = theValue;
  println("Speed", speed);
}

void Direction(int theValue) {
  println("direction value " + theValue);
  if (theValue == 0)
  {
    direction = 1; // forward
  }
  else
  {
    direction =  -1; // reverse
  }

  println("Direction" + direction);
}

void Submit() {
  print("the following text was submitted :");
  url1 = cp5.get(Textfield.class, "Test File Name").getText();
  print(" Test File Name = " + url1);
  print("  SPEED " + speed);
  println("  DIR  " + direction);
// output packet to serial port
  port.write("<" + url1 + "," + speed + "," + direction + ">");  
}

Thank you so much!!!