NewB: XY plotter,how do i get xy position?!

Hello all, I am an artist - new to arduino. I am building a simple XY plotter. I am using motors (lead screws) from 2 identical scanners. Before i get started i have a simple question, that keeps me up at night. for example: How will mr.Arduino keep up with the changing position of the X-axis? How will it know if it is at 0% or 100%? If a make the lead screw longer (for larger canvas), how will it adapt?

Is it a scale from 0%-100%,is it millimeters, is it a formula involving RPM,track length,wheel radius? Are there 'tick marks' to count?

I am sure this question has already been answered but I don't know the proper terminology to find it. I am sure u veterans can point me in the right direction. Thanks ladies and gents, arduino is going to change the way i do my art!

I've been working on this as well, I got my Arduino to determine the distances by following absolute numbers of steps. Find out how many steps it takes to move an inch (or centimeter) and multiply that by the total length of that axis. My Y axis total travel is 40" long, and it takes 3500 steps to go one inch, so 3500 * 40 = 168000 steps. Say I want the axis to run 5.5 inches, find the fraction by dividing one inch by 2 to get the number of steps for half an inch (1750 steps) then go 3500 * 5 + 1750.

I've never been good at math, but I managed to get this done to where it works, if there's a better way to do that calculation I'm all ears. I wrote a small processing sketch that takes arrow key input to move a tenth of an inch at a time in either direction. It shows the position, as well as a diagram showing where the tool head should be, and outputs the data as a string looking like "X000000Y000000". All I have to do is get that to the Arduino so I can tell it that each time it takes in that string, to move each motor that number of steps. It's easy enough to use "if" statements to make sure it will run the correct direction:

if (axisXvalue > currentPosition && axisValue < axisTotalTravel) {
  axisXmotor.step(axisXvalue, FORWARD, SINGLE);
}

When I get home I'll post the processing code which I wrote to make it easier to hone the system and play with it manually.

The part that's been keeping me up at night is trying to figure out how to make the Arduino take in the data string through serial and parse it. I downloaded the String library which should make parsing it easier, but where I'm hung up is on how to make the Arduino create a string based on the input. When the Arduino reads serial data, it reads it one character at a time. There doesn't seem to be a simple way to assemble all of the characters into a string to parse. I don't really need a full string, if I could just get the numbers into separate integer values for each axis I'd be fine. Anyone have any ideas as to how to do this?

I already tried the liquidCrystal examples, but they just output one character at a time. I need a way to make a variable, and append each digit on to the end of the variable. The String library has a function called "append()", but it doesn't provide any useful information on how to use it. I also tried loading all the characters into an array, but I have no idea how to turn that array into a single multi-digit variable.

When I get home, I'm going to try looking directly at the String library file and see if I can figure out how the append() function works, but if anyone has a better idea, please let me know. I've spent too much time trying to create a data string from serial, it would be nice to get back to drawing lines on my machine. Also when I get home, I'll post the code I already have as well as the processing code for generating the values.

Counting as Parcanman will work, but you will need to implement home (and end-of-travel) switches for each each axis, and on occasion bump up against them (at the very least at the beginning) to re-align everything. This is because no matter how you design such a table, there is always going to be some "slop" (also known as "backlash") in the system.

You might also want to check out some of the homebrew CNC forums and sites for information; they are doing exactly the same thing as you (and would be needing a ton more accuracy than what you need).

Also look into the possibility of absolute encoders (vs incremental encoders, which just count steps and possibly travel direction); such encoders, connected to appropriate gearing so that they only turn so much per linear-unit of travel, might also be helpful (however, they aren't cheap, and are difficult to construct).

:slight_smile:

When the Arduino reads serial data, it reads it one character at a time. There doesn't seem to be a simple way to assemble all of the characters into a string to parse. I don't really need a full string, if I could just get the numbers into separate integer values for each axis I'd be fine. Anyone have any ideas as to how to do this?

This code will get all the serial data into a character array:

int index;
char inData[24]; // Or whatever size is needed

void loop()
{
   index = 0;
   while(Serial.available() > 0)
   {
       char aChar = Serial.read();
       inData[index] = aChar;
       index++;
       inData[index] = '\0';
   }

   // inData now contains all the serial data
   // that was available in a NULL-terminated array
}

There are a number of issues with this approach. All the available serial data is stuffed into the array. But, you have no idea whether that data represents a complete packet, less than a complete packet, or more than one packet.

Depending on how the data is being sent, there are solutions for these issue.

If you can send the data like this:

<123,107>

Then, the start of packet marker (<) can be detected, as can the end of packet marker (>). The Arduino can collect whatever data is available, and append it to the string being built. It can know whether to use the string, because an end of packet marker has arrived (after a start of packet marker), or not to, because the end of packet marker has not (yet) arrived.

The string can then be parsed, based on the , as a delimiter, or the values need not be stored in a string at all, if only integer data is to be dealt with.

More details on your part == more help on our part.