Go Down

Topic: Run through sequence once on each button state.  (Read 163 times) previous topic - next topic

markwaibel

Aug 20, 2017, 02:15 am Last Edit: Aug 20, 2017, 03:46 am by markwaibel
Hi, I am very much a novice at this and was wandering if I could get some advice here.

I am trying to get a code on my arduino that will read the state on a digital pin and run through a different sequence of simple digitalWrite events depending on if the state is high or low. The part I am having a hard time with is I need it to only go through the sequence once every time the pin changes it's state. The current code I have here continuously loops the code during each state.

I tried using millis() to make it only run until it hit the end of the interval, but then after that it wouldn't run again. I tried for a considerable amount of time to use an interrupt as well, but I just couldn't get it to work.

Here is my current basic code:


int tractorState = 1;
int statePin = 7;

int highPin = 13;

int starterPin = 6;

int ptoForward = 4;
int ptoReverse = 3;

int throttleForward = 8;
int throttleReverse = 5;

void setup() {
  Serial.begin(9600);
    pinMode(ptoForward,OUTPUT);
    pinMode(ptoReverse,OUTPUT);
    pinMode(throttleForward,OUTPUT);
    pinMode(throttleReverse,OUTPUT);
    pinMode(starterPin,OUTPUT);
    pinMode(highPin,OUTPUT);
    pinMode(tractorState,INPUT);
}

void loop() {
 
 
  tractorState = digitalRead(statePin);
  digitalWrite(highPin,HIGH);

  if (tractorState == 1 )
 
  {
    starttractor();
    startpto();
    increasethrottle();
  }
    else if(tractorState == 0)
    {
    stoptractor();
    stoppto();
    decreasethrottle();
    }
 
}
void starttractor(){
  digitalWrite(starterPin,HIGH);
}

void startpto(){
  digitalWrite(ptoForward, HIGH);
  delay(10000);
  digitalWrite(ptoForward, LOW);
}

void increasethrottle(){
  digitalWrite(throttleForward,HIGH);
  delay(10000);
   digitalWrite(throttleForward,LOW);
}

void stoptractor(){
  digitalWrite(starterPin,LOW);
}

void stoppto(){
  digitalWrite(ptoReverse, HIGH);
  delay(10000);
  digitalWrite(ptoReverse, LOW);
}

void decreasethrottle(){
  digitalWrite(throttleReverse,HIGH);
  delay(10000);
  digitalWrite(throttleReverse,LOW);
}

Any feedback would be great. Thanks.

jbellavance

#1
Aug 20, 2017, 02:41 am Last Edit: Aug 20, 2017, 02:42 am by jbellavance
Hi,

The problem is that Arduino is much faster than you are.

A simple way to fire only once is to use the Click paradigm. Don't do anything before I release the switch.

That would translate to :
Code: [Select]
if (digitalRead(statePin) {
  while digitalRead(statePin) {;} //Wait for the button to be released
}
You could also take a look at this and this.

Jacques
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

gpop1

using flags rather than code would be a better way to handle the function calls

Code: [Select]

int tractorState = 1;
int statePin = 7;

int highPin = 13;

int starterPin = 7;

int ptoForward = 4;
int ptoReverse = 3;

int throttleForward = 8;
int throttleReverse = 5;

void setup() {
  Serial.begin(9600);
  pinMode(ptoForward, OUTPUT);
  pinMode(ptoReverse, OUTPUT);
  pinMode(throttleForward, OUTPUT);
  pinMode(throttleReverse, OUTPUT);
  pinMode(starterPin, OUTPUT);
  pinMode(highPin, OUTPUT);
  pinMode(tractorState, INPUT);
}

void loop() {
  static byte startonetime;
  static byte stoponetime;

  tractorState = digitalRead(statePin);
  digitalWrite(highPin, HIGH);

  if (tractorState == 1 )

  {
    startonetime = 1;//set a flag
  }
  else if (tractorState == 0)
  {
    stoponetime = 1;//set a flag
  }

  if (startonetime == 1) {//as this code is before stop it will run this cycle
    starttractor();
    startpto();
    increasethrottle();
    startonetime = 0;// this will stop it running the cycle again
  }

  if (stoponetime == 1) {//this code will run after the start cycle if both flags are true
    stoptractor();
    stoppto();
    decreasethrottle();
    stoponetime = 0;
  }

  //this is bad coding but as you are using delays it should work
  // plus it shows you how to use flags to control code
}
void starttractor() {
  digitalWrite(starterPin, HIGH);
}

void startpto() {
  digitalWrite(ptoForward, HIGH);
  delay(10000);
  digitalWrite(ptoForward, LOW);
}

void increasethrottle() {
  digitalWrite(throttleForward, HIGH);
  delay(10000);
  digitalWrite(throttleForward, LOW);
}

void stoptractor() {
  digitalWrite(starterPin, LOW);
}

void stoppto() {
  digitalWrite(ptoReverse, HIGH);
  delay(10000);
  digitalWrite(ptoReverse, LOW);
}

void decreasethrottle() {
  digitalWrite(throttleReverse, HIGH);
  delay(10000);
  digitalWrite(throttleReverse, LOW);
}

Go Up