Divide Problem

Jake

Well-known member
I am running Arduino IDE 1.6.5 with Teensyduino 1.2.4 on 64 bit Linux. I am having a strange problem with dividing a defined variable with another defined variable. When I add, subtract or multiply the two variables there is not a problem. When I put the defined variables into other variables, the divide works fine.

I thought I would try to resolved the problem by updating to Teensyduino 1.2.5 Beta, by downloading it from page https://forum.pjrc.com/threads/29508-Teensyduino-1-25-Beta-1-Available and try it before posting here. Its download size is 53.9 MB compared to 67.6 MB for 1.24. And I cannot get it to execute to install so am working with 1.24.

The offending code is on line 52, commented out below
Code:
   //fanJerkTime = FAN_ALPHA_MAX / FAN_JERK;
. If I replace the divide with +, -, or * then it works as expected, but with the / it results in 0.00. The replacement lines 49 to 51
Code:
    float num = FAN_ALPHA_MAX;
  float denom = FAN_JERK;
  fanJerkTime = num / denom;
works as expected.

I will appreciate your comments and help, on both the divide problem and updating to 1.25.

Code:
// See fanSpeedCurve.xmcd for the derivation

#define FAN_OMEGA_MAX     12000/60.0            // Max fan RPM converted to Hz
#define FAN_OMEGA_OPERATING     10000/60.0      // Operating fan RPM converted to Hz
#define FAN_OMEGA_TOLERANCE 100/60.0            // fan speed between FAN_OMEAGA_MAX and FAN_OMEGA_TOLERANCE
#define FAN_ALPHA_MAX     FAN_OMEGA_MAX/12.0    // Max fan rotational acceleration (denom is time)
#define FAN_JERK          FAN_ALPHA_MAX/2.0     // Max fan jerk (rate of change of acceleration) (denom is time)

// following are already is DooleyHouse.h
#define PWM_WRITE_FREQUENCY 1464            // multiple of 732?  check with Kevin for ideal frequency for him
#define PWM_WRITE_RESOLUTION 12             // bits resolution (up to 16)
#define PWM_REF_VOLTAGE              3.3    // PWM output voltage

boolean fanOn;
unsigned int timeCurrent, timeOld;
float fanDeltaTime, fanJerkTime;
float fanSpeed, fanAccel;
float fanSpeedUpperThreshold, fanSpeedLowerThreshold;  // beyond this speed the acceleration rate starts changing
float PWMscaling;

void setup() {
  Serial.begin(9600);  // for debugging or datalogging
  delay(800);
  Serial.println("Starting Serial Port");

  // setup the PWM output for the fan speed
  analogWriteResolution(PWM_WRITE_RESOLUTION);            //  set in dooleyHouse.h
  PWMscaling = (powf(2.0f, PWM_WRITE_RESOLUTION) - 1.0f) / PWM_REF_VOLTAGE;
  Serial.println(PWM_WRITE_RESOLUTION);
  // pins 5, 6, 9, 10, 20, 21, 22 & 23 are grouped together on teensy 3.1
  analogWriteFrequency(20, PWM_WRITE_FREQUENCY);       //  main fan rotational speed
  analogWriteFrequency(21, PWM_WRITE_FREQUENCY);       //  extractor fan rotational speed

  Serial.print(FAN_OMEGA_MAX);
  Serial.print(" ");
  Serial.print(FAN_OMEGA_OPERATING);
  Serial.print(" ");
  Serial.print(FAN_OMEGA_TOLERANCE);
  Serial.print(" ");
  Serial.print(FAN_ALPHA_MAX);
  Serial.print(" ");
  Serial.print(FAN_JERK);
  Serial.print(" ");
  Serial.print(PWM_REF_VOLTAGE);
  Serial.println(" ");

  fanOn = true;
  //fanJerkTime = (float) FAN_ALPHA_MAX / (float) FAN_JERK;
  float num = FAN_ALPHA_MAX;
  float denom = FAN_JERK;
  fanJerkTime = num / denom;
  //fanJerkTime = FAN_ALPHA_MAX / FAN_JERK;
  fanSpeedUpperThreshold = FAN_OMEGA_OPERATING - (FAN_ALPHA_MAX - FAN_JERK*fanJerkTime)*fanJerkTime;
  fanSpeedLowerThreshold = 0 - (-FAN_ALPHA_MAX + FAN_JERK*fanJerkTime)*fanJerkTime;
  fanSpeed = 0;
  fanAccel = 0;
  
  Serial.print(fanJerkTime);
  Serial.print(" ");
  Serial.print(fanSpeedUpperThreshold);
  Serial.print(" ");
  Serial.print(fanSpeedLowerThreshold);
  Serial.print(" ");
  Serial.print(fanSpeed);
  Serial.print(" ");
  Serial.print(fanAccel);
  Serial.print(" ");
  Serial.print(PWMscaling);
  Serial.println(" ");
  
  timeCurrent = micros();
}

void loop() {
  // put your main code here, to run repeatedly:
  timeOld = timeCurrent;
  timeCurrent = micros();
  fanDeltaTime = (timeCurrent - timeOld) * 1e-6;

  if (fanOn) {      // fan is on
    if (fanSpeed < fanSpeedLowerThreshold) {
      fanSpeed = fanSpeed + (fanAccel + FAN_JERK/2*fanDeltaTime)*fanDeltaTime;
      fanAccel = fanAccel * FAN_JERK*fanDeltaTime;
      Serial.println("1st S-curve");
    }
    else if (fanSpeed >= fanSpeedLowerThreshold && fanSpeed < fanSpeedUpperThreshold) {
      fanSpeed = fanSpeed + fanAccel*fanDeltaTime;
    }
    else if (fanSpeed <= fanSpeedUpperThreshold && fanSpeed < FAN_OMEGA_OPERATING) {
      fanSpeed = fanSpeed - (fanAccel + FAN_JERK/2*fanDeltaTime)*fanDeltaTime;
      fanAccel = fanAccel * -FAN_JERK*fanDeltaTime;      
    }
    else if (fanSpeed > FAN_OMEGA_OPERATING + FAN_OMEGA_TOLERANCE) {
      fanSpeed = fanSpeed - (FAN_ALPHA_MAX / 1000)*fanDeltaTime;
    }
  }
  Serial.print(fanDeltaTime*1e6);
  Serial.print(" ");
  Serial.print(fanSpeed);
  Serial.print(" ");
  Serial.print(fanAccel);
  Serial.println(" ");
  
  /*else {       // fan is off
  
  }*/
}
 
I'm on my mobile right now but could the problem be that fan jerk is zero? That is, don't you need an equal sign in the define section?
 
In looking at it, I would suggest that parenthesis are your friends, and to remind you that #define is textual substitution.

Your code is:

Code:
#define FAN_OMEGA_MAX     12000/60.0            // Max fan RPM converted to Hz
#define FAN_OMEGA_OPERATING     10000/60.0      // Operating fan RPM converted to Hz
#define FAN_OMEGA_TOLERANCE 100/60.0            // fan speed between FAN_OMEAGA_MAX and FAN_OMEGA_TOLERANCE
#define FAN_ALPHA_MAX     FAN_OMEGA_MAX/12.0    // Max fan rotational acceleration (denom is time)
#define FAN_JERK          FAN_ALPHA_MAX/2.0     // Max fan jerk (rate of change of acceleration) (denom is time)

// ...

fanJerkTime = FAN_ALPHA_MAX / FAN_JERK;

This gets replaced as:

Code:
fanJerkTime = 12000/60.0/12.0 / 12000/60.0/12.0/2.0;

Which isn't what you wanted. I would suggest either using parenthesis around each #define expression or use the const float declaration which acts as separate statements:

Code:
#define FAN_OMEGA_MAX     (12000/60.0)            // Max fan RPM converted to Hz
#define FAN_OMEGA_OPERATING     (10000/60.0)      // Operating fan RPM converted to Hz
#define FAN_OMEGA_TOLERANCE (100/60.0)            // fan speed between FAN_OMEAGA_MAX and FAN_OMEGA_TOLERANCE
#define FAN_ALPHA_MAX     (FAN_OMEGA_MAX/12.0)    // Max fan rotational acceleration (denom is time)
#define FAN_JERK          (FAN_ALPHA_MAX/2.0)     // Max fan jerk (rate of change of acceleration) (denom is time)

or:

Code:
const float FAN_OMEGA_MAX = 12000/60.0f;                        // Max fan RPM converted to Hz
const float FAN_OMEGA_OPERATING  = 10000/60.0f;                        // Operating fan RPM converted to Hz
const float FAN_OMEGA_TOLERANCE =  100/60.0f;                         // fan speed between FAN_OMEAGA_MAX and FAN_OMEGA_TOLERANCE
const float FAN_ALPHA_MAX = FAN_OMEGA_MAX/12.0f;    // Max fan rotational acceleration (denom is time)
const float FAN_JERK  = FAN_ALPHA_MAX/2.0f;       // Max fan jerk (rate of change of acceleration) (denom is time)
 
Back
Top