[SOLVED] Trouble with millis()

THANKS!!

I finally go it working with the if statement!! (I have found it the easiest way to do it)
If I had used interrupts it only does my wall function for a few microseconds.
So if statements seemed like the best way to go (well for me anyway). The only thing is that I had to put lots of delays and ifs :). It works, and I'm happy. :open_mouth:

Here is my final code if anyone wanted to see it!

void setup() {                
  //Setup our motors and speed control plus define our pins

  //Give names to the Motor 1 pins so we can easily change them.
#define pwma 11
#define ain2 10
#define ain1 9

  //Give names to the Motor 2 pins so we can easily change them.
#define pwmb 5
#define bin1 7
#define bin2 6

  //Give a name to our button pin so we can esialy change it.
#define button 2

  //Give our LEDs a name
#define LED 3


  //Motor 1 Outputs
  //PWMA
  pinMode(pwma, OUTPUT);
  //AIN2
  pinMode(ain2, OUTPUT); 
  //AIN1 
  pinMode(ain1, OUTPUT);

  //Motor 2 Outputs
  //BIN1
  pinMode(bin1, OUTPUT);
  //BIN2
  pinMode(bin2, OUTPUT);
  //PWMB
  pinMode(pwmb, OUTPUT);

  //Set button as output
  pinMode(button, INPUT);

  //Set-up LEDs
  pinMode(LED, OUTPUT);
  
  digitalWrite(button, HIGH);

}

void loop() { 
  
  digitalWrite(LED, HIGH);

  int ranNum;
  int ranNuma;
  ranNum = random(25, 100);
  ranNuma = random(100, 200);
  
  if (digitalRead (button) == LOW) { Wall(); }
  
  else {
  // === turn around === //
  //M1
  digitalWrite(pwma, 100);
  digitalWrite(ain2, LOW);
  digitalWrite(ain1, HIGH);
  //M2
  digitalWrite(pwmb, 100);
  digitalWrite(bin2, HIGH);
  digitalWrite(bin1, LOW);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }

  // ===== Straight ===== //
  //M1
  digitalWrite(pwma, 100);
  digitalWrite(ain2, HIGH);
  digitalWrite(ain1, LOW);
  //M2
  digitalWrite(pwmb, 100);
  digitalWrite(bin2, HIGH);
  digitalWrite(bin1, LOW);
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  }
}

void Wall(){
  // === Go Backwards === //
  //M1
  digitalWrite(pwma, 255);
  digitalWrite(ain2, LOW);
  digitalWrite(ain1, HIGH);
  //M2
  digitalWrite(pwmb, 255);
  digitalWrite(bin2, LOW);
  digitalWrite(bin1, HIGH);
  delay(2000);


}

OP (ORIGINAL POST)

Hello,
What I want to happen is my robot is going along a pre-programmed course but when a button on the front of jabduino gets pressed (bumped into a wall) how can I make the robot then "DO THIS."  The problem is I want it to be able to sense a press and "DO THIS" at any time, not just at certain times...  I have tried using millis() but can't work it out. Could I please have some pointers with my code?

Thanks in Advanced.

This is my current code:

[code]//Setup our motors and speed control plus define our pins
// Motor 1
#define pwma 11
#define ain2 10
#define ain1 9

//Motor 2
#define pwmb 7
#define bin1 6
#define bin2 5

long previousMillis = 0;    // will store last time LED was updated
long previousMillis2 = 0;
long previousMillis3 = 0;

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 200;
long interval2 = 750;
long interval3 = 2000;

void button3() {
  //Go backwards
    //M1
    digitalWrite(pwma, 50);
    digitalWrite(ain2, LOW);
    digitalWrite(ain1, HIGH);
    //M2
    digitalWrite(pwmb, 100);
    digitalWrite(bin2, LOW);
    digitalWrite(bin1, HIGH);
    delay(1000);
  
  // === turn around === //
  //M1
  digitalWrite(pwma, 50);
  digitalWrite(ain2, LOW);
  digitalWrite(ain1, HIGH);
  //M2
  digitalWrite(pwmb, 100);
  digitalWrite(bin2, HIGH);
  digitalWrite(bin1, LOW);
  delay(250);
  
  }

void setup() {

// ==== Motor 1 ===== //
  //PWMA
  pinMode(pwma, OUTPUT);
  //AIN2
  pinMode(ain2, OUTPUT); 
  //AIN1 
  pinMode(ain1, OUTPUT);
  
// ==== Motor 2 ==== //
  //BIN1
  pinMode(bin1, OUTPUT);
  //BIN2
  pinMode(bin2, OUTPUT);
  //PWMB
  pinMode(pwmb, OUTPUT);
  
  //BUTTON STUFF
  #define button 2
  pinMode(button, INPUT);
        
}

void loop()
{
  //=================================================
  //Start of 1 thing//
  if (digitalRead(button) == HIGH) button3();
  
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval3) {
    // save the last time 
    previousMillis = currentMillis;   
// ===== Straight ===== //
  //M1
  digitalWrite(pwma, 50);
  digitalWrite(ain2, HIGH);
  digitalWrite(ain1, LOW);
  //M2
  digitalWrite(pwmb, 100);
  digitalWrite(bin2, HIGH);
  digitalWrite(bin1, LOW);
  }
  //End of 1 thing//
  //=================================================
  //Start of 2 thing//
  if(currentMillis - previousMillis2 > interval) {
    // save the last time 
    previousMillis2 = currentMillis;   
// === turn around === //
  //M1
  digitalWrite(pwma, 50);
  digitalWrite(ain2, LOW);
  digitalWrite(ain1, HIGH);
  //M2
  digitalWrite(pwmb, 100);
  digitalWrite(bin2, HIGH);
  digitalWrite(bin1, LOW);
  }
  //End of 2 thing//
  //=================================================
}

[/code]

The intentions of your code would be clearer if you indented correctly.
Try the auto format tool in the IDE and repost.

Why not use a pin-change interrupt to handle that? Look up the attachInterrupt() function on the main site. Saves you having to poll the switches all the time to see if something happened.

long previousMillis = 0;    // will store last time LED was updated
long previousMillis2 = 0;
long previousMillis3 = 0;

Is that the way you normally count things? Most people count 1, 2, 3...

When you find yourself numbering variables, its time to think arrays.

void button3() {

Perhaps you've noticed that the Arduino comes with functions like digitalRead(), analogWrite(), etc. where the function name clearly defines what the function does. button3 does no such thing.

I have tried using millis() but can't work it out.

The code does something. You expect it to do something. If the two somethings were the same, it is unlikely that you would be posting here.

However, you have not explained what either something is, so I'm having a hard time understanding how to help you.

Saves you having to poll the switches all the time to see if something happened.

With an interrupt that sets a flag, instead you'd need to constantly check the flag. That isn't noticeably faster.

jabelone:
What I want to happen is my robot is going along a pre-programmed course but when a button on the front of jabduino gets pressed (bumped into a wall) how can I make the robot then "DO THIS."

You are on the right path with how you are using millis(), but you might also want to consider a state machine.

Create a variable (usually called something clever like "STATE") that you assign values to let you know what the robot should be doing.

Thanks everyone, I'm only 14 so don't know much about programming in C++. I think the attachInterrupt(0, button3, RISING) would be the best and easiest. I will let you all know when I get it working or get it just sitting there again. :slight_smile:

PaulS:

Saves you having to poll the switches all the time to see if something happened.

With an interrupt that sets a flag, instead you'd need to constantly check the flag. That isn't noticeably faster.

Also thanks PaulS but I'm not that worried about the speed of the code yet... I just want it to work! :)[quote author=James C4S link=topic=113803.msg856108#msg856108 date=1342011261]

jabelone:
What I want to happen is my robot is going along a pre-programmed course but when a button on the front of jabduino gets pressed (bumped into a wall) how can I make the robot then "DO THIS."

You are on the right path with how you are using millis(), but you might also want to consider a state machine.

Create a variable (usually called something clever like "STATE") that you assign values to let you know what the robot should be doing.
[/quote]

I am just going to try interrupts first, if I were to do a state machine. would this tut be the right thing?
[url=http://www.isisconceptuallaboratory.com/teaching/Sm[Art]%20Spaces/fsm.pdf]isisconceptuallaboratory.com

PaulS:

long previousMillis = 0;    // will store last time LED was updated

long previousMillis2 = 0;
long previousMillis3 = 0;



Is that the way you normally count things? Most people count 1, 2, 3...

Sorry, I confuse myself sometimes because Ls and 1s look exactly the same.

AWOL:
The intentions of your code would be clearer if you indented correctly.
Try the auto format tool in the IDE and repost.

Sorry, here it is.

//Setup our motors and speed control plus define our pins
// Motor 1
#define pwma 11
#define ain2 10
#define ain1 9

//Motor 2
#define pwmb 7
#define bin1 6
#define bin2 5

volatile int state = LOW;

void setup() {

  // ==== Motor 1 ===== //
  //PWMA
  pinMode(pwma, OUTPUT);
  //AIN2
  pinMode(ain2, OUTPUT); 
  //AIN1 
  pinMode(ain1, OUTPUT);

  // ==== Motor 2 ==== //
  //BIN1
  pinMode(bin1, OUTPUT);
  //BIN2
  pinMode(bin2, OUTPUT);
  //PWMB
  pinMode(pwmb, OUTPUT);

  //BUTTON STUFF
#define button 2
  pinMode(button, INPUT);
  
  attachInterrupt(0, button3, RISING);

}

void loop()
{
  //=================================================
  //Start of 1st thing//
   
    // ===== Straight ===== //
    //M1
    digitalWrite(pwma, 50);
    digitalWrite(ain2, HIGH);
    digitalWrite(ain1, LOW);
    //M2
    digitalWrite(pwmb, 100);
    digitalWrite(bin2, HIGH);
    digitalWrite(bin1, LOW);
    delay(1000)
  
  
  //End of 1st thing//
  //=================================================
  //Start of 2nd thing//
  
    // === turn around === //
    //M1
    digitalWrite(pwma, 50);
    digitalWrite(ain2, LOW);
    digitalWrite(ain1, HIGH);
    //M2
    digitalWrite(pwmb, 100);
    digitalWrite(bin2, HIGH);
    digitalWrite(bin1, LOW);
  }
  //End of 2nd thing//
  //=================================================

void button3() {
  //Go backwards
  //M1
  digitalWrite(pwma, 50);
  digitalWrite(ain2, LOW);
  digitalWrite(ain1, HIGH);
  //M2
  digitalWrite(pwmb, 100);
  digitalWrite(bin2, LOW);
  digitalWrite(bin1, HIGH);
  delay(1000);

  // === turn around === //
  //M1
  digitalWrite(pwma, 50);
  digitalWrite(ain2, LOW);
  digitalWrite(ain1, HIGH);
  //M2
  digitalWrite(pwmb, 100);
  digitalWrite(bin2, HIGH);
  digitalWrite(bin1, LOW);
  delay(250);

}

Sorry, I confuse myself sometimes because Ls and 1s look exactly the same.

Understood. But, A, B, and C look distinctly different, don't they?

I'd like to encourage you, now, to loose the // on the end of comments. Unnecessary and distracting.

Also, good comments are useful. When you find yourself with comments like this:

  //Start of 1st thing//
  //End of 1st thing//
  //=================================================
  //Start of 2nd thing//
  //End of 2nd thing//

it makes me think that you don't have a good grasp of what the code is doing, so you just stuck some junk there.

If the code is understandable without comments, don't feel that you need to add some just to look nice. If not, and the comments are needed, there are two things you can do. First, understand what the code is doing, and write comments that reflect that. Or, put in comments that admit you don't know what the code does. Someone will be sure to offer advice, if you ask. Sometimes, even if you don't.

You're doing great, so I don't want to see you develop bad habits that you will need to unlearn.

void button3() {

And, functions still need meaningful names... :slight_smile:

Good to see you getting into it at 14. :slight_smile: One of my son's friends is the same age and making a "Tamagotchi" Arduino ... I think.

A couple of suggestions:

long previousMillis2 = 0;

Time should really be unsigned long. It will wrap around twice as quickly if it is a long, eg.

unsigned long previousMillis2 = 0;

If you want to learn about interrupts:

However in your case, where you want to do a lot if you hit a wall, your main loop might be simpler as:

void loop ()
  {

  if (digitalRead (wallButton) == HIGH) 
     doHitWall ();  
  else
     doSomethingElse ();

  } // end of loop

Then make functions do to one thing if you are against the wall, and a different thing if not.

THANKS!!

I finally go it working with the if statement!! (I have found it the easiest way to do it)
If I had used interrupts it only does my wall function for a few microseconds.
So if statements seemed like the best way to go (well for me anyway). The only thing is that I had to put lots of delays and ifs :). It works, and I'm happy. :open_mouth:

Here is my final code if anyone wanted to see it!

void setup() {                
  //Setup our motors and speed control plus define our pins

  //Give names to the Motor 1 pins so we can easily change them.
#define pwma 11
#define ain2 10
#define ain1 9

  //Give names to the Motor 2 pins so we can easily change them.
#define pwmb 5
#define bin1 7
#define bin2 6

  //Give a name to our button pin so we can esialy change it.
#define button 2

  //Give our LEDs a name
#define LED 3


  //Motor 1 Outputs
  //PWMA
  pinMode(pwma, OUTPUT);
  //AIN2
  pinMode(ain2, OUTPUT); 
  //AIN1 
  pinMode(ain1, OUTPUT);

  //Motor 2 Outputs
  //BIN1
  pinMode(bin1, OUTPUT);
  //BIN2
  pinMode(bin2, OUTPUT);
  //PWMB
  pinMode(pwmb, OUTPUT);

  //Set button as output
  pinMode(button, INPUT);

  //Set-up LEDs
  pinMode(LED, OUTPUT);
  
  digitalWrite(button, HIGH);

}

void loop() { 
  
  digitalWrite(LED, HIGH);

  int ranNum;
  int ranNuma;
  ranNum = random(25, 100);
  ranNuma = random(100, 200);
  
  if (digitalRead (button) == LOW) { Wall(); }
  
  else {
  // === turn around === //
  //M1
  digitalWrite(pwma, 100);
  digitalWrite(ain2, LOW);
  digitalWrite(ain1, HIGH);
  //M2
  digitalWrite(pwmb, 100);
  digitalWrite(bin2, HIGH);
  digitalWrite(bin1, LOW);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNum);
  if (digitalRead (button) == LOW) { Wall(); }

  // ===== Straight ===== //
  //M1
  digitalWrite(pwma, 100);
  digitalWrite(ain2, HIGH);
  digitalWrite(ain1, LOW);
  //M2
  digitalWrite(pwmb, 100);
  digitalWrite(bin2, HIGH);
  digitalWrite(bin1, LOW);
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  delay(ranNuma);
  if (digitalRead (button) == LOW) { Wall(); }
  }
}

void Wall(){
  // === Go Backwards === //
  //M1
  digitalWrite(pwma, 255);
  digitalWrite(ain2, LOW);
  digitalWrite(ain1, HIGH);
  //M2
  digitalWrite(pwmb, 255);
  digitalWrite(bin2, LOW);
  digitalWrite(bin1, HIGH);
  delay(2000);


}