Go Down

Topic: If-statement Is not tripping (Read 6893 times) previous topic - next topic

Syn42ME

Okay, I'm running into a very odd issue. I'm programming a custom stepper-control class to be able to drive a micro-step stepper controller and motor. I'm using an if statement at one point to determine if the microsecond clock has reached the trip point to pulse the motor.

Code: [Select]

bool StepperMicro::step()

  // Call the step function
  if (micros() > _longNextStepTime)
  {
    this->_longNextStepTime = micros() + this->_intStepInterval;
    this->stepMotor();
    this->_intStepsRemaining--;
  }

  // Return true if the remainint steps has reached 0.
  if( this->_intStepsRemaining < 1 ) return false;
  else return true;
}


I've used the Serial.println() command to check the values of both micros() and _longNextStepTime. micros() increments and reads as it should, and _intStepInterval, amusingly enough, is at roughly -24000 (not sure why, but hey, it's lower than micros().) Thus, the if-statement should trip. However, it isn't. I've placed serial prints inside the if-statement to confirm; no good.

Any ideas why this isn't tripping? This statement is used in a couple of other places, even for a blinking LED. Also drove the stepper before I started wrapping up the functionality in a class.

-Syn

PaulS

First suggestion: The this-> stuff looks amateurish. 99.99% of the time, it is not needed. Get rid of it, except in that 0.01% of the time that it is needed.

Second suggestion: Posting code snippets that omit key information, like how _longNextStepTime and _intStepInterval are defined is not the best way to get help. Including long and int in the names is no assurance that the variables are actually defined that way.

Third suggestion: Addition involving variables that can roll over, such as the return value from micros(), is a bad idea. Subtraction is guaranteed to work. Addition is not. Restructure the test to involve subtraction, not addition.

Fourth suggestion: This code:
Code: [Select]
  if( this->_intStepsRemaining < 1 ) return false;
  else return true;

would be much clearer as
Code: [Select]
   return (intStepsRemaining > 0);
The value in the parentheses will evaluate to true (if steps remaining is positive) or false (if no steps remaining).

Quote
_intStepInterval, amusingly enough, is at roughly -24000

This tells me that _intStepInterval is not properly defined as unsigned long.

Syn42ME

First Suggestion Reply: I didn't think it was needed, but I noticed that the Stepper.cpp example in the software made use of it in the Stepper class. I attempted to find what it actually meant online, but search engines don't really return anything helpful when using the word "this", and the symbols are ignored. If I recall, it's used for referencing the class member via pointer, but I don't really know. I was copying the example. I'll delete them.

Second Suggestion Reply: Point. I was refraining from posting the whole thing: I'll submit all definitions next time.

Third Suggestion Reply: Is this because the addition result might be larger than the variable size?

Fourth Suggestion Reply: Thanks for the suggestion! I'm getting back into coding and a bit rusty. Much more streamlined!

Fifth Suggestion Reply: Actually, I mistyped that. I meant to reference _longNextStepTime, and you're right. It is just long, not unsigned long. I will correct that.

Thanks a bunch for the feedback! Maybe these changes will fix the if-statement issue.

-Syn

Syn42ME

#3
Jan 26, 2011, 07:17 pm Last Edit: Jan 26, 2011, 07:19 pm by Syn42ME Reason: 1
Okay, I modified the code as suggested, and then some. It's working now, and the microsteping actually works. I figured I might as well post the current code. Thanks for your help!

The following is a class I wrote to be able to control a commercial microstep controller. As the controller I have (from work, awesome) is a variable-microstep device, I wrote the library to accommodate this. There are a few things to add, but it's comming.

I posted the code over here: Microstep Stepper Controller Interface Class

-Syn

Naftali

</*
Into Robotics
*/
 
#include <Servo.h>
 
int servoPin = 9;
 
Servo servo; 
 
int servoAngle = 0;   // servo position in degrees
 
void setup()
{
  Serial.begin(9600); 
  servo.attach(servoPin);
}
 
 
void loop()
{
//control the servo's direction and the position of the motor

   servo.write(45);      // Turn SG90 servo Left to 50 degrees
   delay(10);          // Wait 1 second
   servo.write(9);      // Turn SG90 servo back to 90 degrees (center position)
   delay(10);          // Wait 1 second
   servo.write(135);     // Turn SG90 servo Right to 135 degrees
   delay(10);          // Wait 1 second
   servo.write(90);      // Turn SG90 servo back to 90 degrees (center position)
   delay(10);

//end control the servo's direction and the position of the motor


//control the servo's speed 

//if you change the delay value (from example change 50 to 10), the speed of the servo changes
  for(servoAngle = 0; servoAngle < 180; servoAngle++)  //move the micro servo from 0 degrees to 180 degrees
  {                                 
    servo.write(servoAngle);             
    delay(5);                 
  }

  for(servoAngle = 180; servoAngle > 0; servoAngle--)  //now move back the micro servo from 0 degrees to 180 degrees
  {                               
    servo.write(servoAngle);         
    delay(10);     
  }
  //end control the servo's speed 
}>

sterretje

@Naftali
Do you have a question?

When posting code. please use code tags
type [code]
paste your code after that
type [/code] after that.

If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Delta_G

Code: [Select]
if (micros() > _longNextStepTime)
  {
    this->_longNextStepTime = micros() + this->_intStepInterval;


This will fail whenever the return value from micros rolls over.  At some point _longNextStepTime will be very close to the max of a long and when you add the interval to it then it will go negative if it really is a long or back around to a small number if it really is unsigned long and your if statement will immediately be true giving you at least one bad step interval.  Take a look at the Blink WIthout Delay example and study up on how it uses subtraction and unsigned math to guard against that. 
Ad hoc, ad loc, and quid pro quo.  So little time - so much to know!  ~Jeremy Hillary Boob Ph.D

PaulMurrayCbr

#7
Jun 13, 2016, 10:36 am Last Edit: Jun 13, 2016, 10:48 am by PaulMurrayCbr
If I recall, it's used for referencing the class member via pointer, but I don't really know.
It's use to refer to a class member when the variable is being hidden. You'll see it in things like this:

Code: [Select]

class Foo {
  int importantThing;

  void setImportantThing(int importantThing) {
    this->importantThing = importantThing;
  }
}


People use it when they feel it's important to make a clear distinction between variables that parameters, ones that are auto (defined in the function), and class member variables. It's basically a coding style thing. Another way to to this is to use a p prefix for parameters, and an m prefix for class members.

Code: [Select]

class Foo {
  int mImportantThing;

  void setImportantThing(int pImportantThing) {
    mImportantThing = pImportantThing;
  }
}


Personally, I think this is a solution looking for a problem. If you don't know what variable is what, then your names are too short and/or your methods are too long.

Likewise, in a world of modern compilers with strong typing it's pretty pointless to prefix variables with their types (hungarian notation). Makes heaps of sense if you are coding assembler or passing around a lot of void* pointers, but otherwise no.

Personally (again), I say to use meaningful names for your variables except for one-letter names in loops, and suffix variables holding physical measurements with the unit of measure: elapsedTimeMs/elapsedTimeMin/elapsedTimeUs.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

PaulS

Quote
and suffix variables holding physical measurements with the unit of measure: elapsedTimeMs/elapsedTimeMin/elapsedTimeUs.
But NOT the name of the function that returns the time in that unit of measure. The insistence in using Millis in the name of variables irritates me no end.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy