Hi guys,
I have been working with the code below where I am reading the signals coming from two weight scales using a MAX232 to convert RS232 into TTL Logic and the serial hardware pins of the Arduino Mega 2560 (Serial 2 and Serial 3). My code works perfectly for the acquisition part: I can acquire and read the weight of the scales on my Serial Monitor.
What my code does in the void loop is acquiring the weight values of the scales, and once the weight float value of the scale 1 is greater than a certain Desired Weight set initially, running a Stepper Motor with a ramp up profile on the Step Pin. (moveMotor())
Unfortunately, when the condition just mentioned is verified, the ramp up profile generated on the Step Pin has some gaps in between, causing my motor to stall (see picture "Ramp profile while serial reading in void loop").
const byte sleep33=12; // SLEEP signal driver stepper
byte stepPin=35; // STEP Signal
byte directionPin33=25; // DIRECTION signal
int incomingByte = 0; // for incoming serial data
char receivedChar_scale1;
const byte numChars_scale1 = 32 ;
char receivedChars_scale1[numChars_scale1];
char tempChars_scale1[numChars_scale1]; // temporary array for use when parsing
char Weight_scale1[numChars_scale1] = {0};
int integerWeight_scale1 = 0;
float floatWeight_scale1 = 0.0;
float DesiredWeight_scale1 = 50.0;
boolean newData_scale1 = false;
int num_scale1;
char receivedChar_scale2;
const byte numChars_scale2 = 32 ;
char receivedChars_scale2[numChars_scale2];
char tempChars_scale2[numChars_scale2]; // temporary array for use when parsing
char Weight_scale2[numChars_scale2] = {0};
int integerWeight_scale2 = 0;
float floatWeight_scale2 = 0.0;
float DesiredWeight_scale2 = 0.0;
boolean newData_scale2 = false;
int num_scale2;
unsigned long curMicros;
unsigned long prevStepMicros = 0;
unsigned long slowMicrosBetweenSteps = 1667; // microseconds (starting frequency)
unsigned long fastMicrosBetweenSteps = 462; // constant speed frequency)
unsigned long stepIntervalMicros;
unsigned long stepAdjustmentMicros;
int numAccelSteps = 100; // number of steps for the acceleration part
int numSteps = 2000; //total number of steps in case you go for a complete trapezoidal profile
int stepsToGo;
unsigned long currentMicroTime=0;
void setup() {
pinMode(directionPin33, OUTPUT);
digitalWrite(directionPin33,HIGH);
pinMode(stepPin, OUTPUT);
pinMode (sleep33, OUTPUT);
digitalWrite(sleep33,LOW); // turning the driver in sleep mode
Serial.begin(9600);
Serial2.begin(9600);
Serial3.begin(9600);
stepAdjustmentMicros = (slowMicrosBetweenSteps - fastMicrosBetweenSteps) / numAccelSteps;
stepIntervalMicros = slowMicrosBetweenSteps;
stepsToGo = numSteps;
} // end of setup
void loop() {
recvWithEndMarker_scale1();
if (newData_scale1 == true) {
strcpy(tempChars_scale1, receivedChars_scale1);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with
parseData_scale1();
showParsedData_scale1();
newData_scale1 = false;
}
recvWithEndMarker_scale2();
if (newData_scale2 == true) {
strcpy(tempChars_scale2, receivedChars_scale2);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with
parseData_scale2();
showParsedData_scale2();
newData_scale2 = false;
}
if (floatWeight_scale1 >= DesiredWeight_scale1){
if (currentMicroTime==0) {
currentMicroTime=micros();
digitalWrite(sleep33,HIGH); //turning ON the driver
moveMotor();
}
else {
digitalWrite(sleep33,HIGH); //turning ON the driver
moveMotor();
}
}
}
void recvOneChar_scale1() {
if (Serial2.available() > 0) {
receivedChar_scale1 = Serial2.read();
newData_scale1 = true;
}
}
void recvOneChar_scale2() {
if (Serial3.available() > 0) {
receivedChar_scale2 = Serial3.read();
newData_scale2 = true;
}
}
void recvWithEndMarker_scale1() {
static byte ndx_scale1 = 0;
char endMarker_scale1 = 'n';
char rc_scale1;
while (Serial2.available() > 0 && newData_scale1 == false) {
rc_scale1 = Serial2.read();
if (rc_scale1 != endMarker_scale1) {
receivedChars_scale1[ndx_scale1] = rc_scale1;
ndx_scale1++;
if (ndx_scale1 >= numChars_scale1) {
ndx_scale1 = numChars_scale1 - 1;
}
}
else {
receivedChars_scale1[ndx_scale1] = ''; // terminate the string
ndx_scale1 = 0;
newData_scale1 = true;
}
}
}
void recvWithEndMarker_scale2() {
static byte ndx_scale2 = 0;
char endMarker_scale2 = 'n';
char rc_scale2;
while (Serial3.available() > 0 && newData_scale2 == false) {
rc_scale2 = Serial3.read();
if (rc_scale2 != endMarker_scale2) {
receivedChars_scale2[ndx_scale2] = rc_scale2;
ndx_scale2++;
if (ndx_scale2 >= numChars_scale2) {
ndx_scale2 = numChars_scale2 - 1;
}
}
else {
receivedChars_scale2[ndx_scale2] = ''; // terminate the string
ndx_scale2 = 0;
newData_scale2 = true;
}
}
}
void showNewData_scale1() {
if (newData_scale1 == true) {
Serial.print(receivedChar_scale1);
newData_scale1 = false;
}
}
void showNewData_scale2() {
if (newData_scale2 == true) {
Serial.print(receivedChar_scale2);
newData_scale2 = false;
}
}
void parseData_scale1() { // split the data into its parts
char * strtokIndx_scale1; // this is used by strtok() as an index
strtokIndx_scale1 = strtok(tempChars_scale1," "); // get the first part - the string
strcpy(Weight_scale1, strtokIndx_scale1); // copy it to messageFromPC
integerWeight_scale1 = atoi(strtokIndx_scale1); // convert this part to an integer
floatWeight_scale1 = atof(strtokIndx_scale1); // convert this part to a float
}
void parseData_scale2() { // split the data into its parts
char * strtokIndx_scale2; // this is used by strtok() as an index
strtokIndx_scale2 = strtok(tempChars_scale2," "); // get the first part - the string
strcpy(Weight_scale2, strtokIndx_scale2); // copy it to messageFromPC
integerWeight_scale2 = atoi(strtokIndx_scale2); // convert this part to an integer
floatWeight_scale2 = atof(strtokIndx_scale2); // convert this part to a float
}
void showParsedData_scale1() {
Serial.print("Weight Drain: ");
Serial.println(Weight_scale1);
Serial.print("Integer Drain: ");
Serial.println(integerWeight_scale1);
Serial.print("Float Drain: ");
Serial.println(floatWeight_scale1);
}
void showParsedData_scale2() {
Serial.print("Weight Concentrates: ");
Serial.println(Weight_scale2);
Serial.print("Integer Concentrates: ");
Serial.println(integerWeight_scale2);
Serial.print("Float Concentrates: ");
Serial.println(floatWeight_scale2);
}
void moveMotor() {
if (stepsToGo > 0) {
if (micros() - currentMicroTime - prevStepMicros >= stepIntervalMicros) {
prevStepMicros = prevStepMicros + stepIntervalMicros;
singleStep();
//stepsToGo --;
if (stepsToGo <= numAccelSteps) {
if (stepIntervalMicros < slowMicrosBetweenSteps) {
stepIntervalMicros = stepIntervalMicros + stepAdjustmentMicros;
}
}
else {
if (stepIntervalMicros > fastMicrosBetweenSteps) {
stepIntervalMicros = stepIntervalMicros - stepAdjustmentMicros;
}
}
}
}
else {
// direction = ! direction;
//digitalWrite(directionPin, direction);
// next two lines just for the demo
delay(2000);
Serial.println("Changing direction");
stepsToGo = numSteps;
prevStepMicros = micros();
}
}
void singleStep() {
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
}