Code:
#include "AccelStepper.h"
#include "PID_v1.h"
#include <stdlib.h>
#include <EEPROM.h>
#define DRIVER 1
#define HOMING 0
#define CLOSING 1
#define PULLING 2
#define OPENING 3
#define RETURNING 4
// Setpoint equation constants. y = 21968.23036x + 290.7863525
//linear regression for clamp load cell, calculated with weights from 0.5Kg to 1.5Kg
#define SLOPE 21968.23036f
#define INTERCEPT 290.7863525f
// Setpoint equation constants. y = 2241.65615x + 290.7862525
// linear regression from 4.9N ro 14.7N
#define SLOPE_N 2241.656159f
#define INTERCEPT_N 290.7863525f
//EEPROM addresses
#define DEFAULT_VALUES_FLAG 100
#define GRAMS_MSB 101
#define GRAMS_LSB 102
#define KP 103
#define KI 104
#define KD 105
#define SPEED_MSB 106
#define SPEED_3SB 107
#define SPEED_2SB 108
#define SPEED_LSB 109
#define ACCELERATION_MSB 110
#define ACCELERATION_3SB 111
#define ACCELERATION_2SB 112
#define ACCELERATION_LSB 113
//CONSTANTS
#define KP_DEFAULT 20.0f
#define KI_DEFAULT 12.0f
#define KD_DEFAULT 16.0f
#define MAX_PULL_SPEED 4000
#define MAX_PULL_ACCELERATION (MAX_PULL_SPEED * 1.2)
#define MAX_CLAMP_ACCELERATION 1000000
#define MAX_CLAMP_SPEED 100000
#define PID_SAMPLE_TIME 20
const uint8_t switchPin = 2;
const uint8_t clampLoadCellPin = A10;
const uint8_t pullLoadCellPin = A11;
const uint8_t pullMotorStepPin = 4;
const uint8_t pullMotorDirectionPin = 5;
const uint8_t clampMotorStepPin = 6;
const uint8_t clampMotorDirectionPin = 7;
const uint8_t yMotorStepPin = 8;
const uint8_t yMotorDirectionPin = 9;
const int enablePin = 20;
const long topPosition = -12500;
const long initialClamp = 100000; //ADC reading from clamp load cell, approx. 1Kg
//y = 21968.23036x + 290.7863525 linear trendline for clamp load cell, calculated with weights from 0.5Kg to 1.5Kg
//double setPoint = 11275.0; //setpoint for 500g -> 4.9N -> 0.3883V
//double setPoint = 22259.0; //setpoint for 1000g -> 9.8N -> 0.7689V
//double setPoint = 33243.0; //setpoint for 1500g -> 14.7N -> 1.1495V
//double setPoint = 44227.0; //setpoint for 2000g -> 19.6N -> 1.5301V
//double setPoint = 55211.0; //setpoint for 2500g -> 24.5N -> 1.9107V
//double setPoint = 59605.0; //setpoint for 2700g -> 26.46N -> 2.0629V
double setPoint = 22259.0; //default value for 1000g, 9.8N
char inputString[32];
bool startCommand;
boolean stringComplete = false,
startSwitch = false;
uint8_t pullingState = 0,
status = 0,
i = 0;
uint16_t grams;
uint32_t previous,
pullSpeed,
pullAcceleration; // could consider using unions for saving eeprom data in byte format
double input,
output,
error,
previousError,
pullLoad,
kp = KP_DEFAULT,
ki = KI_DEFAULT,
kd = KD_DEFAULT;
AccelStepper pullMotor(DRIVER, pullMotorStepPin, pullMotorDirectionPin);
AccelStepper clampMotor(DRIVER, clampMotorStepPin, clampMotorDirectionPin);
//AccelStepper yMotor(DRIVER, yMotorStepPin, yMotorDirectionPin);
PID clampPID(&input, &output, &setPoint, kp, ki, kd, DIRECT);
void setup() {
pinMode(13, OUTPUT);
pinMode(switchPin, INPUT_PULLUP);
pinMode(enablePin, OUTPUT);
Serial.begin(0);
if (EEPROM.read(DEFAULT_VALUES_FLAG) == 0) {
grams = EEPROM.read(GRAMS_MSB) << 8;
grams += EEPROM.read(GRAMS_LSB);
setPoint = calculateSetPoint(grams);
kp = EEPROM.read(KP);
ki = EEPROM.read(KI);
kd = EEPROM.read(KD);
pullSpeed = EEPROM.read(SPEED_MSB) << 24;
pullSpeed += EEPROM.read(SPEED_3SB) << 16;
pullSpeed += EEPROM.read(SPEED_2SB) << 8;
pullSpeed += EEPROM.read(SPEED_LSB);
pullAcceleration = EEPROM.read(ACCELERATION_MSB) << 24;
pullAcceleration += EEPROM.read(ACCELERATION_3SB) << 16;
pullAcceleration += EEPROM.read(ACCELERATION_2SB) << 8;
pullAcceleration += EEPROM.read(ACCELERATION_LSB);
clampPID.SetTunings(kp, ki, kd);
} else
{
pullSpeed = MAX_PULL_SPEED;
pullAcceleration = MAX_PULL_ACCELERATION;
}
pullMotor.setMaxSpeed(pullSpeed);
pullMotor.setAcceleration(pullAcceleration);
clampMotor.setMaxSpeed(MAX_CLAMP_SPEED);
clampMotor.setAcceleration(MAX_CLAMP_ACCELERATION);
//yMotor().setMaxSpeed(4000);
//yMotor().setAcceleration(4800);
clampPID.SetSampleTime(PID_SAMPLE_TIME); //Library is modified for working with microseconds
clampPID.SetOutputLimits(0.0, 500.0);
clampPID.SetMode(AUTOMATIC);
analogReference(EXTERNAL); // Configure Teensy to read value using 2.5v reference from amplifier
analogReadRes(16); // Set analog resolution to 16-Bits
analogReadAveraging(0); // Set 16 averaging values
delay(100); // wait until amplifier starts
digitalWrite(enablePin, HIGH); // enable
status = HOMING;
digitalWrite(13, LOW);
}
void loop()
{
doCommandTasks();
doStraightenTasks();
}
void doStraightenTasks () {
startSwitch = digitalRead(switchPin);
if (!startSwitch || startCommand) {
startCommand = false;
status = CLOSING;
closeClamp();
status = PULLING;
pullMotor.moveTo(topPosition);
while (pullMotor.isRunning()) {
pullLoad = analogRead(pullLoadCellPin);
input = analogRead(clampLoadCellPin);
clampMotor.run();
pullMotor.run();
int8_t direction = 1;
error = setPoint - input;
if (error > 0) direction = 1;
else direction = -1;
clampMotor.run();
pullMotor.run();
bool newOutput = clampPID.Compute();
clampMotor.run();
pullMotor.run();
if (newOutput) clampMotor.move((long) (output * direction));
clampMotor.run();
#if 1
if(millis() - previous > 10) {
char msg[20];
//sprintf(msg,"%u,%u", (uint16_t)input, (uint16_t)setPoint);
//sprintf(msg,"%u,%u,%i", (uint16_t)input, (uint16_t)setPoint, (int16_t)(output*direction));
sprintf(msg,"%u,%u,%u", (uint16_t)input, (uint16_t)setPoint, (uint16_t)pullLoad);
Serial.println(msg);
previous = millis();
}
#endif
clampMotor.run();
pullMotor.run();
}
status = OPENING;
openClamp();
status = RETURNING;
pullMotor.moveTo(0);
pullMotor.setSpeed(MAX_PULL_SPEED);
while (pullMotor.isRunning()) pullMotor.run();
startSwitch = false;
}
}
Thanks in advance!!