Well, that isn't the case here, Nick. I basically copy/pasted your code into my project. And as I said, it does let me change the baud rate, which I wasn't able to do before, but it doesn't work if I go to a higher baud rate.
I'll try the dummy program. I actually have one written already, so it should be easy to modify for this test. Thanks for the suggestion!
Here is main:
//#include <SoftwareSerial.h>
//SoftwareSerial serial2(9,10); // Tx = 10, Rx = 9
const int ledPin = 13;
const int scaleFactorInt = 403; //Use radius of 0.79" to figure this out. This is for 11" long beam.
const double scaleFactorDouble = 403.0; //Use radius of 0.79" to figure this out. This is for 11" long beam.
//Define the constants from beam measurments.
const int beamLength = 11; //The length of the beam in inches.
const double beamThickness = 0.022; //Beam thickness in inches.
const int gaugeLocation = 3; //Location of the gauges, in inches from the pivot.
void setup()
{
//Start serial to communicate with motor.
Serial.begin(9600);
//Serial.println("Serial started.");
pinMode(13, OUTPUT);
hardStopCalibrate(); //Find zero.
//Set Maximum Acceleration
sendCom("A=700");
//Set Maximum velocity
sendCom("V=10000000");
//Send the motor to a good central position.
goTo(inchesToLocation(5));
//Send Go command to start motor servo with new values.
sendCom("G");
//Tell the motor to go to a new baud rate.
sendCom("BAUD9600");
//Prepare to change the Arduino baud rate.
Serial.flush();
delay(2);
Serial.end();
//Change the arduino's baud rate.
Serial.begin(9600);
}
int locationValue = inchesToLocation(5); //This needs to exist outside of the loop.
const int maxLocation = inchesToLocation(8.5); //Max location.
const int minLocation = inchesToLocation(3); //Min location.
void loop()
{
int prevLocation = locationValue;
//Determine the deflection.
double z = calculateZ(calculateStrain(), locationValue); //This is stored so that it is only calculated once.
//Figure out the new desired location.
locationValue = inchesToLocation(desiredLocation(z, forceProfile(z)));
//If the location error is greater than desired, send the updated location to the motor.
//Done to reduce motor jitter caused by noise on the analog line.
int e = locationValue - prevLocation; //Location error value.
if (abs(e) > 30)
{
if (locationValue > maxLocation) //If the calculated location value is too big, go to endpoint.
{
locationValue = maxLocation;
}
else if (locationValue < minLocation) //If the calculated location value is too small, go to endpoint.
{
locationValue = minLocation;
}
goTo(locationValue); //Send the motor the desired location.
}
else{locationValue = prevLocation;} //Prevents slow drifting by storing the last sent location.
digitalWrite(13, !digitalRead(13)); //Toggle LED after each loop.
}
My "Small Functions":
const String setPoint = "P=";
//Build the position string for the motor.
String goPoint(int location)
{
return setPoint + location;
}
//Send the motor to a specific location.
void goTo(int location)
{
sendCom(goPoint(location));
sendCom("G");
}
//Send a command to the motor in a friendly way.
void sendCom(String command)
{
Serial.print(command); //Send the command string to the motor.
Serial.print('\r'); //Send the end line to the motor (delimiter.)
}
//Send a status request to the motor, and return the responce.
String requestStatus(String command)
{
//Send the status request to the motor.
sendCom(command);
//Wait for a message to arrive, with a maximum delay.
int i = 0;
while(!Serial.available() && i < 1000000)
{i++;}
//If there is a message from the motor, save it as a string.
boolean done = false;
String motorStatus;
while (Serial.available() > 0 && !done)
{
delay(10);
char next;
next = char(Serial.read());
//Check for delimiters, so as to not combine messages.
if (next != '\r' && next != ' ')
{
motorStatus += next;
}
else{done = true;}
}
Serial.flush(); //Clear the buffer of any other data.
motorStatus.trim();
return motorStatus;
}
//Just like requestStatus, but only checks for a message. Doesn't send anything to the motor.
String getStatus()
{
boolean done = false;
String motorStatus;
//Wait for a message to arrive, with a maximum delay.
int i = 0;
while(!Serial.available() && i < 1000000)
{i++;}
//If there is a message from the motor, save it as a string.
while (Serial.available() > 0 && !done)
{
char next;
next = char(Serial.read());
//Check for delimiters, so as to not combine messages.
//(Smart motor uses a carriage return "\r" as a delimiter.)
if (next != '\r' && next != ' ')
{
motorStatus += next;
}
else{done = true;}
}
Serial.flush(); //Clear the buffer of any other data.
motorStatus.trim();
return motorStatus;
}
//This is defined as the the distance from the pivot.
//Input in is inches.
int inchesToLocation(double inches)
{
return (int)((inches - 0.875) * scaleFactorInt);
}
//Does the opposite of the above function, changing from location to inches.
double locationToInches(int location)
{
return (double)(location/scaleFactorDouble + 0.875);
}
int stringToInt(String stringValue)
{
int intValue = 0;
int length = 0;
length = stringValue.length();
int i = 0;
for(i=0; i<length; i++)
{
intValue = (10*intValue) + stringValue.charAt(i)-(int) '0';
}
return intValue;
}
Calculate Desired Location:
const long modulus = 30000000;
//Width = 3/4", h = 0.02". I=(1/12)bh^3
const double aMomentOfInertia = 0.0000005;
//If this calculation is too slow, look into converting to int math.
//Takes as input a z value (should come from function that calculates it from
//strain guage input) and desired force (should come from user defined function.)
//Returns the new desired location in inches.
const double distanceMultiplier = sqrt(3*modulus*aMomentOfInertia/beamLength); //Precalculate constant to speed up operation.
double desiredLocation(double z, double force)
{
double distanceFromEnd = 0.0; // = sqrt[(3zEI)/(FL)]
distanceFromEnd = distanceMultiplier*sqrt(z/force);
//Serial.print("Calculated distance from end=");
//Serial.println(distanceFromEnd, 6);
return beamLength - distanceFromEnd;
}