I modified the example 3 in Serial Input Basics because I couldn't find a way to easily extract numbers in decimal, but it seams to work as intended, and it is in a separate function, and it doesn't use Serial.parseInt().
The way my program reads values, it allows to enter only the first value to change only the first variable (here N2).
I added commentaries to make the program easier to understand.
The goal of it is to turn a motor 2 constantly at N2 rpm, and another motor 1 should run faster by DN rpm during T seconds and then slower also by DN rpm also for T seconds. In mathematical terms:
For 0<t<T, N1 = N2 + DN, for T<t<2T, N1 = N2 - DN
If the variable nz = 0, DN is also 0 but T is infinite, so I added a special case for that.
But I can't get my motors to turn faster than 40 rpm, and it's not a torque issue, because I can try to stop it wih my hands and it still turns at around 40rpm.
#include <Wire.h>
#include <AccelStepper.h>
#include <Adafruit_MotorShield.h>
Adafruit_MotorShield AFMStop(0x60);
Adafruit_StepperMotor *myStepper1 = AFMStop.getStepper(200, 1);
Adafruit_StepperMotor *myStepper2 = AFMStop.getStepper(200, 2);
void forwardstep1() {
myStepper1->onestep(FORWARD, DOUBLE);
}
void backwardstep1() {
myStepper1->onestep(BACKWARD, DOUBLE);
}
void forwardstep2() {
myStepper2->onestep(FORWARD, DOUBLE);
}
void backwardstep2() {
myStepper2->onestep(BACKWARD, DOUBLE);
}
AccelStepper stepper1(forwardstep1, backwardstep1);
AccelStepper stepper2(forwardstep2, backwardstep2);
int N2=0; //Motor 2 speed (U/min)
int nz=0; //number of cycles
int A=0; //Amplitude (mm)
int Data=0;
float T=1; //half period
int i=1;
float DN; //DeltaN (N1 = N2 +/- DN)
float dr=18; //roller diameter (mm)
double timer=0;
char receivedInt;
boolean newData = false;
int index=0;
void setup()
{
AFMStop.begin();
Serial.begin(9600);
stepper1.setAcceleration(500);
stepper2.setAcceleration(500);
Serial.print("Ready \n");
}
void receiveData() {
char endMarker = '\n';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (rc != endMarker && rc != ',') {
Data*=10;
Data = Data+rc-'0';
}
else {
index++;
if(index==1){
N2=Data;
Data=0;
if(N2==0){DN=0;}
Serial.print("N2= ");
Serial.println(N2, DEC);
if(rc==endMarker){index=0;}
}
if(index==2){
nz=Data;
Data=0;
T=450/(nz*N2*3.14159*dr);
Serial.print("nz= ");
Serial.println(nz,DEC);
Serial.print("T= ");
Serial.println(T,DEC);
if(rc==endMarker){index=0;}
}
if(index==3){
A=Data;
Data=0;
DN=60*A*nz*N2/450;
Serial.print("A= ");
Serial.println(A,DEC);
Serial.print("DN= ");
Serial.println(DN,DEC);
index=0;
}
newData = true;
}
}
}
void NewData() {
if (newData == true) {
stepper1.move(400);
stepper2.move(400);
timer=millis();
newData = false;
timer=0;
stepper1.setMaxSpeed((N2+i*DN)*200/60);
stepper2.setMaxSpeed(N2*200/60);
}
}
void loop(){
receiveData();
NewData();
if(N2>0){
if(millis()-timer >= T*1000){
stepper1.move(400);
stepper2.move(400);
timer=millis();
stepper1.setMaxSpeed((N2+i*DN)*200/60); //N1 = N2 + i*DN
i=-i; //i is to add or substract DeltaN to N2 to get N1
}
if(nz==0 && stepper1.distanceToGo()<= 10){ //if nz=0, I want both motors to turn at the same speed
stepper1.move(400);
stepper2.move(400);
}
}
stepper1.run();
stepper2.run();
}
EDIT: I tried the example from Adafruit and just modified the setMaxSpeed to 400 to try to reach 120 rpm, but I couldn't get past 40 rpm...
// Shows how to run three Steppers at once with varying speeds
//
// Requires the Adafruit_Motorshield v2 library
// https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library
// And AccelStepper with AFMotor support
// https://github.com/adafruit/AccelStepper
// This tutorial is for Adafruit Motorshield v2 only!
// Will not work with v1 shields
#include <Wire.h>
#include <AccelStepper.h>
#include <Adafruit_MotorShield.h>
Adafruit_MotorShield AFMSbot(0x61); // Rightmost jumper closed
Adafruit_MotorShield AFMStop(0x60); // Default address, no jumpers
// Connect two steppers with 200 steps per revolution (1.8 degree)
// to the top shield
Adafruit_StepperMotor *myStepper1 = AFMStop.getStepper(200, 1);
Adafruit_StepperMotor *myStepper2 = AFMStop.getStepper(200, 2);
// Connect one stepper with 200 steps per revolution (1.8 degree)
// to the bottom shield
//Adafruit_StepperMotor *myStepper3 = AFMSbot.getStepper(200, 2);
// you can change these to DOUBLE or INTERLEAVE or MICROSTEP!
// wrappers for the first motor!
void forwardstep1() {
myStepper1->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
myStepper1->onestep(BACKWARD, SINGLE);
}
// wrappers for the second motor!
void forwardstep2() {
myStepper2->onestep(FORWARD, DOUBLE);
}
void backwardstep2() {
myStepper2->onestep(BACKWARD, DOUBLE);
}
// Now we'll wrap the 3 steppers in an AccelStepper object
AccelStepper stepper1(forwardstep1, backwardstep1);
AccelStepper stepper2(forwardstep2, backwardstep2);
void setup()
{
AFMSbot.begin(); // Start the bottom shield
AFMStop.begin(); // Start the top shield
stepper1.setMaxSpeed(400);
stepper1.setAcceleration(1000.0);
stepper1.move(100000);
stepper2.setMaxSpeed(400);
stepper2.setAcceleration(1000.0);
stepper2.move(100000);
}
void loop()
{
// Change direction at the limits
if (stepper1.distanceToGo() == 0)
stepper1.moveTo(-stepper1.currentPosition());
if (stepper2.distanceToGo() == 0)
stepper2.moveTo(-stepper2.currentPosition());
stepper1.run();
stepper2.run();
}