Math problem on Arduino Mega

I have a math problem (pun not intended) on an Arduino Mega.
I am running this code:

float dA = (mx + 255) / 510;
float dB = (mX + 255) * (1/510);

with mX being a value between -255 and 255. The output on dA should be at 0 when mX is at 255, be at 1 when mX is -255, and anywhere in between is mapped. Same thing for dA, but the output is the opposite. However, the outcome is always 0 for both.

Full Code
// Motor A connections
int enA = 9;
int in1 = 8;
int in2 = 7;
// Motor B connections
int enB = 3;
int in3 = 5;
int in4 = 4;

int xPin = A0;
int yPin = A1;
int swPin = 2;

void setup() {
  // Set all the motor control pins to outputs
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(xPin, INPUT);
  pinMode(yPin, INPUT);
  pinMode(swPin, INPUT_PULLUP);
  
  // Turn off motors - Initial state
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  analogWrite(enA, 0);
  analogWrite(enB, 0);

  Serial.begin(9600);
}

void loop() {
  int X = analogRead(xPin);
  int Y = analogRead(yPin);
  boolean sw = !digitalRead(swPin);

  int mX = map(X, 0, 1024, -255, 255);
  int mY = map(Y, 0, 1024, -255, 255);

  int mA = mY;
  int mB = mY;

   // EVIL CODE
  float dA = (mX + 255) / 510;
  float dB = (mX + 255) * (1/510);

  Serial.print("mX: ");
  Serial.print(mX);
  Serial.print(", mY: ");
  Serial.print(mY);
  Serial.print(", dA: ");
  Serial.print(dA);
  Serial.print(", dB: ");
  Serial.println(dB);
}

void speedA(int a) {
  if (a > 0) {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);

    analogWrite(enA, a);
  } else if (a < 0) {
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);

    analogWrite(enA, a * -1);
  } else {
    digitalWrite(in1, LOW);
    digitalWrite(in2, LOW);

    analogWrite(enA, 0);
  }
}

void speedB(int b) {
  if (b > 0) {
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);

    analogWrite(enB, b);
  } else if (b < 0) {
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);

    analogWrite(enB, b * -1);
  } else {
    digitalWrite(in3, LOW);
    digitalWrite(in4, LOW);

    analogWrite(enB, 0);
  }
}

Thanks in advance!

You are doing integer division, then that gets assigned to float.

How do I fix it?

... maybe do non-integer math on the right of the equal sign?
the link shows that just adding a Decimal will force float.

1 Like

[quote="tinkerer9, post:1, topic:1032263"]

float dA = (mx + 255) / 510;
float dB = (mX + 255) * (1/510);
float dA = (mx + 255.0) / 510.0;
float dB = (mX + 255.0) * (1/510.0);
1 Like

Is it not enough to enter one factor as float number like:?

float dA = (mx + 255) / 510.0;

Ideally, yes, but the compiler can be too clever by half. Like extra parens, they don't hurt and clarify the intent to even the most casual observer. In strongly typed languages I don't like to mix types and hope the compiler gets my meaning. Make EVERYTHING float, or int, or double, or whatever so there is no doubt about intent.

2 Likes

I tried using casting and the results are shown in comment field.

void setup() 
{
  Serial.begin(9600);
  int mx = 4;
  int mX = 4;
  float dA = (float)(mx + 255) / 510;   //shows: 0.51 correct
  float dB = (float)(mX + 255) * (1 / 510);//shows: 0.00 NOT 0.51
  Serial.println(dA, 2);
  Serial.println(dB, 2);
}

void loop() {}

the integer division is killing you. Put .0's on everything so its clear you want floats thruout and run it again. Also, print more than 2 decimals to reveal any lint in the math hidden by rounding. (1 / 510) = 0 in integer math. anything times 0 is zero.
The parens tell the compiler that the two numerical integer constants are to be used in integer math. The 1st expression works because the casting worked.

1 Like

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