In the code below i first calculate the number of steps a stepper should step according to the degrees value.
char xDishBuffer[8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
int xGearRatio = 42; // stepper ratio per X degree of rotation (1:42)
int xMicroSteps = 2; // Value of the microsteps
// Posible value's are 1, 2, 4, 8 and 16
typedef enum {
X_ROTOR, Y_ROTOR
}
stepperfn;
long deg2step( float degrees, stepperfn stepper );
long deg2step( float degrees, stepperfn stepper ) {
if (stepper == X_ROTOR) return (( degrees / 1.8) * xMicroSteps * xGearRatio);
if (stepper == Y_ROTOR) return ((-degrees / 1.8) * yMicroSteps * yGearRatio);
}
long xResult = 0;
float xxResult ;
void setup() {
Serial.begin(19200); // Start the Serial communication
while (!Serial);
xResult = deg2step(99.99, X_ROTOR);
Serial.println(xResult);
xxResult = xResult / xGearRatio / xMicroSteps * 1.8;
dtostrf(xxResult, 7, 2, xDishBuffer); // Make it alse printable
Serial.println(xDishBuffer);
}
void loop() {
// put your main code here, to run repeatedly:
}
With 99.99 degrees the result = 4666(.2) steps.
If i reverse the calculation the result should be almost equals 99.99 but printed is 99.00.
Maybe i use the wrong types but how to solve this?
Shouldn't xResult be a float ?
The results not wrong you are. The C language has been around since the 1970's and gcc the (compiler used by the IDE) has been around for many years - so any bugs which a newbie would find are long gone!
Converting (casting) to int allways rounds down.
Mark
UKHeliBob:
Shouldn't xResult be a float ?
No not according to the AccelStepper library documentation, it should be a long.
http://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html#ace236ede35f87c63d18da25810ec9736
holmes4:
The results not wrong you are. The C language has been around since the 1970's and gcc the (compiler used by the IDE) has been around for many years - so any bugs which a newbie would find are long gone!
Converting (casting) to int allways rounds down.
Mark
But where do i convert to a int?
xxResult = xResult / xGearRatio / xMicroSteps * 1.8;
xxResult = 4666 / 42 / 2 * 1.8; // int div int -> int
xxResult =111 / 2 * 1.8; // int div int -> int
xxResult =55 * 1.8; int mul float -> float
xxResult =99.00
voila
long xResult = 0; long is a type of int
..........
xxResult = xResult / xGearRatio / xMicroSteps * 1.8; // in here is the int cast, try
xxResult = (float)xResult / (float)xGearRatio /(float) xMicroSteps*1.8;
Logic - As I read the statement it read take xResult and / by GearRatio thats two ints so rounding down takes place. The same happens when you divide by xMicroSteps.
Mark
if you are doing some float calculation , and then converting to an integer type at the end ( or long ), it is often better to add 0.5 to the result before it gets truncated to an integer type.
This has the same effect as rounding the floating point number to the nearest integer number.
You need to be careful when mixing floating point types and integer types in calculation expressions.
You are also wasting a lot of time and probably memory by calculating (1/1.8)xmicrostepsxgearatio millions and millions of times when it doesn't change. Do you want to wear out your cpu ? Calculate this number once, in setup( ), or let the compiler do it.
The compiler might optimize it already...
gharryh:
UKHeliBob:
Shouldn't xResult be a float ?
No not according to the AccelStepper library documentation, it should be a long.
AccelStepper: AccelStepper Class Reference
Well, considering that the code you posted does not compile (yGearRatio and yMicroSteps not defined) and it does not use the AccelStepper library, I don't see the relevance of what AccelStepper wants.