Help with a timed output

Hello all,

I am trying to make a controller for a transmission shifting mechanism. What I am trying to do is have a push button trigger a timed 5v output to a relay which will open a solenoid, moving the actuator. My question is... which function would be easiest to trigger for a certain length of time (milliseconds)? I have seen the scheduler, fuse burn, and others but I dont think they would work.. I was thinking maybe the delay function? I am a totally noob at this but I want to learn, so if you could point me in the right direction that would be great!

Thanks!

I am a totally noob at this but I want to learn

Then start reading the tutorials at http://arduino.cc/en/Tutorial/HomePage Yes, it takes some time but all this knowledge is available for free!

For your application these two are interesting:

after some thought it appears i was over complicating things. adding a delay after digitalwrite appears to work.

const int buttonPin = 2;
const int ledPin = 13;

int buttonState = 0;

void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}

void loop(){
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
digitalWrite(ledPin, HIGH);
delay(250);
digitalWrite(ledPin, LOW);
}
else {
digitalWrite(ledPin, LOW);
}
}

Thanks! This was definitely a duh moment.... :-/ I will post some updates as I am trying to incorporate a led tach.

adding a delay after digitalwrite appears to work

It works as long as you don't need to use the processor for a quarter of a second.

When you've looked at the Blink tutorial, have a look at the Blink Without Delay tutorial.

Am I going about this the right way? (note i have only modified the "upshift") it also says lvalue required as left operand of assignment...

const int UpButton = 2;
const int DownButton = 3;
const int NeutralButton = 4;
const int UpRelay = 12;
const int DownRelay = 13;

int UpState = 0;
int DownState = 0;
int NeutralState = 0;

long interval = 250;
long Upstart = 0;

void setup() {
pinMode(UpRelay, OUTPUT);
pinMode(DownRelay, OUTPUT);
pinMode(UpButton, INPUT);
pinMode(DownButton, INPUT);
pinMode(NeutralButton, INPUT);
}

void loop(){

UpState = digitalRead(UpButton);
DownState = digitalRead(DownButton);
NeutralState = digitalRead(NeutralButton);

if (UpState == HIGH) {
digitalWrite(UpRelay, HIGH);
unsigned long Upstart = millis();
if (Upstart + interval = millis() ) {
digitalWrite(UpRelay, LOW);
}
else {
digitalWrite(UpRelay, HIGH);
}
}
else {
digitalWrite(UpRelay, LOW);
}
if (DownState == HIGH) {
digitalWrite(DownRelay, HIGH);
delay(250);
digitalWrite(DownRelay, LOW);
}
else {
digitalWrite(DownRelay, LOW);
}
if (NeutralState == HIGH) {
digitalWrite(UpRelay, HIGH);
delay(250);
digitalWrite(UpRelay, LOW);
}
else {
digitalWrite(UpRelay, LOW);
}
}

Am I going about this the right way?

No, you need to use the # icon on the editor's toolbar when you're posting code.

Upstart + interval = millis()

'=' is an assignment.
'==' is a comparison.

unsigned long Upstart = millis();
    if (Upstart + interval [glow]== [/glow]millis() ) {

Seems unlikely, doesn't it?

Ah ok my bad, I will try this tonight. What do you mean by it seems unlikely?

Suppose millis return 27. You store that in Upstart. That takes a couple of machine instructions to perform, granted, but each machine instruction executes in 62.5 nano-seconds, so it's not a LOT of time.

Then, you immediately test if Upstart + interval is equal to the value returned by millis.

Unless you have changed out the crystal on your Arduino, it does not seem like that 1/4 of a second has elapsed while the value was stored, millis was called again, and the if statement evaluated.

If you got one of those 4Hz crystals, maybe...

Since the Arduino comes with either a 8,000,000 or 16,000,000 Hz crystal, it seems unlikely that the if condition will ever evaluate to true.

That makes sense, again I am very new to this so forgive me. Can you recommend a different way? Or point me to an example that I can learn from?

Just noticed something,

if (Upstart + interval == millis() ) {
     digitalWrite(UpRelay, LOW);
    }
     else {
      digitalWrite(UpRelay, LOW);

After some talking with a work friend of mine, we were able to get a working code.

const int UpButton = 2;
const int DownButton = 3;
const int NeutralButton = 4;
const int UpRelay = 12;
const int DownRelay = 13;

int UpState = 0;
int DownState = 0;
int NeutralState = 0;
int UpsolState = 0;
int DownsolState = 0;

long Upinterval = 5000;
long Downinterval = 5000;
long Neutralinterval = 5000;
long Upstart = 0;
long Downstart = 0;
long Neutralstart = 0;

void setup() {
  pinMode(UpRelay, OUTPUT);
  pinMode(DownRelay, OUTPUT);
  pinMode(UpButton, INPUT);
  pinMode(DownButton, INPUT);
  pinMode(NeutralButton, INPUT);
}

void loop(){
 
  UpState = digitalRead(UpButton);
  DownState = digitalRead(DownButton);
  NeutralState = digitalRead(NeutralButton);
  digitalWrite(UpRelay, UpsolState);
  digitalWrite(DownRelay, DownsolState);
  
  if (UpState == HIGH && UpsolState == LOW)
  {
    UpsolState = HIGH;
    Upstart = millis();
  }
  if (Upstart + Upinterval == millis() && UpsolState == HIGH ) 
  {
    UpsolState = LOW;
  }
    if (DownState == HIGH && DownsolState == LOW)
  {
    DownsolState = HIGH;
    Downstart = millis();
  }
  if (Downstart + Downinterval == millis() && DownsolState == HIGH ) 
  {
    DownsolState = LOW;
  }
   if (NeutralState == HIGH && UpsolState == LOW)
  {
    UpsolState = HIGH;
    Neutralstart = millis();
  }
  if (Neutralstart + Neutralinterval == millis() && UpsolState == HIGH ) 
  {
    UpsolState = LOW;
  }
}

Okay so now I have the issue that when I hold the button down it holds the relay/solenoid open. I'm fairly sure that it is because the delay is starting after the button is closed not as soon as it opens.. which doesnt make much sense to me.

HELP!!

Do you have external pull-up or pull-down resistors on the switches? You are not enabling the internal pull-ups, so external ones are required.

  if (Downstart + Downinterval == millis() && DownsolState == HIGH )

The value returned by millis should never appear to one side of the == operator. The value returned by millis should never be used in an addition construct.

Try something like this:

if(Downstart - millis() >= Downinterval) && DownsolState == HIGH)

I do have 10k pull down resistors on each button. I will try this code tonight.

Just looking at that code.. Wouldn't this give you a negative number?