Show Posts
Pages: [1] 2
1  Using Arduino / Motors, Mechanics, and Power / Pausing Steppers using AccelStepper on: December 03, 2012, 06:05:01 pm
Hi All,

I'm building a weird clock as part of a sculpture installation. I'm using three different stepper motors to control the "hands" of the clock. I say its weird because this clock uses half-day increments, months, and two-month increments rather than seconds, minutes, hours. But, for this question, that shouldn't matter.

I'm trying to figure out how to delay the second hand between movements without effecting the minute and hour hands. So, as it is now, I ramp up the second hand up to speed, rotate, and ramp down to 180-degrees and repeat. I don't have any delay between the ramp down and the next ramp up, but I'd like to have some. If I add a "delay(10)" in there for instance, both the minute and hour hands will also delay each time a second passes. The minute and hour hands take a few seconds to position themselves and I'd like them to move smoothly and not encounter this delay. So, I think I have to delay the second hand using millis() or some other function.

So, the condensed question is how do you use AccelStepper to move and stop one stepper multiple time while two other steppers continue to move smoothly? I'm using three Big Easy Drivers and an Arduino Uno. Its all powered off of a 12v/10A power supply.

Code:
/*
Description
This is the Arduino code for the Coincidence Clock. Three individual stepper motors are connected to the day, month and coincidence dials on the clock.
The day dial in the center moves in half-day increments. So, the first movement is 180-degrees with a brief pause follwed by another 180-degree revolution completing the motion.


Steppers = 200 steps / revolution. 1.2A / coil. 
 
*/

//******************Constants***********
#include <AccelStepper.h>
#include <Servo.h>
 
Servo myservo;  // create servo object to control a servo

AccelStepper dayStepper(1, 13, 12);
AccelStepper monthStepper(1, 10, 9);
AccelStepper coincidenceStepper(1, 7, 6);

int halfDaySteps = 400; //Using 1/4 step
int monthSteps = 3430;  //use default 16 steps. 231 teeth on wheel. 18 teeth on pulley. Ratio = 12.833. 200 steps / rev * 16 = 3200, 3422.13 steps
int coincidenceSteps = 2193;  // Default 16th step. 74 teeth on wheel, 18 on pulley. Ration = 4.111. 3200 * 4.111 / 6 = 2193 steps per movement

long totalDays = 9490000 * 2 + 1; // DAYS * 2 (half day steps) Add +1 to total desired days. 26000 years = 365 * 26000 = 9,490,000
int daysInMonth = 30 * 2; // 30 Days in a month * 2 half days
int daysInCoincidence = 60 * 2; // 30 days in Coincidence * 2 half days

//******************Variables***********
long dayCount = 0;
long monthCount = 0;
long oldTime = 0;
//****************Function Prototypes******

void endlessLoop();
//***************Setup******************************
void setup() {
 
  dayStepper.setMaxSpeed(500);
  dayStepper.setAcceleration(4000);
  monthStepper.setMaxSpeed(684);
  monthStepper.setAcceleration(2000);
  coincidenceStepper.setMaxSpeed(438);
  coincidenceStepper.setAcceleration(2000);
 
  myservo.attach(2);  // attaches the servo on pin 2 to the servo object
  delay(1000);
 
  for(int i=15; i <= 170; i++){    //Sweep the servos to align season symbols
    myservo.write(i);                  // sets the servo position according to the scaled value
    delay(3);                    // waits for the servo to get there
  }
 delay(1000);
 for(int i=170; i >= 15; i--){       //Return servos to start position
  myservo.write(i);                  // sets the servo position according to the scaled value
  delay(3);        // waits for the servo to get there
 }
 delay(1000);
}

//*************Main Program Loop************************
void loop() {
 
  if (dayStepper.distanceToGo() == 0)
   {
    dayStepper.setCurrentPosition(0);
    dayCount++;
    dayStepper.moveTo(halfDaySteps);
    oldTime = millis();
   }

 
  int monthTag = dayCount % daysInMonth;
  if(monthTag == 0){
    if (monthStepper.distanceToGo() == 0)
    {
      //delay(5000);
      monthStepper.setCurrentPosition(0);
      monthCount++;
      monthStepper.moveTo(monthSteps);
    }
  }
 
  int coincidenceTag = dayCount % daysInCoincidence;
  if(coincidenceTag == 0){
    if (coincidenceStepper.distanceToGo() == 0)
    {
      //delay(5000);
      coincidenceStepper.setCurrentPosition(0);
      coincidenceStepper.moveTo(coincidenceSteps);
    }
  } 
 
  dayStepper.run();
  monthStepper.run();
  coincidenceStepper.run();
 
   if(dayCount == totalDays){
     for(int i=15; i <= 170; i++){
     myservo.write(i);                  // sets the servo position according to the scaled value
     delay(3);                          // waits for the servo to get there
   }
   endlessLoop();
  }
 
}
//*********************FUNCTIONS***************************
void endlessLoop(){
  int i =0;
  while(i == 0){
  }

}
//**************************************************************************




I tried this, and it you have to fudge around with the timing to get the pause to work. But, if I do this, the second hand seems to loose its position and stops in random places. So, calling dayStepper at a delayed rate seems to screw with the positioning.

Code:
if (millis() - oldTime > 1500){
  if (dayStepper.distanceToGo() == 0)
   {
    dayStepper.setCurrentPosition(0);
    dayCount++;
    dayStepper.moveTo(halfDaySteps);
    oldTime = millis();
   }
}

Thanks for any help!
2  Using Arduino / Programming Questions / Re: Replacing String objects with C strings on: October 17, 2012, 01:06:03 pm
I used the strstr() function and it seems to be working. I finally got the code to recognize the output. So, a minor victory! Thanks a ton.

Now, I use this information to set the home position for my CNC, or to let me know if my bed over-traveled in the +X, -X, +Y or -Y directions. Each limit has it's own L,XXXX code. In the grand scheme of things, I'd like to be able to call a function like "triangle" or "square" that would fill my stepCommand array with the desired string commands. This involves loading my char *stepCommand array with passed from functions, which I'm guessing is going to be a pain. But, I'll research that and see what I can do.

Serial Monitor output at limit switch activation:

-30000XG --> IF LOOP
Character Read:
FFFFFF86 ---> Character 0
A ---> Character 1
4C ---> Character 2
2C ---> Character 3
31 ---> Character 4
36 ---> Character 5
33 ---> Character 6
39 ---> Character 7
32 ---> Character 8
D ---> Character 9
A ---> Character 10
2A ---> Character 11
======================
†
L,16392
* --> Read String
Write Q Here

Code:
/*
CNC Bed Sketch

This program drives a Peter Norburg SD4DEU Stepper Driver board running SD4DNCRouter firmware connecting at 9600 Baud.
 
 
*/

//******************Constants***********
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX

char homePosition[5] = "0XYG";



//******************Variables***********

char readString[70];
char c;
int index = 0;
int commandNumber = 0;
int numCommands = 0;

//****************Function Prototypes******
long convertToSteps(int inches);

//***************Setup******************************
void setup() {
  delay(1000);
 
  //readString[0] = '\0';    //Add a null termination to readString
 
  Serial.begin(9600);    //Begin serial communication at 9600
  mySerial.begin(9600);  //Set software serial baud rate
 
  randomSeed(analogRead(0));
 
  // Initialize Stepperboard Values
  mySerial.write("!");      //reset Stepper Board
  delay(50);
  mySerial.write("1500R");  //Set Run Rate
  delay(50);
  mySerial.write("800P");  //Set Ramp Rate
  delay(1000);
}

//*************Main Program Loop************************
void loop() {
 
 
 char* stepCommand[] = {    //Load up CNC Patterns into string array
 "30000XG",
 "-30000XG"
  };
 
 int numCommands = (sizeof(stepCommand)/sizeof(char*)); //Calculate array size

 while(mySerial.available()){
   c = mySerial.read();   //get one byte from buffer
   readString[index++] = c;    //increment array (original array index is returned)
   readString[index] = '\0';    //Add NULL to next index
   //i=i+1;
   //Serial.print(c);
   //Serial.println(" --> c charachter byte");
   if(readString[index-1]== '*'){
     mySerial.write(stepCommand[commandNumber]);
     Serial.print(stepCommand[commandNumber]);
     Serial.println(" --> IF LOOP");
     commandNumber++;
     if(commandNumber == numCommands){    //if the max number of commands is reached...
        commandNumber = 0;                //reset command number back to zero
     } 
     break;
   }
 }

 mySerial.write("L");
 
 if(strlen(readString) > 0){
   Serial.println("Character Read: ");
   for(int j=0; j < strlen(readString); j++){
     Serial.print(readString[j], HEX);
     Serial.print(" ---> Character ");
     Serial.println(j);
   }
   Serial.println("======================");
   Serial.print(readString);
   Serial.println(" --> Read String");
   char response[10];
   response[0] = '\0';
   
   
   
   if((strstr(readString, "L,16392")) != 0){
     Serial.println("Write Q Here");
     Serial.println("");
   }
   else{
     Serial.println("Strings not Equal");
     Serial.println("");
   }
   readString[0] = '\0';      //clear the array
   index = 0;
 } 
}
//*********************FUNCTIONS***************************
long convertToSteps(int inches){
  long steps = 130435 * inches;  //there are 130435 steps in 1-inch
  return(steps);
}
//**************************************************************************

3  Using Arduino / Programming Questions / Re: Replacing String objects with C strings on: October 17, 2012, 12:33:35 pm
All right. So I changed the println command in include HEX and the spaces disappear. I also set index back to zero right after I clear the array. The Hex shows all the crap in there. Thats a good trick! Now, I think I can use the strstr() function (or something) to pluck out useful string.  Or, is there an easier way to do that?

LIMIT SWITCH PORTION OF SERIAL MONITOR OUTPUT:

30000XG --> IF LOOP
Character Read:
FFFFFF86 ---> Character 0
A ---> Character 1
FFFFFF86 ---> Character 2
A ---> Character 3
FFFFFF86 ---> Character 4
A ---> Character 5
4C ---> Character 6
2C ---> Character 7
31 ---> Character 8
36 ---> Character 9
33 ---> Character 10
39 ---> Character 11
32 ---> Character 12
D ---> Character 13
A ---> Character 14
2A ---> Character 15
======================
†
†
†
L,16392
* --> Read String
Strings not Equal

Code:
/*
CNC Bed Sketch

This program drives a Peter Norburg SD4DEU Stepper Driver board running SD4DNCRouter firmware connecting at 9600 Baud.
 
 
*/

//******************Constants***********
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX

char homePosition[5] = "0XYG";



//******************Variables***********

char readString[70];
char c;
int index = 0;
int commandNumber = 0;
int numCommands = 0;

//****************Function Prototypes******
long convertToSteps(int inches);

//***************Setup******************************
void setup() {
  delay(1000);
 
  //readString[0] = '\0';    //Add a null termination to readString
 
  Serial.begin(9600);    //Begin serial communication at 9600
  mySerial.begin(9600);  //Set software serial baud rate
 
  randomSeed(analogRead(0));
 
  // Initialize Stepperboard Values
  mySerial.write("!");      //reset Stepper Board
  delay(50);
  mySerial.write("1500R");  //Set Run Rate
  delay(50);
  mySerial.write("800P");  //Set Ramp Rate
  delay(1000);
}

//*************Main Program Loop************************
void loop() {
 
 
 char* stepCommand[] = {    //Load up CNC Patterns into string array
 "30000XG",
 "-30000XG"
  };
 
 int numCommands = (sizeof(stepCommand)/sizeof(char*)); //Calculate array size

 while(mySerial.available()){
   c = mySerial.read();   //get one byte from buffer
   readString[index++] = c;    //increment array (original array index is returned)
   readString[index] = '\0';    //Add NULL to next index
   //i=i+1;
   //Serial.print(c);
   //Serial.println(" --> c charachter byte");
   if(readString[index-1]== '*'){
     mySerial.write(stepCommand[commandNumber]);
     Serial.print(stepCommand[commandNumber]);
     Serial.println(" --> IF LOOP");
     commandNumber++;
     if(commandNumber == numCommands){    //if the max number of commands is reached...
        commandNumber = 0;                //reset command number back to zero
     } 
     break;
   }
 }

 mySerial.write("L");
 
 if(strlen(readString) > 0){
   Serial.println("Character Read: ");
   for(int j=0; j < strlen(readString); j++){
     Serial.print(readString[j], HEX);
     Serial.print(" ---> Character ");
     Serial.println(j);
   }
   Serial.println("======================");
   Serial.print(readString);
   Serial.println(" --> Read String");
   char response[] = {'L', ',','1', '6', '3', '9', '2','\0'};
   if(strcmp(readString, response) == 0){
     Serial.println("Write Q Here");
     Serial.println("");
   }
   else{
     Serial.println("Strings not Equal");
     Serial.println("");
   }
   readString[0] = '\0';      //clear the array
   index = 0;
 } 
}
//*********************FUNCTIONS***************************
long convertToSteps(int inches){
  long steps = 130435 * inches;  //there are 130435 steps in 1-inch
  return(steps);
}
//**************************************************************************

4  Using Arduino / Programming Questions / Re: Replacing String objects with C strings on: October 17, 2012, 11:24:19 am
Thanks, Paul. I've indexed the array and its working better. I've tried to get an idea of what is in the readSting array by using a FOR loop to print each character and where it is in the array. Just the initialization strings sent from the control board after power up eats up 43 array spots. I copied a portion of the Serial Monitor output showing where I hit the limit switch. The "L,16392" in the readString array seems to be chopped into spaces and some other garbage characters. So, I either need to filter the characters coming into the array so I don't get the garbage. Or, I have to somehow modify my strcmp() function to start looking at the "L" character and then read the array from there. Maybe strbrk() would do this? Any recommendations?

SERIAL MONITOR OUTPUT:

† ---> Character 0

 ---> Character 1
† ---> Character 2

 ---> Character 3
† ---> Character 4

 ---> Character 5
L ---> Character 6
, ---> Character 7
0 ---> Character 8

 ---> Character 9

 ---> Character 10
* ---> Character 11
†
†
†
L,0
* --> Read String
Strings not Equal
-30000XG --> IF LOOP
30000XG --> IF LOOP
-30000XG --> IF LOOP
30000XG --> IF LOOP
-30000XG --> IF LOOP

 ---> Character 0
† ---> Character 1

 ---> Character 2
L ---> Character 3
, ---> Character 4
1 ---> Character 5
6 ---> Character 6
3 ---> Character 7
9 ---> Character 8
2 ---> Character 9

 ---> Character 10

 ---> Character 11
* ---> Character 12

†
L,16392
* --> Read String
Strings not Equal
30000XG --> IF LOOP
-30000XG --> IF LOOP
30000XG --> IF LOOP
-30000XG --> IF LOOP

Code:
/*
CNC Bed Sketch

This program drives a Peter Norburg SD4DEU Stepper Driver board running SD4DNCRouter firmware connecting at 9600 Baud.
 
 
*/

//******************Constants***********
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX

char homePosition[5] = "0XYG";



//******************Variables***********

char readString[70];
char c;
int i = 0;
int commandNumber = 0;
int numCommands = 0;

//****************Function Prototypes******
long convertToSteps(int inches);

//***************Setup******************************
void setup() {
  delay(1000);
 
  //readString[0] = '\0';    //Add a null termination to readString
 
  Serial.begin(9600);    //Begin serial communication at 9600
  mySerial.begin(9600);  //Set software serial baud rate
 
  randomSeed(analogRead(0));
 
  // Initialize Stepperboard Values
  mySerial.write("!");      //reset Stepper Board
  delay(50);
  mySerial.write("1500R");  //Set Run Rate
  delay(50);
  mySerial.write("800P");  //Set Ramp Rate
  delay(1000);
}

//*************Main Program Loop************************
void loop() {
 
 
 char* stepCommand[] = {    //Load up CNC Patterns into string array
 "30000XG",
 "-30000XG"
  };
 
 int numCommands = (sizeof(stepCommand)/sizeof(char*)); //Calculate array size

 while(mySerial.available()){
   c = mySerial.read();   //get one byte from buffer
   readString[i++] = c;    //increment array (original array index is returned)
   readString[i] = '\0';    //Add NULL to next index
   //i=i+1;
   //Serial.print(c);
   //Serial.println(" --> c charachter byte");
   if(readString[i-1]== '*'){
     mySerial.write(stepCommand[commandNumber]);
     Serial.print(stepCommand[commandNumber]);
     Serial.println(" --> IF LOOP");
     commandNumber++;
     if(commandNumber == numCommands){    //if the max number of commands is reached...
        commandNumber = 0;                //reset command number back to zero
     } 
     break;
   }
 }

 mySerial.write("L");
 
 if(strlen(readString) > 0){
   for(int j=0; j < strlen(readString); j++){
     Serial.print(readString[j]);
     Serial.print(" ---> Character ");
     Serial.println(j);
   }
   Serial.print(readString);
   Serial.println(" --> Read String");
   char response[] = {'L', ',','1', '6', '3', '9', '2',' ','\0'};
   if(strcmp(readString, response) == 0){
     Serial.println("Write Q Here");
   }
   else{
     Serial.println("Strings not Equal");
   }
   readString[0] = '\0';      //clear the array
 } 
}
//*********************FUNCTIONS***************************
long convertToSteps(int inches){
  long steps = 130435 * inches;  //there are 130435 steps in 1-inch
  return(steps);
}
//**************************************************************************


5  Using Arduino / Programming Questions / Re: Replacing String objects with C strings on: October 16, 2012, 06:31:59 pm
I'm getting closer. I'm a bit confused on how to make sure readString is null terminated..I just chose the last place in the array and put a '\0' there. I made c a character array and null terminated the second spot. So, now the strcmp() function is working. Looking at the serial monitor output, it makes sense that readString is loading up. I've noticed that if I increase the size of the serialRead array, I get more of my code going through. If I don't make it big enough to accept the initialization/firmware strings from the stepper board, it never gets to the " * " and my motors won't start. If I make the readString array around [40] my code will go load for a while and stop.  If I make it [100], the code runs for a long time, and doesn't seem to stop. Any clue as to what going on here?

The string compare function that compares my limit code "L,16392" to readString still doesn't work, even if I put an * on the end. So, there is still something fishy there, too.

Code:
/*
CNC Bed Sketch

This program drives a Peter Norburg SD4DEU Stepper Driver board running SD4DNCRouter firmware connecting at 9600 Baud.
 
 
*/

//******************Constants***********
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX

char homePosition[5] = "0XYG";



//******************Variables***********

char readString[100];
int commandNumber = 0;
int numCommands = 0;

//****************Function Prototypes******
long convertToSteps(int inches);

//***************Setup******************************
void setup() {
  delay(1000);
 
  readString[99] = '\0';    //Add a null termination to readString
 
  Serial.begin(9600);    //Begin serial communication at 9600
  mySerial.begin(9600);  //Set software serial baud rate
 
  randomSeed(analogRead(0));
 
  // Initialize Stepperboard Values
  mySerial.write("!");      //reset Stepper Board
  delay(50);
  mySerial.write("1500R");  //Set Run Rate
  delay(50);
  mySerial.write("800P");  //Set Ramp Rate
  delay(1000);
}

//*************Main Program Loop************************
void loop() {
 
 
 char* stepCommand[] = {    //Load up CNC Patterns into string array
 "30000XG",
 "-30000XG"
  };
 
 int numCommands = (sizeof(stepCommand)/sizeof(char*)); //Calculate array size

 while(mySerial.available()){
   char c[2] = {mySerial.read(), '\0'} ;   //get one byte from buffer
   strcat(readString, c);
   //Serial.print(c);
   //Serial.println(" --> c charachter byte");
   if(strcmp(c, "*") == 0){
     mySerial.write(stepCommand[commandNumber]);
     Serial.print(stepCommand[commandNumber]);
     Serial.println(" --> IF LOOP");
     commandNumber++;
     if(commandNumber == numCommands){    //if the max number of commands is reached...
        commandNumber = 0;                //reset command number back to zero
     } 
     break;
   }
 }

 mySerial.write("L");
 
 if(strlen(readString) > 0){
   Serial.print(readString);
   Serial.println(" --> Read String");
   char response[10] = "L,16392";
   response[9] = '\0';
   if(strncmp(readString, response, 7) == 0){
     Serial.println("Write Q Here");
   }
   else{
     Serial.println("Strings not Equal");
   }
  readString[0] = '\0';      //clear the array
 } 
}
//*********************FUNCTIONS***************************
long convertToSteps(int inches){
  long steps = 130435 * inches;  //there are 130435 steps in 1-inch
  return(steps);
}
//**************************************************************************



SERIAL MONITOR OUTPUT BELOW:

M1,-12
SD4DNCRouter 4.3 Oct 3, 2011

* --> Read String
Strings not Equal
-30000XG --> IF LOOP
†
* --> Read String
Strings not Equal
30000XG --> IF LOOP
†
* --> Read String
Strings not Equal
-30000XG --> IF LOOP
†
G3* --> Read String
Strings not Equal
30000XG --> IF LOOP
†
L,256
* --> Read String
Strings not Equal
-30000XG --> IF LOOP
†
* --> Read String
Strings not Equal
30000XG --> IF LOOP
†
G2* --> Read String
Strings not Equal
-30000XG --> IF LOOP
†
L,0
* --> Read String
Strings not Equal
30000XG --> IF LOOP

(REPEATING)
6  Using Arduino / Programming Questions / Replacing String objects with C strings on: October 16, 2012, 02:59:41 pm
Hi All,

I'm working on a program that controls a stepper board. The board issues an '*' character each time it finished a command. So, I have some code that waits for the * and then issues a stepper location. The board also issues feedback on location and such. Right now I use a String object to load in the response form the board and print it out to the serial monitor. After feedback on this forum, I'm trying to replace this String object with a character array so that I don't run into memory problems. However, I'm running into compiling problems and I get a lot of "invalid conversion from 'char' to 'const char*'" errors doing what I'm doing. I think there is some char* vs char stuff going on that I don't quite understand.

Here is the code that compiles with my String object. The comparison between the readString object and the "L,16392" isn't working, but that's kinda why I'm trying to change these Objects to C strings...in hopes that I can make that comparison work out. Right now my output looks like it is the same, but the IF statement always says that the strings are not equal.

Code:
/*
CNC Bed Sketch

This program drives a Peter Norburg SD4DEU Stepper Driver board running SD4DNCRouter firmware connecting at 9600 Baud.
 
 
*/

//******************Constants***********
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX

char homePosition[5] = "0XYG";



//******************Variables***********

String readString;
int commandNumber = 0;
int numCommands = 0;


//****************Function Prototypes******
long convertToSteps(int inches);

//***************Setup******************************
void setup() {
  delay(1000);
 
  Serial.begin(9600);    //Begin serial communication at 9600
  mySerial.begin(9600);  //Set software serial baud rate
 
  randomSeed(analogRead(0));
 
  // Initialize Stepperboard Values
  mySerial.write("!");      //reset Stepper Board
  delay(50);
  mySerial.write("1500R");  //Set Run Rate
  delay(50);
  mySerial.write("800P");  //Set Ramp Rate
  delay(1000);
}

//*************Main Program Loop************************
void loop() {
 
 
 char* stepCommand[] = {    //Load up CNC Patterns into string array
 "30000XG",
 "-30000XG"
  };
 
 int numCommands = (sizeof(stepCommand)/sizeof(char*)); //Calculate array size

 while(mySerial.available()){
   char c = mySerial.read();   //get one byte from buffer
   readString += c;
   if(c== '*'){
     mySerial.write(stepCommand[commandNumber]);
     Serial.print(stepCommand[commandNumber]);
     Serial.println(" --> IF LOOP");
     commandNumber++;
     if(commandNumber == numCommands){    //if the max number of commands is reached...
        commandNumber = 0;                //reset command number back to zero
     } 
     break;
   }
 }

 mySerial.write("L");
 
 if(readString.length() > 0){
   Serial.println(readString + " --> ReadString");
   String response = "L,16392";
   if(readString == response){
     Serial.println("Write Q Here");
   }
   else{
     Serial.println("Strings not Egual");
   }
   readString = "";  //clears variable for new input
   }
}
//*********************FUNCTIONS***************************
long convertToSteps(int inches){
  long steps = 130435 * inches;  //there are 130435 steps in 1-inch
  return(steps);
}
//**************************************************************************



And here is my attempt at converting the readString into a C character array. I made an array 20 characters long to hold the myserial.read() data. I'm trying to use the strcat() concatenate function to load charachters into the array, but I get the "invalid conversion from 'char' to 'const char*'" errors. I can get around the errors by pointing to the address of c like:

strcat(readString, &c);  but the output is all garbled up.

Code:
/*
CNC Bed Sketch

This program drives a Peter Norburg SD4DEU Stepper Driver board running SD4DNCRouter firmware connecting at 9600 Baud.
 
 
*/

//******************Constants***********
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX

char homePosition[5] = "0XYG";



//******************Variables***********

char readString[20];
int commandNumber = 0;
int numCommands = 0;
int i = 0;

//****************Function Prototypes******
long convertToSteps(int inches);

//***************Setup******************************
void setup() {
  delay(1000);
 
  Serial.begin(9600);    //Begin serial communication at 9600
  mySerial.begin(9600);  //Set software serial baud rate
 
  randomSeed(analogRead(0));
 
  // Initialize Stepperboard Values
  mySerial.write("!");      //reset Stepper Board
  delay(50);
  mySerial.write("1500R");  //Set Run Rate
  delay(50);
  mySerial.write("800P");  //Set Ramp Rate
  delay(1000);
}

//*************Main Program Loop************************
void loop() {
 
 
 char* stepCommand[] = {    //Load up CNC Patterns into string array
 "30000XG",
 "-30000XG"
  };
 
 int numCommands = (sizeof(stepCommand)/sizeof(char*)); //Calculate array size

 while(mySerial.available()){
   char c = mySerial.read();   //get one byte from buffer
   strcat(readString, c);
   if(c== '*'){
     mySerial.write(stepCommand[commandNumber]);
     Serial.print(stepCommand[commandNumber]);
     Serial.println(" --> IF LOOP");
     commandNumber++;
     if(commandNumber == numCommands){    //if the max number of commands is reached...
        commandNumber = 0;                //reset command number back to zero
     } 
     break;
   }
 }

 mySerial.write("L");
 
 if(strlen(readString) > 0){
   Serial.print(readString);
   Serial.println(" --> Read String");
   char response[10] = "L,16392";
   if(strncmp(readString, response, 7) == 0){
     Serial.println("Write Q Here");
   }
   else{
     Serial.println("Strings not Equal");
   }
   for(int j = 0; j <= 20; j++){
   readString[j] = ' ';  //clears variable for new input
   }
 } 
}
//*********************FUNCTIONS***************************
long convertToSteps(int inches){
  long steps = 130435 * inches;  //there are 130435 steps in 1-inch
  return(steps);
}
//**************************************************************************


Thanks for any guidance here.




7  Using Arduino / Motors, Mechanics, and Power / Re: Communicating with Peter Norburg Stepper Board on: October 16, 2012, 10:40:43 am
Hi There! I'm back with another question. I have my system running pretty good. I've been having trouble communicating with the stepper controller board with respect to reading limit switches when they are triggered on the ends on my CNC bed. So, my code just issues a simple back-and-forth command for the X-axis stepper motor. While this is in motion, I trigger the +X limit switch and try to record the response. The data coming from the stepper board load up into a String object. I know I should change this to an C string array, but its just easier for me at the moment to work with the Objects. Once I have a better handle on it, I'll try to convert my readString object to a character array. Anywho, if I poll the stepper board with an "L" character, it responds with info on what going on with the limit switches. It so happens that "L,16392" corresponds to the +X limit switch getting tripped. I  compare my readString to this string value with an IF statement, but even though the output on the Serial Monitor seems to look the same, the code does not consider them equal. I tried if(readString == String("L,16392")) as well, but that just has the same results. Any ideas? Code and Serial Monitor output below:

Code:
/*
CNC Bed Sketch

This program drives a Peter Norburg SD4DEU Stepper Driver board running SD4DNCRouter firmware connecting at 9600 Baud.
 
 
*/

//******************Constants***********
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX

char homePosition[5] = "0XYG";



//******************Variables***********

String readString;
int commandNumber = 0;
int numCommands = 0;


//****************Function Prototypes******
long convertToSteps(int inches);

//***************Setup******************************
void setup() {
  delay(1000);
 
  Serial.begin(9600);    //Begin serial communication at 9600
  mySerial.begin(9600);  //Set software serial baud rate
 
  randomSeed(analogRead(0));
 
  // Initialize Stepperboard Values
  mySerial.write("!");      //reset Stepper Board
  delay(50);
  mySerial.write("1500R");  //Set Run Rate
  delay(50);
  mySerial.write("800P");  //Set Ramp Rate
  delay(1000);
}

//*************Main Program Loop************************
void loop() {
 
 
 char* stepCommand[] = {    //Load up CNC Patterns into string array
 "30000XG",
 "-30000XG"
  };
 
 int numCommands = (sizeof(stepCommand)/sizeof(char*)); //Calculate array size

 while(mySerial.available()){
   char c = mySerial.read();   //get one byte from buffer
   readString += c;
   if(c== '*'){
     mySerial.write(stepCommand[commandNumber]);
     Serial.print(stepCommand[commandNumber]);
     Serial.println(" --> IF LOOP");
     commandNumber++;
     if(commandNumber == numCommands){    //if the max number of commands is reached...
        commandNumber = 0;                //reset command number back to zero
     } 
     break;
   }
 }

 mySerial.write("L");
 
 if(readString.length() > 0){
   Serial.println(readString + " --> ReadString");
   if(readString == "L,16392"){
     Serial.println("Write Q Here");
   }
   else{
     Serial.println("Strings not Egual");
   }
   readString = "";  //clears variable for new input
   }
}
//*********************FUNCTIONS***************************
long convertToSteps(int inches){
  long steps = 130435 * inches;  //there are 130435 steps in 1-inch
  return(steps);
}
//**************************************************************************


L,0
* --> ReadString
Strings not Egual
-30000XG IF LOOP
†
†
†
L,0
* --> ReadString
Strings not Egual
30000XG IF LOOP
†
†
†
L,16392
* --> ReadString
Strings not Egual
-30000XG IF LOOP
†
†
†
L,16392
* --> ReadString
Strings not Egual
30000XG IF LOOP
8  Using Arduino / Programming Questions / Re: random integers to string arrays on: October 10, 2012, 12:02:34 pm
Ah, "l" for a long integer. That made it work.

Many props,
---> Karl
9  Using Arduino / Programming Questions / Re: random integers to string arrays on: October 10, 2012, 11:03:53 am
PeterH,

This method is close to working. I can get the X value to print in there, but the Y value seems to be chopped to either a 0 or -1.


Code:
/*
Test program to convert random integers into strings commands to send to Stepper Control Board.
 
*/

//******************Constants***********


//******************Variables***********



//****************Function Prototypes******


//***************Setup******************************
void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(0));
 
 
}

//*************Main Program Loop************************
void loop() {

long randNumber_X1 = random(-10000, 10001);
long randNumber_Y1 = random(-10000, 10001);
long randNumber_X2 = random(-10000, 10001);
long randNumber_Y2 = random(-10000, 10001);

Serial.print(randNumber_X1);
Serial.print(" ");
Serial.println(randNumber_Y1);

 
 const int LEN=20; // pick a number big enough to hold your longest command string + 1
 char command[LEN];
 sprintf(command, "%dX%dYG", randNumber_X1, randNumber_Y1);
 Serial.println(command);
 
}
//*********************FUNCTIONS***************************

//**************************************************************************


And the Serial Monitor output is below. The first line just prints the random numbers, the second is the sprintf conversion. Any clue as to whats up?

8899 -3632
8899X0YG
4295 -5583
4295X0YG
-2445 -3267
-2445X-1YG
-5280 -9285
-5280X-1YG
342 -2815
342X0YG
-5991 -3474
-5991X-1YG


10  Using Arduino / Programming Questions / random integers to string arrays on: October 08, 2012, 06:00:33 pm
Hi All,

I'm working on a project where I have to send string commands to a stepper motor controller. These commands look typically like "10030XYG" or "-1500X45000YG" and tell the control board how many steps to move the X or Y motors. I have a separate program that can take commands that I type in, load these command strings into an array, and send them out to the control board as needed. But, what I really want to to is randomly generate the X and Y positions, convert those to strings, append the X/Y/G charachters, and then load them into the array.

I'm trying to get my head around getting everything in a string format that will load into the "char* stepArray[]" string array. So, I made another test program shown here in order to get this portion to work. I'm using String objects for now, but they don't seem to agree with the char* stepArray[].  I get a "String_Tests:51: error: cannot convert 'String' to 'char*' in initialization" error line. I understand string objects are not recommended due to memory issues. But, so far, trying to get one command string out of a character array is proving difficult. I've also fooled around with using "ltoa" to convert the random long numbers into strings, but then I have to append the letters and so forth.

I think that if I can get my stepArray[] array to load up, I should have this issue licked. Thanks for any help and recommendations,
--> K

Code:
/*
Test program to convert random integers into strings commands to send to Stepper Control Board.
 
*/

//******************Constants***********


//******************Variables***********
String stepCommand = "";


//****************Function Prototypes******


//***************Setup******************************
void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(0));
 
 
}

//*************Main Program Loop************************
void loop() {

long randNumber_X1 = random(-10000, 10001);
long randNumber_Y1 = random(-10000, 10001);
long randNumber_X2 = random(-10000, 10001);
long randNumber_Y2 = random(-10000, 10001);

 Serial.print(randNumber_X1);
 Serial.print(" ");
 Serial.println(randNumber_Y1);
 
 Serial.print(randNumber_X2);
 Serial.print(" ");
 Serial.println(randNumber_Y2);
 
 String firstPosition = stepCommand + randNumber_X1 + "X" + randNumber_Y1 + "Y" + "G";
 String secondPosition = stepCommand + randNumber_X2 + "X" + randNumber_Y2 + "Y" + "G";
 String homePosition = "0XYG";
 
 Serial.println(firstPosition);    //This prints to Serial Monitor as expected
 Serial.println(secondPosition);  //This prints to Serial Monitor as expected
 Serial.println(homePosition);  //This prints to Serial Monitor as expected
 
 char* stepArray[] = {    //Load up CNC Patterns into string array. HOW TO LOAD STRINGS???
  firstPosition,
  secondPosition,
  homePosition
  };
 
   
 
}
//*********************FUNCTIONS***************************

//**************************************************************************

11  Using Arduino / Motors, Mechanics, and Power / Re: Communicating with Peter Norburg Stepper Board on: October 04, 2012, 02:54:23 pm
Alright, I have the software.serial stuff working pretty well. My stepper commands are coming from pins 2 & 3 and don't interfere with the serial.print commands that I send to the serial monitor. There is something goofy going on with trying to receive the data from the stepper board and then print it to the monitor. This could be from some sort of interference between the serial and software.serial commands running at the same time, or like you said, maybe how I'm trying to read the string.

Quote
Serial.available() returns the number of characters currently in the buffer.  If it returns a value greater than zero, then there are that many characters in the buffer right then and there.  If removing the delay() caused your code not to work the way you want, then that's symptomatic of another problem.

I see what you're saying. I tried again without the delay and it seems to work now. Maybe it was just buggy before I tried the software.serial method.

Code:
/*
CNC Bed Sketch

This program drives a Peter Norburg SD4DEU Stepper Driver board running SD4DNCRouter firmware connecting at 9600 Baud.
 
 
*/

//******************Constants***********
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX

char* stepCommand[] = {    //Load up CNC Patterns into string array
  "10000X",
  "G",
  "-10000X",
  "G",
  "0X",
  "G",
  "10000Y",
  "G",
  "-10000Y",
  "G",
  "0Y",
  "G"
  };
 
const int numCommands = (sizeof(stepCommand)/sizeof(char*)); //Calculate array size

//******************Variables***********
String readString;
int commandNumber = 0;
//****************Function Prototypes******


//***************Setup******************************
void setup() {
  Serial.begin(9600);    //Begin serial communication at 9600
 
  mySerial.begin(9600);  //Set software serial baud rate
 
  mySerial.write("!");      //reset Stepper Board
  delay(50);
  mySerial.write("1500R");  //Set Run Rate
  delay(50);
  mySerial.write("800P");  //Set Ramp Rate
  delay(50);
 
  Serial.println("Starting Serial"); //Signal start of communication
 
  Serial.print("String Array Size = ");
  Serial.println(numCommands);
 
  Serial.println("<<<<<Commands Below>>>>>>");    //This just prints the given string commands to see if they are being sent correctly
  for (int i = 0; i < numCommands; i++){
   Serial.println(stepCommand[i]);
   }
   
  Serial.print("<<<<<Commands Above>>>>>");
 
  delay(1000);
}

//*************Main Program Loop************************
void loop() {
    while(mySerial.available()){
      //delay(100);                //Wait for buffer to fill
      char c = mySerial.read();   //get one byte from buffer
      readString += c;
      if(c== '*'){
        mySerial.write(stepCommand[commandNumber]);
        Serial.println(stepCommand[commandNumber]);
        commandNumber++;
          if(commandNumber == numCommands){    //if the max number of commands is reached...
            commandNumber = 0;                //reset command number back to zero
          } 
        break;
      } 
    }
    if(readString.length() > 0){
      Serial.println(readString);
      readString = "";  //clears variable for new input
   }
}
//*********************FUNCTIONS***************************

//**************************************************************************


This is the output from the serial monitor. You can see that the list of commands print to the monitor fine. But, the strings put together by the "readString" object come out all jumbled. My cut-n-paste doesn't show it, but add hieroglyphic symbols appear where a blank space is shown below. Even though this comes out with weird charachters, my motors are moving according to plan. I've seen this before with mismatched baud rates, but everything here is 9600. It doesn't seem to affect the operation of the CNC bed, so I guess its no big deal.


Starting Serial
String Array Size = 12
<<<<<Commands Below>>>>>>
10000X
G
-10000X
G
0X
G
10000Y
G
-10000Y
G
0Y
G
<<<<<Commands Above>>>>>10000X

M1,-12
SD4DNCRouter 4.3 Oct 3, 2011

*
G
†
*
-10000X
†
*
G
†
G3*
0X
†
*
G
†
G2*
10000Y
†
*
G
†
G1*
-10000Y
†
*
G
†
G0*
†
†

0Y
G0*


Thanks for your help. Much appreciated. I'll review C strings and see if I can make all that work.
12  Using Arduino / Motors, Mechanics, and Power / Re: Communicating with Peter Norburg Stepper Board on: October 03, 2012, 12:57:20 pm
Okay. I think I understand what going on a little more. Thanks for your help!

Now, I've dicked around with the code and found that the Serial.print command is what screwing everything up. I commented out all the lines of code that I intended to print to the Serial Monitor and the bed is moving as expected. How can I separate the instructions for the stepper board from the data I'd like to print on the Serial Monitor. Is software.serial the solution here?


Code:
/*
CNC Bed Sketch

This program drives a Peter Norburg SD4DEU Stepper Driver board running SD4DNCRouter firmware connecting at 9600 Baud.
 
 
*/

//******************Constants***********

const int numCommands = 12;
char* stepCommand[numCommands] = {    //Load up CNC Patterns into string array
  "1000X",
  "G",
  "-1000X",
  "G",
  "0X",
  "G",
  "1000Y",
  "G",
  "-1000Y",
  "G",
  "0Y",
  "G"
  };
 

//******************Variables***********
String readString;
String writeString;
int commandNumber = 0;
//****************Function Prototypes******


//***************Setup******************************
void setup() {
  Serial.begin(9600);    //Begin serial communication at 9600
  pinMode(0, INPUT);      //0 Pin is RX
  pinMode(1, OUTPUT);    //1 Pin is TX
 
  Serial.write("*");      //send initial "*" to start Stepperboard
 /*
  Serial.println("Starting Serial"); //Signal start of communication
 
  Serial.print("String Array Size = ");
  Serial.println(numCommands);
 
  Serial.println("<<<<<Commands Below>>>>>>");    //This just prints the given string commands to see if they are being sent correctly
  for (int i = 0; i < numCommands; i++){
   Serial.println(stepCommand[i]);
   delay(500);
   }
  Serial.print("<<<<<Commands Above>>>>>");
  */
  delay(1000);
}

//*************Main Program Loop************************
void loop() {
    while(Serial.available() > 0){
      delay(100);                //Wait for buffer to fill
      char c = Serial.read();   //get one byte from buffer
      readString += c;
      if(c== '*'){
        Serial.write(stepCommand[commandNumber]);
        commandNumber++;
          if(commandNumber == numCommands){    //if the max number of commands is reached...
            commandNumber = 0;                //reset command number back to zero
          }
        //delay(500);
        break;
      } 
    }
    //if(readString.length() > 0){
    //  Serial.println(readString);
     // readString = "";  //clears variable for new input
  // }
}
//*********************FUNCTIONS***************************

//**************************************************************************

Quote
And while this probably isn't exhibiting itself as any sort of problem, there's no reason to have a delay between Serial.available() and Serial.read().

FYI. I tried taking out the delay here and the while loop just runs through. There needs to be a slight delay in order for the buffer to load in a character, it seems.

About the Strings Objects:
You recommend dealing with collecting the incoming characters in an array rather than the string object? Like how I loaded all my command strings into the char* stepCommand[ ] array?

Using SoftwareSerial:
If I move the stepperboard IO to two other pins, will that send all Serial.println commands ONLY to the serial monitor and my Serial.write commands ONLY to my stepperboard? I'm trying to figure how I can print debug data to the serial monitor without freaking out the stepperboard.

Thanks a lot for your help. I'm psyched that I have this thing moving around now. Cool shit.

--> Karl

13  Using Arduino / Motors, Mechanics, and Power / Re: Communicating with Peter Norburg Stepper Board on: October 03, 2012, 11:48:00 am
Thanks for the help! I'm going to try your suggestions. A couple clarification questions:

Quote
Your calculation of the number of elements in this array is incorrect.  It's basically returning the total number of characters in the array, not the number of full command strings.  The way you're defining the array, there's no easy way to calculate the number of commands in the array.  Best to just handle that semi-manually, either with a #define or a const param. 

const int numCommands = (sizeof(stepCommand)/sizeof(char*));
This line of code gives me a value of 12, which seems to be right to me. Maybe even though I have 12 commands, this isn't the correct array size? I'm going to try your method, just trying to figure out why this doesn't work so I can understand what going on here.



Quote
Beyond that, you'll likely run into problems with your String objects as well.  Best just not to use them.  They thrash memory pretty hard.

The stepper board is controlled with commands like "1000X" which is a string, right? How would I get around using string objects?

Thanks a ton,
-->K
14  Using Arduino / Motors, Mechanics, and Power / Communicating with Peter Norburg Stepper Board on: October 03, 2012, 10:25:27 am
Hi All,

This is the first project that I've had to communicate between a separate board and and Arduino via TTL. I'm building a little CNC bed for a sculpture that uses a Peter Norburg SD4D stepper controller card and two bipolar 3A stepper motors. The Norburg card is nice for this, as you can throw it commands and it will automatically sync the motors, plus automatically calculate arcs and circles for the bed. The board I'm using is below:

http://www.stepperboard.com/prod11-SD4D.htm

The Norburg card sends an "*" charachter after its completed a move to tell you that its ready for the next command. So, for instance, if I wanted my bed to move 1000 steps in the X direction, I would first send it "1000X", wait for the "*" response, then send it "G", which tells it to go. After the motors complete this movement, it responds with a "*" again. I have the RX (pin 0) connected to the SO (Serial Out) and TX(pin 1) to SI(Serial In) on the Norburg. The stepper board comes with a Simple Serial program where you can issue line commands via USB. I've done this and can get both motors to follow simple X & Y commands, so I know the connection between the stepper board, stepper drivers and motors is working fine.

So, I've searched the internets for some code to poll for the "*" and found the following. This works, but its patchy. Say, it may get through 70% of the commands, but then just hangs. I've got a few things that I'm unfamiliar with or have reoccuring problems:

1) I/O & USB problems at Upload: I seem to keep getting "avrdude: stk500_getsync(): not in sync: resp=0x00" message when I try up upload new code when my IO wires are connected. Any way around this?

2)Serial Monitor vs I/O: Whats the different between Serial.print and Serial.write? If I'm using Serial.Print to show whats up on the Serial Monitor, are these also getting sent to the stepper controller? Or, is it only when Serial.write is used that data is sent via the I/O pins? Because when I'm just printing my operations via Serial.Print at the beginning of my code, the motors seem to be freaking out a little bit. Actually, just opening or closing the Serial Monitor window seems to have an effect on my code. If I comment out the Serial.Print commands, the motors seems to stay idle.

3) As I mentioned above this code gets part way through the command list, but then just hangs. The Serial Monitor shows that "*" charachters are being returned. But for some reason it just balls up. Any ideas on how to debug this so that I can see if what commands are being issued to the stepper board?

Code:
/*
CNC Bed Sketch

This program drives a Peter Norburg SD4DEU Stepper Driver board running SD4DNCRouter firmware connecting at 9600 Baud.
 
 
*/

//******************Constants***********
char* stepCommand[] = {    //Load up CNC Patterns into string array
  "1000X",
  "G",
  "-1000X",
  "G",
  "0X",
  "G",
  "1000Y",
  "G",
  "-1000Y",
  "G",
  "0Y",
  "G"
  };
  
 const int numCommands = (sizeof(stepCommand)/sizeof(char*)); //Calculate array size
 

//******************Variables***********
String readString;
String writeString;
int commandNumber = 0;
//****************Function Prototypes******


//***************Setup******************************
void setup() {
  Serial.begin(9600);    //Begin serial communication at 9600
  pinMode(0, INPUT);      //0 Pin is RX
  pinMode(1, OUTPUT);    //1 Pin is TX
  
  //Serial.write ("200R");                //Set Run Rate to 200 steps/sec
  //Serial.write("-12?");              //This line returns SD4D firmware version. Uses to check polling code below
 
  Serial.println("Starting Serial"); //Signal start of communication
 
  Serial.print("String Array Size = ");
  Serial.println(numCommands);
  
  Serial.println("<<<<<Commands Below>>>>>>");    //This just prints the given string commands to see if they are being sent correctly
  for (int i = 0; i < numCommands; i++){
   Serial.println(stepCommand[i]);
   delay(500);
   }
  Serial.print("<<<<<Commands Above>>>>>");
  
  delay(1000);
}

//*************Main Program Loop************************
void loop() {
    while(Serial.available() > 0){
      delay(100);
      char c = Serial.read();   //get one byte from buffer
      readString += c;
      if(c== '*'){
        Serial.write(stepCommand[commandNumber]);
        commandNumber++;
          if(commandNumber == numCommands){    //if the max number of commands is reached...
            commandNumber = 0;                //reset command number back to zero
          }
        //delay(500);
        break;
      }  
    }
    if(readString.length() > 0){
      Serial.println(readString);
      readString = "";  //clears variable for new input
   }
}
//*********************FUNCTIONS***************************

//**************************************************************************

This is what comes up on my Serial Monitor:

h1000X    (The "h" command isn't in the above code. I added that and its a status ping for the stepper board)
I4*           (the I4 is the status return)
G
*
-1000X
*
G
*
0X
*
G
*
1000Y
*
G
*
-1000Y

I deleted a LOT of carriage returns from the Serial Monitor. The carriage returns increase as the commands are issued. By the time I get to where the code balls up, its all carriage returns. I don't know what that means.

Thanks for any help! Let me know if I'm leaving out any info....
--. Karl
15  Using Arduino / Motors, Mechanics, and Power / Re: Adding decoupling capacitor to Vin on: March 08, 2012, 12:29:42 pm
The motors are 12v and are also running off of the 12v wall wort. The arduino sends signals to transistors that trip the relays through the digital out pins . I do use the +5v pin on the Arduino to supply voltage to actually trip the relays. I suppose this could be it...perhaps running the 5v to more than one relay coil could be too much. Maybe I should be supplying the 5v for the relay coils from the wall wort via a voltage regulator rather than straight from the Arduino board. I'll try this next.

I tried jumping a 330uf capacitor between the Vin and ground pins to filter out noise. No real luck there as the Arduino still trips.

Thanks for the help!

****UPDATE*****

Okay, using the +5v pin to trip the relays seems to be the problem. I used a 5v voltage regulator instead and it seems to have eliminated the reset problem. I guess I don't understand why I don't get reset issues when running off of USB power, because the board still has to supply the same 5v to the relays. Maybe with 12volts coming into the Arduino and 5v going out, its just too much power transfer for the board to take.
Pages: [1] 2