AXNRXN

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?

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>>>>>");

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

char stepCommand[][]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. I would include this value in the declaration of your array as well, like:

char* stepCommand[numCommands]Doing so will cause a compile error if your param does not agree with your array (if you add another command to the array and forget to update numCommands value, it won't compile)

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.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().

AXNRXN

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?

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.

Hmm, apparently I have misunderstood how sizeof() works in that situation. If it's returning the correct array size, then ignore my comments, they're apparently incorrect.

On the String objects though, your commands are stored in C strings, which are just arrays of chars. The String objects I'm referring to are

Those are String objects. The String class isn't working properly in the current version of Arduino and causes memory leaks over time. Switch them to C strings as well.

As for your other questions...

1: You cannot have multiple devices connected to the serial port at the same time. If your stepper controller is connected to the serial port, then you can't connect to it with your PC (the usb port ties into that serial port. The Uno only has the 1 hardware uart). You could move the stepper controller to a softwareserial port on any of the other pins, allowing you to communicate with the Uno with the computer via USB while it's connected to the stepper controller.

2: Serial.print(100) will send the string "100" out the serial port as 3 bytes of data corresponding the characters 1, 0, and 0. It converts data to human readable ascii. Serial.write(100) sends the numeric value of 100 out the serial port as a single byte of data. When transmitting char data the output is the same either way. In general though, if the intent is to transmit human readable text, use print/println.

AXNRXN

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?

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);}

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.

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.

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.

Quote

You recommend dealing with collecting the incoming characters in an array rather than the string object?

Yes.

Quote

Like how I loaded all my command strings into the char* stepCommand[ ] array?

Sorta. Working with C strings requires more effort than working with String objects, which is why most people are so fond of using Strings. If you aren't very familiar with manipulating C strings, googling C string tutorial should provide plenty of guidance. There are a lot of C library functions for handling all the heavy lifting, so it's not all that much more effort than using a String class. It's just not all wrapped up in a nice package for you.

Quote

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.

If you use the software serial class to communicate with the stepperboard, you'll create a new serial object associated with those pins and use that object to communicate with the board, not Serial. Something like...

AXNRXN

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.

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]); }

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.

AXNRXN

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:

L,0* --> ReadStringStrings not Egual-30000XG IF LOOP???L,0* --> ReadStringStrings not Egual30000XG IF LOOP???L,16392* --> ReadStringStrings not Egual-30000XG IF LOOP???L,16392* --> ReadStringStrings not Egual30000XG IF LOOP