Division arithmetic returning an integer

Hello everyone,
First time long time!
I have an issue that seems simple (and I'm sure it is) but it's driving me nuts. My project (On a Mega board) is reading a camera release signal from an automated 360 degree DSLR robot (Seitz Roundshot) My Arduino then sends a signal to a Nema 17 stepper motor that is part of a photographic background effect. My issue is that when I calculate a simple gear ratio (Line 80 "Ratio = Drive / Pinion") I'm getting an integer result regardless of the values of "Drive" and "Pinion". For example, For the values "Pinion = 12" and "Drive = 40" Serial Monitor gives me a result of 3.00. When I look at calculated values further down the string of calculations, this confirms that it is using a value of 3.00 and not 3.33 as it should. Any help would be much appreciated.
Here's my sketch so far.

[code]
#include <AccelStepper.h>

//Forward
const int Background_Forward = 4;
int Background_Forward_State = LOW;

//Backward
const int Background_Backward = 5;

//Reset
const int Reset_Trigger = 10;
int Reset_Trigger_State = HIGH;
const int Reset_Pin = 9;

//Alarm
const int Alarm_Pin = 6;
int Alarm_Pin_State = LOW;
const int Alarm_Speaker = 7;

int Alarm_Buzzes = 10;
int Alarm_Duration_1 = 1000;
int Alarm_Duration_2 = 2000;

//Program Duration
int Run_Speed = 200;
int Run_Acceleration = 50;

// Millis Variables
unsigned long Previous_Time_1 = 0;
unsigned long Previous_Time_2 = 0;

unsigned long Current_Time_1;
unsigned long Current_Time_2;

unsigned long Millis_Delay_1 = 1000;

//Rotation directions
int Forward = 1;
int Reverse = -1;

//Drive Variables
double Pi = 3.14159;
int Cylinder_Diameter = 112;
const int Dist_To_Background = 500;
const int Images_In_Sequence = 360;
int Image_Degrees_Turned;
double Image_Degrees_Turned_Rad;

double Degrees_Per_Image;
double Dist_Background_Moves;
double Cylinder_Circumfrence;
double Angle_Drum_Turns;

const int Pinion = 12;
const int Drive = 40;
double Ratio;
double Angle_Motor_Turns;
double Steps_Per_Degree;
int Steps_Per_Motor_Rotation = 800;
double Steps_Per_Inc;

AccelStepper stepper(1, 2, 3);

void setup()
{
  digitalWrite(Reset_Trigger, HIGH);

  Serial.begin(9600);

  Cylinder_Circumfrence = Pi * Cylinder_Diameter;

  Image_Degrees_Turned = 360 / Images_In_Sequence;

  Image_Degrees_Turned_Rad = Image_Degrees_Turned * Pi / 180;

  Dist_Background_Moves = tan(Image_Degrees_Turned_Rad) * Dist_To_Background;

  Angle_Drum_Turns = (Dist_Background_Moves / Cylinder_Circumfrence) * 360;
  
  Ratio = Drive / Pinion;

  Angle_Motor_Turns = Angle_Drum_Turns * Ratio;

  Steps_Per_Degree = Steps_Per_Motor_Rotation / 360;

  Steps_Per_Inc = Steps_Per_Degree * Angle_Motor_Turns;

  stepper.setMaxSpeed(Run_Speed);
  stepper.setAcceleration(Run_Acceleration);
  stepper.moveTo(Steps_Per_Inc);

  pinMode(Alarm_Pin, INPUT);
  pinMode(Alarm_Speaker, OUTPUT);
  pinMode(Background_Forward, INPUT);
  pinMode(Background_Backward, INPUT);
  pinMode(Reset_Pin, INPUT);
  pinMode(Reset_Trigger, OUTPUT);


}

void loop()
{
  Serial.print("Ratio    ");
  Serial.println(Ratio);

  digitalRead(Background_Forward);
  digitalRead(Background_Backward);
  Alarm_Pin_State = digitalRead(Alarm_Pin);
  Reset_Trigger_State = digitalRead(Reset_Trigger);

Increment:
  digitalRead(Alarm_Pin);
  Background_Forward_State = digitalRead(Background_Forward);

  if ((digitalRead(Background_Forward) == HIGH) && (digitalRead(Alarm_Pin) == HIGH))
  {
    Alarm_Pin_State = digitalRead(Alarm_Pin);
    if (Alarm_Pin_State == LOW)
    {
      for (Alarm_Buzzes; Alarm_Buzzes > 0; Alarm_Buzzes--)
      {
        delay(100);
        tone(Alarm_Speaker, 300);
        delay(Alarm_Duration_1);
        tone(Alarm_Speaker, 600);
        delay(Alarm_Duration_2);
      }
      noTone(Alarm_Speaker);
      delay(50);

      digitalWrite(Reset_Trigger, LOW);
    }
    stepper.runToNewPosition(Steps_Per_Inc);
    stepper.setCurrentPosition(0);

    stepper.run();
  }

  //=========================================================

Step_Back:
  digitalRead(Background_Backward);
  Alarm_Pin_State = digitalRead(Alarm_Pin);

  if ((digitalRead(Background_Backward) == HIGH) && (digitalRead(Alarm_Pin) == HIGH))
  {
    Alarm_Pin_State = digitalRead(Alarm_Pin);
    if (Alarm_Pin_State == LOW)
    {
      for (Alarm_Buzzes; Alarm_Buzzes > 0; Alarm_Buzzes--)
      {
        delay(100);
        tone(Alarm_Speaker, 300);
        delay(Alarm_Duration_1);
        tone(Alarm_Speaker, 600);
        delay(Alarm_Duration_2);
      }
      noTone(Alarm_Speaker);
      delay(50);
      digitalWrite(Reset_Trigger, LOW);
    }
    {
      stepper.runToNewPosition(-Steps_Per_Inc);
      stepper.setCurrentPosition(0);

      stepper.run();
    }
  }
  Alarm_Pin_State = digitalRead(Alarm_Pin);
  if (Alarm_Pin_State == LOW)
  {
    for (Alarm_Buzzes; Alarm_Buzzes > 0; Alarm_Buzzes--)
    {
      delay(100);
      tone(Alarm_Speaker, 300);
      delay(Alarm_Duration_1);
      tone(Alarm_Speaker, 600);
      delay(Alarm_Duration_2);
    }
    noTone(Alarm_Speaker);
    delay(1000);
    digitalWrite(Reset_Trigger, LOW);
  }
Reset:
  digitalRead(Reset_Trigger);
  digitalRead(Reset_Pin);

  if (digitalRead(Reset_Pin) == HIGH)
  {
    digitalWrite(Reset_Trigger, LOW);
  }
}
[/code]

Hello vicbodi
Extend all coded floating constants to xxx.0.

Have a nice day and enjoy coding in C++.
Дайте миру шанс!

in the statement where Ratio is a double and Drive and Pinion are intgers

Ratio = Drive / Pinion

the expression Drive / Pinion would be calculated as an integer loosing any fractional component and the result converted to a double when assigned to Ratio
cast one of the integers to a double

Ratio = (double)Drive / Pinion

and the expression will be evaluated as double

In summary of the 2 posts above...

When doing arithmetic the type of the result is obtained from the type of the things on the right of the "=".

So you need to force it to be float, either by adding ".0" to literal values, or explicitly casting to type float for other variables.

Thanks Horace, I didn't realise that variable type of the product of a formula could be dependent on the variable types within the formula. I assumed that assigning the variable type according to the expected input or result was the way to go, won't be making that mistake again. I have now changed the Pinion and Drive variables to floats and it works perfectly!

within an expression an integer divided by an integer yeilds an integer

have a read of operator-precedence-and-associativity-in-c and c-type-conversions

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.