Theoretical based Question on the delay() function

I've never really needed to know the answer till now, and I couldn't find reading material on the matter so here's my question...

Can the delay() function in Arduino 1.0.3 be negative?

For certain instances, the way my delay function must be coded, the value inside the delay function can be negative. I don't return any errors when verifying the sketch so does the program automatically take the absolute value since obviously it can't delay a negative amount of time?

Theoretically, no. The value passed to delay is an unsigned long integer. If you give it a negative number it will be interpreted as a very long delay.

Pete

irish_:
the value inside the delay function can be negative

No, it can't. The argument is an unsigned long; it is fundamentally impossible for an unsigned value to be negative. However, if you are doing arithmetic with signed variables and cast the result to an unsigned value then you could end up converting a negative signed value to a very large unsigned value.

The fact that your algorithm is coming up with a negative delay value makes me suspect that it may be flawed. To start with, if you're representing times as signed values then that's probably a mistake. Perhaps if you posted your code, somebody might be able to suggest how to avoid the problem.

I do like the idea of a -ve delay though... would that be an advance in time? XD

Sounds like something out of Big Bang Theory....

negative delay - that'd be going back in time, no? So instead of waiting for time to pass, you're undoing time that already passed.
Fire up the flux capacitor!

negative delay - that'd be going back in time, no?

Hmmmm I see it as an advance.... delay "holds time still" so I reckon -ve delay moves us forward.

Ok thanks for the quick replies guys, here's my code.

const int X_Axis_Pin = A0;      //analog pin 0
const int Y_Axis_Pin = A1;      //analog pin 1
const int soft_Pot_Pin = A2;    //analog pin 2
const int DIR_PIN = 8;          //stepper motor direction pin
const int STEP_PIN = 9;         //stepper 
const int magnet_Pin = 10;      //magnet pin
const int button_1_Pin = 2;     // the number of the pushbutton pin
const int button_2_Pin = 3;     // the number of the pushbutton pin
const int button_3_Pin = 4;     // the number of the pushbutton pin
const int button_4_Pin = 5;     // the number of the pushbutton pin
const int button_5_Pin = 6;     // the number of the pushbutton pin
const int button_6_Pin = 7;     // the number of the pushbutton pin
const int valve_1_Pin = 11;     // output to control valve
const int valve_2_Pin = 12;     // output to control valve
const int valve_3_Pin = 13;     // output to control valve
const int valve_4_Pin = A5;     // output to control valve
const float speed_Change = .05; // increment/decrement of Speed
const int time = 1000;
const int scaling_factor = 540/time; //Maximum distance from center divided by time


int X_Axis_Reading;
int Y_Axis_Reading;
int soft_Pot_Reading;
int button_1_State = 0;         // variable for reading the pushbutton status
int button_2_State = 0;         // variable for reading the pushbutton status
int button_3_State = 0;         // variable for reading the pushbutton status
int button_4_State = 0;         // variable for reading the pushbutton status
int button_5_State = 0;         // variable for reading the pushbutton status
int button_6_State = 0;         // variable for reading the pushbutton status
int magnet_State;               // magnet on or off
float Speed = .5;               // stepper motor speed (.01 <= Speed <= 1) 



void setup(){
  digitalWrite(X_Axis_Pin, HIGH); //enable pullup resistors
  digitalWrite(Y_Axis_Pin, HIGH); 
  digitalWrite(button_1_Pin, HIGH);
  digitalWrite(button_2_Pin, HIGH);
  digitalWrite(button_3_Pin, HIGH);
  digitalWrite(button_4_Pin, HIGH);
  digitalWrite(button_5_Pin, HIGH);
  digitalWrite(button_6_Pin, HIGH);
  
  pinMode(DIR_PIN, OUTPUT);       //set outputs
  pinMode(STEP_PIN, OUTPUT);
  pinMode(valve_1_Pin, OUTPUT); 
  pinMode(valve_2_Pin, OUTPUT); 
  pinMode(valve_3_Pin, OUTPUT); 
  pinMode(valve_4_Pin, OUTPUT); 
  
  Serial.begin(9600);
}

void loop(){
  X_Axis_Reading = analogRead(X_Axis_Pin); 
  Y_Axis_Reading = analogRead(Y_Axis_Pin);
  soft_Pot_Reading = analogRead(soft_Pot_Pin);
  button_1_State = digitalRead(button_1_Pin);         // variable for reading the pushbutton status
  button_2_State = digitalRead(button_2_Pin);         // variable for reading the pushbutton status   
  button_3_State = digitalRead(button_3_Pin);         // variable for reading the pushbutton status
  button_4_State = digitalRead(button_4_Pin);         // variable for reading the pushbutton status
  button_5_State = digitalRead(button_5_Pin);         // variable for reading the pushbutton status
  button_6_State = digitalRead(button_6_Pin);         // variable for reading the pushbutton status
  

  Serial.print("X =");
  Serial.println(X_Axis_Reading);
  Serial.print("Y =");
  Serial.println(Y_Axis_Reading);
  Serial.print("1 =");
  Serial.println(button_1_State);
  Serial.print("2 =");
  Serial.println(button_2_State);
  Serial.print("3 =");
  Serial.println(button_3_State);
  Serial.print("4 =");
  Serial.println(button_4_State);
  Serial.print("5 =");
  Serial.println(button_5_State);
  Serial.print("6 =");
  Serial.println(button_6_State);
  Serial.print("Speed =");
  Serial.println(Speed);
  Serial.print("Magnet State = ");
  Serial.println(magnet_State);
 
  
  if ((!button_2_State) && Speed <= 1 - speed_Change){
    Speed = Speed + speed_Change;  //Speed increment 
    Serial.println("Speed Increment.");
  } 

  if ((!button_5_State) && Speed >= .01 + speed_Change){
    Speed = Speed - speed_Change;  //Speed degrement
    Serial.println("Speed Decrement");
  }  
  
  if (!button_3_State){
    rotateDeg(1,Speed);    //rotate 1 degree at Speed
    Serial.println("Forward Step");
  }
  
  if (!button_4_State){
    rotateDeg(-1, Speed);  //rotate -1 degree at Speed
    Serial.println("Reverse Step");
  }
  
  if (!button_6_State){
    //Nothing. insert automation loop here
    Serial.println("Auto Program");
  }
  
  if (!button_1_State){
    if (magnet_State == 1){
      magnet_State = 0;
      digitalWrite(magnet_Pin, LOW);
    }
    else{
      magnet_State = 1;
      digitalWrite(magnet_Pin, HIGH);
      delay(400);                      //to prevent uncontrolable and apparently random toggling. 
      }
    Serial.println("Magnet Toggle");
  }
  
  if (Y_Axis_Reading >= 568){
   digitalWrite(valve_1_Pin, HIGH);
   Serial.println("Before");
   delay(time-((Y_Axis_Reading-559)/scaling_factor));
   Serial.println("During");
   digitalWrite(valve_1_Pin, LOW);
   delay((Y_Axis_Reading-559)/scaling_factor); 
   Serial.println("After");
   }
 
  /*if (Y_Axis_Reading <= 550){
    digitalWrite(valve_2_Pin, HIGH);
    delay(-(Y_Axis_Reading-559)/scaling_factor); 
    digitalWrite(valve_2_Pin, LOW);
    delay(time-(-(Y_Axis_Reading-559)/scaling_factor));
 }
   
  if (X_Axis_Reading >= 555){
    digitalWrite(valve_3_Pin, HIGH);
   delay(time-((X_Axis_Reading-547)/scaling_factor));
    digitalWrite(valve_3_Pin, LOW);
   delay((X_Axis_Reading-547)/scaling_factor); 
   }
 
  if (X_Axis_Reading <= 535){
    digitalWrite(valve_4_Pin, HIGH);
   delay(-(X_Axis_Reading-547)/scaling_factor);
    digitalWrite(valve_4_Pin, LOW);
    delay(time-(-(X_Axis_Reading-547)/scaling_factor));
   }*/
   
  delay(1000); //just here to slow down the output for easier reading
 }
 

 

/*void rotate(int steps, float speed){ 
  //rotate a specific number of microsteps (8 microsteps per step) - (negitive for reverse movement)
  //speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger
  int dir = (steps > 0)? HIGH:LOW;
  steps = abs(steps);

  digitalWrite(DIR_PIN,dir); 

  float usDelay = (1/speed) * 70;

  for(int i=0; i < steps; i++){ 
    digitalWrite(STEP_PIN, HIGH); 
    delayMicroseconds(usDelay); 

    digitalWrite(STEP_PIN, LOW); 
    delayMicroseconds(usDelay); 
  } 
}*/

void rotateDeg(float deg, float speed){ 
  //rotate a specific number of degrees (negitive for reverse movement)
  //speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger
  int dir = (deg > 0)? HIGH:LOW;
  digitalWrite(DIR_PIN,dir); 

  int steps = abs(deg)*(1/0.225);
  float usDelay = (1/speed) * 70;

  for(int i=0; i < steps; i++){ 
    digitalWrite(STEP_PIN, HIGH); 
    delayMicroseconds(usDelay); 

    digitalWrite(STEP_PIN, LOW); 
    delayMicroseconds(usDelay); 
  } 
}

My apparent views of the delay() function must be flawed. The part of the code in consideration is everything including and below: (notice the if statements returning a negative value are commented out)

if (Y_Axis_Reading >= 568){
digitalWrite(valve_1_Pin, HIGH);
Serial.println("Before");
delay(time-((Y_Axis_Reading-559)/scaling_factor));
Serial.println("During");
digitalWrite(valve_1_Pin, LOW);
delay((Y_Axis_Reading-559)/scaling_factor);
Serial.println("After");
}

But does it happen in this or parallel reality? If it happens in this reality, what happens if you unplug power after the LED blinks, but before the command is sent?
If it happens in a parallel reality, that would explain why my code seldom works. The other mes are messing with me me.

delay can be from 0 to 0xFFFFFFFF
your math will always result in a number in that range.
if you have 0x1000 - 0x3000, the result will be 0xFFFFE000, which will be a pretty long delay! 4,294,959,104 mS.

CrossRoads:
delay can be from 0 to 0xFFFFFFFF
your math will always result in a number in that range.
if you have 0x1000 - 0x3000, the result will be 0xFFFFE000, which will be a pretty long delay! 4,294,959,104 mS.

Talk about a blocking function!

Lefty

The other mes are messing with me me.

Yes, Sheldon...

irish_:
Ok thanks for the quick replies guys, here's my code.

The problem you refer to here is caused because you are not detecting transitions in the button state, you are treat it as an input command every time you read the input and find it's active. There's an example sketch showing how to compare the current and previous states so you only take action once each time the button is pressed. You might want to do some debouncing, too.

      delay(400);                      //to prevent uncontrolable and apparently random toggling.
   delay(time-((Y_Axis_Reading-559)/scaling_factor));

time is 1000.
Y_Axis_Reading is a value in the range 0 .. 1023 returned by analogRead().
scaling_factor is 540/1000. Since it's an integer, that equals zero.

Nothing good is going to happen when your code includes a divide by zero.

I suggest you try to explain how the delay is supposed to be related to the result of the analog read. There is probably a simple way to do it, once we understand what it is.

const int button_1_Pin = 2;     // the number of the pushbutton pin
const int button_2_Pin = 3;     // the number of the pushbutton pin
const int button_3_Pin = 4;     // the number of the pushbutton pin
const int button_4_Pin = 5;     // the number of the pushbutton pin
const int button_5_Pin = 6;     // the number of the pushbutton pin
const int button_6_Pin = 7;     // the number of the pushbutton pin

After the third copy/paste, I'd have been thinking array.

irish_:
Can the delay() function in Arduino 1.0.3 be negative?

I've just been reading about quantum mechanics so your question is quite interesting. :slight_smile:

On the face of it, no because you can't pass a negative number to delay in the first place.

void delay(unsigned long);

You may as well ask if it can be an imaginary number. No it can't, because the function does not accept such numbers.


Let me put it to you like this... If two twins wrote a program on an Arduino, both using delay, and one was travelling away from Earth at almost the speed of light, would both delays finish at the same time?

would both delays finish at the same time?

Yes, because the Arduino's clock is not moving relative to the chip.

[quote author=Nick Gammon link=topic=152585.msg1145886#msg1145886 date=1362611514]

irish_:
Can the delay() function in Arduino 1.0.3 be negative?

I've just been reading about quantum mechanics so your question is quite interesting. :slight_smile:

On the face of it, no because you can't pass a negative number to delay in the first place.

void delay(unsigned long);

You may as well ask if it can be an imaginary number. No it can't, because the function does not accept such numbers.


Let me put it to you like this... If two twins wrote a program on an Arduino, both using delay, and one was travelling away from Earth at almost the speed of light, would both delays finish at the same time?
[/quote]Pick up Richard P. Feynman's "QED". He talks about photons jumping back in time, but doesn't say anything about "unsigned long"'s managing to do it. Maybe just an oversight on his part?

No, although the twins would only realise that if the traveling twin eventually came back to Earth so they could compare notes.

Pick up Richard P. Feynman's "QED". He talks about photons jumping back in time, but doesn't say anything about "unsigned long"'s managing to do it. Maybe just an oversight on his part?

Probably, careless of him... just how did he win that Nobel?