Arduino Rotary Table for Dummies

Home Model Engine Machinist Forum

Help Support Home Model Engine Machinist Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
ignator,

Thank you. I will look at your keypad information in the near future. I don't want to sound like a complainer or excuse maker but it seems like my family doesn't understand the definition of the word "retirement" the same way that I do. The fact that I have finally made this rotary table work in a way that I had never even thought about a couple of months ago is encouraging so I will continue on.

Len
From your previous post, it appears you have the keypad working. You need to see what changes you did per weir-smith suggestions, as to if this caused some program math error for it to spin continuously. You should not live with that.
This is my whole point of "instrumenting" the code, to see what it is doing while running. The serial monitor is the easiest way to do this. Mainly printing out program variables that change during operation. There is no magic going on here. There may be bugs, but no magic.
 
Len

I only tested all of the values that I use and all worked well. However, 360 was not one of them and you are correct that anything over 329 deg causes the stepper to rotate continuously. I will need to brush up my C++ and have a look at what is happening however, my first thought is that it is not the code but the limitations of the Arduino for example, it only has a resolution of 10 bits. We shouldn't lose sight of the fact that this micro controller was developed as an entry level device primarily for academic applications however, it is still a very useful device without going to something more complex and they are cheap at $14.

That been said, it doesn't mean that there is not a work around - just needs some thought. I have built three of these units with two being for other people so I need to get to the bottom of the problem. The thing to do first, is to decide what it is that you want from the controller and then solve the problem from there. I use mine primarily for drilling holes in a circle where I don't have to remember where I am in the degrees count. I also machine part circles on a job requiring that. I do not use it for cutting gears as I prefer to use indexing plates to avoid the accumulation error. There are program changes out there that go some way to correct this error. For continuous rotation, I use a seperate module $10 worth and a changeover switch to achieve it. The unit provides variable speed, CW and CCW rotation and emergency stop - love Ebay.

I am providing my email address so if you would like the solution, I can send it to you directly and I am also happy to send you the information on the continuous rotation module. Just send me an email so that I can respond. I have been retired for seven years now and my family still think that they need to give me tasks to do, to keep me out of trouble. Little do they know so I can appreciate your comment.


[email protected]

Bruce
 
it only has a resolution of 10 bits
That is the resolution of the analog to digital converter. This is not used for this all digital rotary table controller.
I'm looking at the code for the first time, and it uses floating point variables for the stepper angle. These are 4 byte long, i.e. 32 bit. But I don't know the detail format of the math library. I see a divisor of 360.0 degrees, but looking at the math to see if the motor exceeds 360 degrees, appears OK. The code for the forward steps;
if(key == 'A') // FORWARD
{
TotalDegrees = TotalDegrees + Degrees;
if (TotalDegrees > 360.0) { // When making a full rotation, restart count at 360 degrees
TotalDegrees = TotalDegrees - 360.0;
}
if ( TotalStepsActual == (int) MicroStepsPerFullRotation) {
TotalStepsActual = 0;
TotalStepsTheoretical = 0.0;
}
TotalStepsActualPrevious = TotalStepsActual; // Save current steps total as previous total
TotalStepsTheoretical = TotalStepsTheoretical + StepsPerIncrementTheoretical;

/*
Round up to integer actual total number of steps moved.
If a fractional value is N.5 or greater, adding .5 will increase the interger portion to N+1.
Conversion to int will truncate any fractional part. Result is that any number with a fractional
part of >=.5 will be round up; <.5 will be rounded down.
*/
TotalStepsActual = (int) (TotalStepsTheoretical + 0.5);

StepsToMove = TotalStepsActual - TotalStepsActualPrevious;

digitalWrite(dir, LOW);
printadvance();
}

The code to step the motor is;

rotation(StepsToMove,0); //this is the function call to 'rotation' that steps the motor located in the function printadvance


..................|-------This should be int declaration
void rotation(float tm, int d) //tm is the passed variable of StepsToMove, the variable 'd' is not used. I'm guessing this was direction at one time
{
for(int i = 0; i < tm; i++) //a simple loop counter, so what could cause this to overflow?
{
digitalWrite(stp, HIGH);
delay(stepdelay);
digitalWrite(stp, LOW);
delay(stepdelay);
}
}
_______________

I can't see the problem, someone who has the setup can see what is going on in the rotation function with the tm variable. I'm confused that 'tm' is a float, and this might trip up the integer counter variable 'i' comparison for some values of 'tm'. In my mind this should cause a compiler flag as type mismatch.
edit;
StepsToMove is declared as a integer in line 88 of the program. I believe this is an error having tm declared as a float in the function 'rotation' which passes in an integer and then converted to a float.
 
Last edited:
It seems like the issue is fundamentally software. Instead of adding hardware (arduino) to solve it, why not just use an integrated solution (Massimo, planetCNC, SuperGerbil) ?
 
Len

I did a quick test today and changed the multiplier to 50 rather than 100 which then requires a total count of 18,000 rather than 36,000. I also selected divide by 1 rather than divide by two on the stepper controller. The unit then worked to 640 deg before the problem returned.

A review of the Arduino spec shows the upper count limit (integer) is 32,767 due to the 8 bit arithmetic which ties in with the above test. As pointed out, StepsToMove is an integer and if changed to float, it should overcome the overflow problem. I will have a play this afternoon.

Bruce
 
Len

I did a quick test today and changed the multiplier to 50 rather than 100 which then requires a total count of 18,000 rather than 36,000. I also selected divide by 1 rather than divide by two on the stepper controller. The unit then worked to 640 deg before the problem returned.

A review of the Arduino spec shows the upper count limit (integer) is 32,767 due to the 8 bit arithmetic which ties in with the above test. As pointed out, StepsToMove is an integer and if changed to float, it should overcome the overflow problem. I will have a play this afternoon.

Bruce

As long as you don't require negative values (which I don't think you do) you could change your integer to an unsigned int which changes your upper limit to 65,535 while still being 16 bit. If you need more, you can change to a 32 bit unsigned long, which again won't give you negative values but will go all the way up to 4,294,967,295. Either should be a relatively simple alteration.
 
Al and Len

I just had a look at the code and there is a mix of integer and float in the steps counter as noted by Len. So just changing the "i" from int in the counter loop to float (line 12 from the bottom of the sketch) cures the problem and I tested it to well past 360 deg. Al, your suggestions would also work so thanks for your input. Just shows that you need to test the limits etc.

Bruce
 
For what it's worth, when I revised the code for my indexer, my general approach was to do all the preliminary calculations using floats and the actual steps with integers. To keep the steps integer from overflowing I reset to zero after a full rotation.

I'm still not entirely happy with my revisions. I started with bmac2's program (which I am not knocking - it's good code but needed revision to work with my stepper/planetary gear setup). I ended up making a lot of modifications some of them just stylistic, some of them to educate myself, and some of them to try a different approach. I believe my code works, but it's not as clean as I would like it to be and I am considering starting over again with a blank slate. Meanwhile I have successfully cut a couple of gears with it, so I'm happy for now.

Now some people will say you should avoid using floats with an Arduino because they take up more space than integers and take longer to calculate, but for an application like an indexer the differences are inconsequential.

If you're new to Arduino programming like me (I've done programming before, but just getting into Arduino), here's a good tutorial on data types:

https://learn.sparkfun.com/tutorials/data-types-in-arduino/all

My build:

https://www.homemodelenginemachinis...nic-arduino-rotary-indexer-another-one.27394/
 
The code that I was commenting on is your version 7.0 I don't have the hardware setup on my Arduino so I can not see why the loop counter was going bonkers, all I could do is look at data types and such. I am not an Arduino or "C" program language expert. Most of my experience was assembly, Fortran, PL1, and an interpreter call ADATE (written in ADA). I really like how Arduino has simplified coding, as it hides the operating system, and hardware interfaces.
 
It looks to me like the new sketch did not actually get loaded. If you look at the link below you will see pictures of what the display should look like. In particular, when you first power up you should see something like:

It is very possible that I'm doing something basically wrong. My assumption was that loading one program into the Arduino and then by loading another into it would totally erase the first program and replace it with the second program. This appeared to be true with a couple of the things that I tried and this is what I did when trying to load and run your version 7. Am I doing it right or is there a purge-type process that has to be accomplished first? I had looked at your screen shots and the result that I was getting made me wonder if the two sketches had inter-scrambled in some fashion.

The question was raised "what is it going to be used for?". To recall, my part of this adventure started with trying to come up with a power feed for my lathe compound to achieve smoothness. When I heard about the Arduino and using it to control a rotary table my interest slightly shifted. I had looked quizzically at the Grizzly 4" rotary table but that seemed too small for my desires especially since I already have a Phase II 8" table. The idea of fitting that with a controller more precise than my fingers and eyesight woke up the interest in me. I would like to (more easily) use the table for machining a flywheel and possibly getting into gear making (I do have a manual indexing head that could be fitted this way also). And, as with any of these machining tools, once you have it you start dreaming up new ways to use it.

Len
 
It seems like the issue is fundamentally software. Instead of adding hardware (arduino) to solve it, why not just use an integrated solution (Massimo, planetCNC, SuperGerbil) ?

I had no idea what you were talking about when I first read your post so I did a search for the things you mentioned. I found nothing on Massimo in relation to stepper motor controls. Planet CNC seems to have ready made controller boards to run anything but their boards are 4-axis and 9-axis - this is single axis stuff. SuperGerbil sounds like they are a startup company trying to get pre-orders so they can gear up to build their boards.

Is any of this equipment such that it's closer to plug-and-play for the 'software challenged' hobbyist?
 
weir-smith and ignator - Thanks for the clarifications. You are right about that loop counter - needs to be fixed. In fact I went back over the code and found a couple of nasty bugs, as well as some minor inconsequential ones. Hopefully I have now fixed them all in updated version 7.14 which is now available here:

https://sites.google.com/site/lagad...es-mills-etc/build---electronic-indexing-head

Some related comments: The old code worked OK for my set-up because the settings for my hardware do not lead to an integer overflow. However, when I experimentally changed the settings to a high micro-stepping number the bug emerged. While correcting the overflow bug (and running some additional tests to verify the fix) I uncovered another nasty bug (failure to recalculate micro-steps per full revolution correctly).

An interesting observation I made while testing: If I experimentally set number of full steps per full revolution to 400, and micro-stepping to 16, with a planetary gear ratio of 26.85, then the total number of microsteps in a full revolution is 171848. Since the step delay is set to 1 (millisecond) this is 172 seconds of delay total. On my setup, I find that the actual time is about double that, so this would be more than 5 minutes for a full revolution! I mention this because in testing these high number values, it can seem like nothing is happening when it's really just taking a long time. In actual use I don't experience this problem because I don't use microstepping at all and my motor is 200 full steps per full revolution (which is typical), so my indexer makes a full revolution in about 10 seconds. Since I'm using it for gear making I'm only moving small increments in actual use, so the move time is typically a second or less.

At this point I am running up against the limits of my knowledge on stepper motors. My understanding is that there has to be some delay between steps to allow the motor time to move, but whether the stepper motor controller handles this or the software (or both) is not clear to me. The code does include a delay parameter - which I have set to 1 (millisecond).
 
At this point I am running up against the limits of my knowledge on stepper motors. My understanding is that there has to be some delay between steps to allow the motor time to move, but whether the stepper motor controller handles this or the software (or both) is not clear to me. The code does include a delay parameter - which I have set to 1 (millisecond).

The driver has no control over the timing between steps, that is entirely set by your software. If the steps are too close together the motor will lose steps. You can usually hear this happening.

I’ve successfully run with a step delay of less than 500 microseconds before mine started losing steps.

John
 
John - that's good information, thank you.

I'll experiment with substituting delayMicroseconds() for delay(). I don't think it's a critical issue for this application, but it should be interesting to try it out.
 
It is very possible that I'm doing something basically wrong.

Have you checked all your wiring. Using any "push in" connectors or breadboarding can create problems.
Reason I'm suspicious is when you quoted you had fitted the keypad backwards.

My assumption was that loading one program into the Arduino and then by loading another into it would totally erase the first program and replace it with the second program.
Correct. Also any problems with loading will show at the bottom of the IDE screen. You may have to "lift" the bottom border of the text screen to see.

Do you have the correct board type selected when you do the programming...?
 
bug.on.windshield.PNG More programming bugs squashed! I have just uploaded version 7.23 of my indexer software (available at link below). This version fixes some bugs when reversing rotation. I should note that while the code allows for reversing rotation, it does not compensate for any backlash. For my indexer a full 360° rotation is 5,370 steps and the amount of backlash is approximately 75 steps (1.39%, even though the motor spec sheet says backlash is <1%).

For this version of the code, I also changed the delay option from milliseconds to microseconds. I tried setting the delay at 1,000 μsecs (works), 750 μsecs (seems to work), and 500 μsecs (stalls). To be on the safe side I'm running with a delay of 1000 μsecs (1 millisecond).

I have considered adding additional code to compensate for backlash, but for my purposes I do not see any real use for it. In practice, when using the indexer I think it is good practice to allow rotation in only one direction to ensure most accurate positioning. In addition, before use I always run the indexer through a full rotation to remove any slack from the system.

https://sites.google.com/site/lagad...es-mills-etc/build---electronic-indexing-head
 
Thanks kquiggle for your good work!

I have two problems when i switched from bmac2 sketch to your sketch. First one was that my lcd keeps showing only blank charaters. After some researching i edited this line:
Code:
LiquidCrystal_I2C lcd(0x3F,20,4);
to this:
Code:
LiquidCrystal_I2C lcd(0x27,20,4);
And now everything works well!

Second problem comes when i updated to your latest sketch. Motor wont turn at all after updating. Solution is simple: setting step delay to 1000 (us) when old value was 1 (ms).

I wrote these if they were helpful to other beginners like me. Now i got everything works well!
 
v4dsXz329 -

Good to hear it is working for you. Some displays use 0x27 and some use 0x3F so your comment is very useful.

If you used a previous version of my sketch it would have stored a value of 1 millisecond in EEPROM, which the updated sketch would interpret as 1 microsecond. If you were using my sketch for the first time, it would use hard-coded settings for my hardware, which are probably wrong for most everyone else. First time users should go through the settings first to make sure the values are correct for their hardware - once these have been updated they will be stored so they don't ever need to be reset unless you make a hardware change.

Both your comments raise good points. I am updating the program comments with notes for first time users to address these issues.

Thanks again.
 
Have you checked all your wiring. Using any "push in" connectors or breadboarding can create problems.
Reason I'm suspicious is when you quoted you had fitted the keypad backwards.


Correct. Also any problems with loading will show at the bottom of the IDE screen. You may have to "lift" the bottom border of the text screen to see.

Do you have the correct board type selected when you do the programming...?

Yes, I had originally hooked up the keypad the way it was described at the beginning of this post. When I pushed the keys they came up in a random fashion so I just decided to reverse the order that they were connected. Everything worked great after that. When I have had a problem like I was describing I had gone back and reloaded the original bmac2 sketch and the keypad worked again - without touching any of the wiring. I have done this numerous times - it is not a wiring problem.

Yes, the correct board type is selected. The original sketch wouldn't run if it wasn't.

I'm getting back to the project today so I will check that bottom line on the IDE screen.
 

Latest posts

Back
Top