change activity with time

Hey All,
I'm trying to get my arduino Uno to steer by a compass (works) but I want it to change direction after 10 seconds and I cant seem to get it to work. heres what I have for code so far. IF I drop the "while" statement and just pick one direction or the other, it works fine.

#include <Time.h> //??

unsigned long time = millis();


while (time < 10000){ //for first ten seconds, go east
if(headingValue/10 >= 95 && headingValue/10 <= 270)
    Steering.write(left);
  if (headingValue/10 <= 85 || headingValue/10 > 270)
    Steering.write(right);
  if (headingValue/10 >85 && headingValue/10 <95)
    Steering.write(straight);
}
  delay(10);
  //turn around (west) and keep running home
  while(time >= 10000){
    if(headingValue/10 >= 275 || headingValue/10 <= 90)
    Steering.write(left);
  if (headingValue/10 <= 265 && headingValue/10 > 90)
    Steering.write(right);
  if (headingValue/10 >265 && headingValue/10 <275)
    Steering.write(straight);
}

Any help would be great. Thanks everyone

while (time < 10000)

And what happens after 10 seconds after reset?

Are you saying it wont read the second batch of directions because it's not specified in the first "while" statement?

I dont know what's going on but It only transmits a compass reading once after startup, which it reacts appropriately to. The problem is it wont update

All I'm saying is that it won't compile, so whether it works or not is moot.

We need to see the real and complete code. Code that will compile. The code in the first posting won't compile.

Do NOT update the first posting. That would only confuse people. Please provide a new post that contains the actual code.

Thanks!

Gotcha guys, sorry about that. heres the whole picture:

#include <Wire.h>

#include <Servo.h>  //includes the servo library to PWM the servo
#include <Time.h> //??

unsigned long time = millis();

int HMC6352Address = 0x42;
// This is calculated in the setup() function
int slaveAddress;
int ledPin = 13;
boolean ledState = false;
byte headingData[2];
int i, headingValue;

const int ENA = 9;
const int IN1 = 12;
const int IN2 = 13;

//servo control?
Servo Steering; //defines the servo to be used to steer?

int depthValue;

const int left = 135;
const int right = 45;
const int straight = 90;

void setup()
{
// Shift the device's documented slave address (0x42) 1 bit right
// This compensates for how the TWI library only wants the
// 7 most significant bits (with the high bit padded with 0)
slaveAddress = HMC6352Address >> 1;   // This results in 0x21 as the address to pass to TWI

Serial.begin(9600);


Wire.begin();

pinMode(ENA, OUTPUT); // only controls one motor - Hbridge could do 2...
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);

Depth.attach(11);
Steering.attach(10);  //attaches the steering servo to pin 10

}
void loop()
{
  
  // Send a "A" command to the HMC6352
  // This requests the current heading data
  Wire.beginTransmission(slaveAddress);
  Wire.write("A");              // The "Get Data" command
  Wire.endTransmission();
  delay(10);                   // The HMC6352 needs at least a 70us (microsecond) delay
  // after this command.  Using 10ms just makes it safe
  // Read the 2 heading bytes, MSB first
  // The resulting 16bit word is the compass heading in 10th's of a degree
  // For example: a heading of 1345 would be 134.5 degrees
  Wire.requestFrom(slaveAddress, 2);        // Request the 2 byte heading (MSB comes first)
  i = 0;
  while(Wire.available() && i < 2)
  { 
    headingData[i] = Wire.read();
    i++;
  }
  headingValue = headingData[0]*256 + headingData[1];  // Put the MSB and LSB together
  Serial.print("Current heading: ");
  Serial.print(int (headingValue / 10));     // The whole number part of the heading
  Serial.print(".");
  Serial.print(int (headingValue % 10));     // The fractional part of the heading
  Serial.println(" degrees");
  delay(500);
  
  delay(10);
//MOTOR CONTROL as taken from somewhere and butchered
digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW); // GO!
  
  
  //my attempts at driving this thing
if (time < 10000){ //for first ten seconds, go east
if(headingValue/10 >= 95 && headingValue/10 <= 270)
    Steering.write(left);
  if (headingValue/10 <= 85 || headingValue/10 > 270)
    Steering.write(right);
  if (headingValue/10 >85 && headingValue/10 <95)
    Steering.write(straight);
}
  delay(10);
  //turn around (west) and keep running home
  if(time >= 10000){
    if(headingValue/10 >= 275 || headingValue/10 <= 90)
    Steering.write(left);
  if (headingValue/10 <= 265 && headingValue/10 > 90)
    Steering.write(right);
  if (headingValue/10 >265 && headingValue/10 <275)
    Steering.write(straight);
}
delay (10);
}

I have changed the "while" statements since my original posting for "if" statements and have a faster refresh rate but it still refuses to read the second step - to turn around and go west

Thanks for the help

I auto-formatted your code - hopefully this makes things clearer.

#include <Wire.h>

#include <Servo.h>  //includes the servo library to PWM the servo
#include <Time.h> //??

unsigned long time = millis();

int HMC6352Address = 0x42;
// This is calculated in the setup() function
int slaveAddress;
int ledPin = 13;
boolean ledState = false;
byte headingData[2];
int i, headingValue;

const int ENA = 9;
const int IN1 = 12;
const int IN2 = 13;

//servo control?
Servo Steering; //defines the servo to be used to steer?

int depthValue;

const int left = 135;
const int right = 45;
const int straight = 90;

void setup()
{
  // Shift the device's documented slave address (0x42) 1 bit right
  // This compensates for how the TWI library only wants the
  // 7 most significant bits (with the high bit padded with 0)
  slaveAddress = HMC6352Address >> 1;   // This results in 0x21 as the address to pass to TWI

  Serial.begin(9600);


  Wire.begin();

  pinMode(ENA, OUTPUT); // only controls one motor - Hbridge could do 2...
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);

  Depth.attach(11);
  Steering.attach(10);  //attaches the steering servo to pin 10

}
void loop()
{

  // Send a "A" command to the HMC6352
  // This requests the current heading data
  Wire.beginTransmission(slaveAddress);
  Wire.write("A");              // The "Get Data" command
  Wire.endTransmission();
  delay(10);                   // The HMC6352 needs at least a 70us (microsecond) delay
  // after this command.  Using 10ms just makes it safe
  // Read the 2 heading bytes, MSB first
  // The resulting 16bit word is the compass heading in 10th's of a degree
  // For example: a heading of 1345 would be 134.5 degrees
  Wire.requestFrom(slaveAddress, 2);        // Request the 2 byte heading (MSB comes first)
  i = 0;
  while(Wire.available() && i < 2)
  { 
    headingData[i] = Wire.read();
    i++;
  }
  headingValue = headingData[0]*256 + headingData[1];  // Put the MSB and LSB together
  Serial.print("Current heading: ");
  Serial.print(int (headingValue / 10));     // The whole number part of the heading
  Serial.print(".");
  Serial.print(int (headingValue % 10));     // The fractional part of the heading
  Serial.println(" degrees");
  delay(500);

  delay(10);
  //MOTOR CONTROL as taken from somewhere and butchered
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW); // GO!

  //my attempts at driving this thing
  if (time < 10000){ //for first ten seconds, go east
    if(headingValue/10 >= 95 && headingValue/10 <= 270)
      Steering.write(left);
    if (headingValue/10 <= 85 || headingValue/10 > 270)
      Steering.write(right);
    if (headingValue/10 >85 && headingValue/10 <95)
      Steering.write(straight);
  }
  delay(10);
  //turn around (west) and keep running home
  if(time >= 10000){
    if(headingValue/10 >= 275 || headingValue/10 <= 90)
      Steering.write(left);
    if (headingValue/10 <= 265 && headingValue/10 > 90)
      Steering.write(right);
    if (headingValue/10 >265 && headingValue/10 <275)
      Steering.write(straight);
  }
  delay (10);
}

So I trimmed a bunch of the extra "delay"s out and it responds quickly to changes in direction but I still cant get it to turn around after 10 seconds... Any suggestions?

Try a difference in time, rather than an absolute time.

HA! WORKS! awesome AWOL, thanks much!

an case anyone is looking for this later, heres those last two paragraphs and how I modified them. I really just swapped in "millis() - time" for "time"

if ((millis() - time) < 10000){ //for first ten seconds, go east
    if(headingValue/10 >= 95 && headingValue/10 <= 270)
      Steering.write(left);
    if (headingValue/10 <= 85 || headingValue/10 > 270)
      Steering.write(right);
    if (headingValue/10 >85 && headingValue/10 <95)
      Steering.write(straight);
  }
 
  //turn around (west) and keep running home
  if((millis() - time) > 10000){
    if(headingValue/10 >= 275 || headingValue/10 <= 90)
      Steering.write(left);
    if (headingValue/10 <= 265 && headingValue/10 > 90)
      Steering.write(right);
    if (headingValue/10 >265 && headingValue/10 <275)
      Steering.write(straight);

I don't see what you're doing with "time", but it doesn't look great.

now youre making me doubt myself....

I defined "time" in the beginning:

unsigned long time = millis();

so I agree that I have no idea what I'm doing but it switched direction after 10 seconds...

far as I can tell I subtracted millis from millis.... but you said "try a difference in time" and it seemed to work

so I agree that I have no idea what I'm doing

And nor do we, since you didn't post your code.

ok ok ok. here she is in the entirety:

#include <Wire.h>

#include <Servo.h>  //includes the servo library to PWM the servo
#include <Time.h> //??

unsigned long time = millis();

int HMC6352Address = 0x42;
// This is calculated in the setup() function
int slaveAddress;
int ledPin = 13;
boolean ledState = false;
byte headingData[2];
int i, headingValue;

const int ENA = 9;
const int IN1 = 12;
const int IN2 = 13;

//servo control?
Servo Steering; //defines the servo to be used to steer?

int depthValue;

const int left = 135;
const int right = 45;
const int straight = 90;

void setup()
{
  // Shift the device's documented slave address (0x42) 1 bit right
  // This compensates for how the TWI library only wants the
  // 7 most significant bits (with the high bit padded with 0)
  slaveAddress = HMC6352Address >> 1;   // This results in 0x21 as the address to pass to TWI

  Serial.begin(9600);


  Wire.begin();

  pinMode(ENA, OUTPUT); // only controls one motor - Hbridge could do 2...
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);

 
  Steering.attach(10);  //attaches the steering servo to pin 10

}
void loop()
{

  // Send a "A" command to the HMC6352
  // This requests the current heading data
  Wire.beginTransmission(slaveAddress);
  Wire.write("A");              // The "Get Data" command
  Wire.endTransmission();
  delay(10);                   // The HMC6352 needs at least a 70us (microsecond) delay
  // after this command.  Using 10ms just makes it safe
  // Read the 2 heading bytes, MSB first
  // The resulting 16bit word is the compass heading in 10th's of a degree
  // For example: a heading of 1345 would be 134.5 degrees
  Wire.requestFrom(slaveAddress, 2);        // Request the 2 byte heading (MSB comes first)
  i = 0;
  while(Wire.available() && i < 2)
  { 
    headingData[i] = Wire.read();
    i++;
  }
  headingValue = headingData[0]*256 + headingData[1];  // Put the MSB and LSB together
  Serial.print("Current heading: ");
  Serial.print(int (headingValue / 10));     // The whole number part of the heading
  Serial.print(".");
  Serial.print(int (headingValue % 10));     // The fractional part of the heading
  Serial.println(" degrees");
  delay(100);

  //my attempts at driving this thing
  if ((millis() - time) < 10000){ //for first ten seconds, go east
    if(headingValue/10 >= 95 && headingValue/10 <= 270)
      Steering.write(left);
    if (headingValue/10 <= 85 || headingValue/10 > 270)
      Steering.write(right);
    if (headingValue/10 >85 && headingValue/10 <95)
      Steering.write(straight);
  }
 
  //turn around (west) and keep running home
  if((millis() - time) > 10000){
    if(headingValue/10 >= 275 || headingValue/10 <= 90)
      Steering.write(left);
    if (headingValue/10 <= 265 && headingValue/10 > 90)
      Steering.write(right);
    if (headingValue/10 >265 && headingValue/10 <275)
      Steering.write(straight);
  }
  delay (10);
}

Tell us about the variable "time"

Its just "millis" really which is why I dont understand how this works. I subtract millis from millis and end up with the relative time since start...?

Gaber:
Its just "millis" really which is why I dont understand how this works. I subtract millis from millis and end up with the relative time since start...?

Your initial time (the value from millis() when you initialize time) is going to be nearly 0. All your times are still relative to when the Arduino was restarted, not relative to the last time you did something. If that's what you want, fine, but using now minus just after reset, as opposed to now, didn't really change anything.

Thanks Paul, I understand it now. I thought I had defined "time" as a changing number but now that you say that, I see how it is a fixed number. This is what I want and I see how it works now. I really appreciate the help from all - AWOL, vaj, and Paul.

-Gabe