Rotary table/indexer controller.

WARNING! Programming Stuff Follows!

After some sleep loss I have some working code with error correction.

Code:
         case '3':                             // Rotate CW
             newKey = false;                    // Clear key flag
             if(MotStat == true)                // Do this if motor is on
             {   
                current = current + Degrees;       // Add new degrees to current total
                if(current >= 360)
                  {
                     current = (current - 360);       // Keep it under 360
                     CSteps = 0; 
                  }
                if(current == 0)                  // Prevents "0/360" error below
                  {
                     ToMove = Degrees * (Multiplier/360); // Figure out how many steps to move
                     CSteps = 0;                  // Reset  cumulative step counter
                  }
                else
                  {
                     ToMove = (current/360) * Multiplier + 0.5 - CSteps; // This is where the magic happens!
                     CSteps = CSteps + ToMove;   // Add moved steps to step counter
                  }
               // More stuff follows to move table and update display...
             }

I had to do some extra stuff to move counter clockwise because if you step backward past zero degrees the original code failed.

Code:
          case '1':                             // Rotate CCW
             newKey = false;                    // Clear key flag
             if(MotStat == true)               // Do this if motor is on
                {
                   current = current - Degrees;
                   if(current < 0)
                      {
                         current = (current + 360);      // Add new degrees to current total
                         CSteps = (Multiplier - CSteps); // Add table steps/rev to total steps
                      }
                   if(current == 0)                  // Prevents "0/360" error below
                      {
                         ToMove = Degrees * (Multiplier/360);
                         CSteps = 0;                
                      }
                   else
                      {
                          ToMove = CSteps + 0.5 - (current * Multiplier)/360; // More magic!
                          CSteps = CSteps - ToMove;
                      }
                   // More stuff follows to move table and update display...
                }

I'll be back to explain this after some chores.

Eric
 
Last edited:
WARNING! Programming Stuff Follows!

After some sleep loss I have some working code with error correction.

case '3': // Rotate CW
newKey = false; // Clear key flag
if(MotStat == true) // Do this if motor is on
{
current = current + Degrees; // Add new degrees to current total
if(current >= 360)
{
current = (current - 360); // Keep it under 360
}
if(current == 0){ // Prevents "0/360" error below
ToMove = Degrees * (Multiplier/360); // Figure out how many steps to move
CSteps = 0; // Reset cumulative step counter
}else{
ToMove = (current/360) * Multiplier + 0.5 - CSteps; // This is where the magic happens!
CSteps = CSteps + ToMove; // Add moved steps to step counter
}

I had to do some extra stuff because if you step backward past zero degrees the original code failed.

case '1': // Rotate CCW
newKey = false; // Clear key flag
if(MotStat == true){ // Do this if motor is on
current = current - Degrees;
if(current < 0)
{
current = (current + 360); // Add new degrees to current total
CSteps = (Multiplier - CSteps); // Add table steps/rev to total steps
}
if(current == 0){ // Prevents "0/360" error below
ToMove = Degrees * (Multiplier/360);
CSteps = 0;
}else{
ToMove = CSteps + 0.5 - (current * Multiplier)/360; // More magic!
CSteps = CSteps - ToMove;
}

I'll be back to explain this after some chores.

Eric
Why don't you enclose that in the </> code tag? It makes it a lot easier to read. Use C language, or C like. It preserves the C formatting, unlike the ordinary forum SW.
 
Why don't you enclose that in the </> code tag? It makes it a lot easier to read. Use C language, or C like. It preserves the C formatting, unlike the ordinary forum SW.
OK, I found the button to do that, but I think you assume I formatted the code with indents and all in the first place. I fixed that.
 
Last edited:
OK, I found the button to do that, but I think you assume I formatted the code with indents and all in the first place.
Well, as a person who does program in python and in C, formatting helps. In python, the formatting can matter a lot.

While not required for the C compiler, it sure makes it easier for other humans to read it. And a lot easier for one to get help, if needed. Generally it is a good thing to format your code neatly and consistently. Just an observation, based on about five decades of coding.

Have to laugh whenever I see the word magic in code. :) I have often written comments in my code, highlighting some "clever" section, describing how it works, and telling the future me not to mess with it, else I will break everything! Every time I have disregarded the past me, I have regretted it, because things did indeed break.
 
I still fails sometimes if I step past zero.

It's been a while since my computer science classes so I'm out of the formatting habit for my own use. I'll have to work on that.

The magic is changing data types. "ToMove" is a long int while "current" and "Degrees" are float. When you put the float into the int it truncates the value and ToMove only gets full steps.
 
I still fails sometimes if I step past zero.

It's been a while since my computer science classes so I'm out of the formatting habit for my own use. I'll have to work on that.

The magic is changing data types. "ToMove" is a long int while "current" and "Degrees" are float. When you put the float into the int it truncates the value and ToMove only gets full steps.
That kind of stuff worries me. Compiler rules and behavior can change over time... Not saying it is true for you, but I have experienced that. Is it that the Arduino can't do the math reliably and convert to integer steps? I guess that is what you are doing?

Failing steps past zero sounds like a unsigned integer problem. All the integers need to be signed, not uint16_t, or uint32_t. Need to be int16_t or int32_t. I manually do the math for going negative to see if it is correct. What you find may surprise you. It happens to me, occasionally, which is why I check my math...
 
Changing data types is not the way I would have done it from scratch. I would have expected a compiler error. I started with someone else's code so I can't answer for their choices. The code is really a mess right now and I'm beating it until it breaks. Once I have the features I want I'll start again.

I think the arduino can handle the math fine. Stepper drivers need to get whole number inputs. Dividing 360 degrees doesn't always give a whole number result. I recall there is a method in C++ to separate the whole number from the remainder (modulo?). The whole number portion could be multiplied by the number of steps/degree to move the table. The remainders could be accumulated to add an extra step when their value + .5 exceeds 1 to keep things close.

I've found passing zero using an arduino is a pain. My first impulse was just don't allow it, but I know there are times I would need to. I'll get there eventually.

I have some lines is places to output the variables to the serial port so I can see how they change. I just have not tried every combination of inputs yet.

I need to dust off my books and refresh my memory.
 
Changing data types is not the way I would have done it from scratch. I would have expected a compiler error. I started with someone else's code so I can't answer for their choices. The code is really a mess right now and I'm beating it until it breaks. Once I have the features I want I'll start again.

I think the arduino can handle the math fine. Stepper drivers need to get whole number inputs. Dividing 360 degrees doesn't always give a whole number result. I recall there is a method in C++ to separate the whole number from the remainder (modulo?). The whole number portion could be multiplied by the number of steps/degree to move the table. The remainders could be accumulated to add an extra step when their value + .5 exceeds 1 to keep things close.

I've found passing zero using an arduino is a pain. My first impulse was just don't allow it, but I know there are times I would need to. I'll get there eventually.

I have some lines is places to output the variables to the serial port so I can see how they change. I just have not tried every combination of inputs yet.

I need to dust off my books and refresh my memory.
Modulo returns the remainder. 7 % 3 = 1. 8 % 3 = 2. 9 % 3 = 0 In C, % is only defined for integers. If you want to do modulo with floats then the function is fmod.
 
That kind of stuff worries me. Compiler rules and behavior can change over time... Not saying it is true for you, but I have experienced that. Is it that the Arduino can't do the math reliably and convert to integer steps? I guess that is what you are doing?

Failing steps past zero sounds like a unsigned integer problem. All the integers need to be signed, not uint16_t, or uint32_t. Need to be int16_t or int32_t. I manually do the math for going negative to see if it is correct. What you find may surprise you. It happens to me, occasionally, which is why I check my math...

Yes, for some reason after passing zero the math procedure sends a negative step count the the motor procedure.

Still looking.
 
Naively, if there is a negative step count, shouldn't one take the absolute value of the counts and reverse the direction to the stepper? I have not looked at the code.
 
Back
Top