简体   繁体   中英

Controlling Motor Relays via Arduino using protothreads

I am working on controlling two motor relays via an arduino. The setup is the following:

Each relay is controlled by a simple switch setup. When the switch is closed, the relay is active. When the switch is open, the relay is inactive.

I decided to give protothreads a go since I want the two switches to control the motors in paralell. In order to do so, I have written the following code:

 #include <pt.h>

#define yMaxLimitLeft 8 //these are the limit switches that control the relays
#define yMaxLimitRight 9 //these are the limit switches that control the relays
#define leftRelay 4
#define rightRelay 5

static struct pt pt1, pt2; // each protothread needs one of these



void setup() {
  Serial.begin(9600);
  PT_INIT(&pt1);  // initialise the two
  PT_INIT(&pt2);  // protothread variables
  pinMode(leftRelay, OUTPUT);  //set pins     
  pinMode(rightRelay, OUTPUT);
  pinMode(yMaxLimitLeft,INPUT);
  pinMode(yMaxLimitRight,INPUT);

}

void loop() {

   digitalWrite(leftRelay, HIGH);//enable relays
  digitalWrite(rightRelay, HIGH);//enable relays
   runLeft(&pt1); //protothreads that controls relay number 1
  runRight(&pt2); //protothreads that controls relay number 2

}

/////////////////////////////////////////////////////////////////////////////
// This function controls the left relay
static int runLeft(struct pt *pt) {

  PT_BEGIN(pt);

  while(1){

    PT_WAIT_UNTIL(pt, digitalRead(yMaxLimitLeft)==HIGH); //wait until the switch is closed
     Serial.println("left off"); 
      digitalWrite(leftRelay, LOW);//disable relay

      }   

    PT_END(pt);
}


//this function controls the right relay
static int runRight(struct pt *pt) {
  PT_BEGIN(pt);

   while(1){


    PT_WAIT_UNTIL(pt, digitalRead(yMaxLimitRight)==HIGH); //wait until the switch is closed
     Serial.println("Right off");   
     digitalWrite(rightRelay, LOW);//disable relay

    }


  PT_END(pt);
}

The problem is the following. As long as I press down only one switch, the respective relay responds. However when I press down both switches, only one relay responds (presumable the one which got triggered the earliest).

How do I fix the code so that when both switches are held down, both relays respond simultaneously?

Thank you very much for your time and help in advance

As long as the predicate in PT_WAIT_UNTIL (ie digitalRead(yMaxLimitLeft)==HIGH ) is true, execution will be stuck in that while loop.

The code probably becomes easier to reason about if loop() only is responsible for keeping the protothreads running. If we move the initial enabling of the relays into setup() , runLeft/Right can be rewritten to contain all logic related to a certain switch+relay. In that case, a second PT_WAIT_UNTIL statement can be used to wait for the switch to open again.

#include <pt.h>

#define yMaxLimitLeft 8 //these are the limit switches that control the relays
#define yMaxLimitRight 9 //these are the limit switches that control the relays
#define leftRelay 4
#define rightRelay 5

static struct pt pt1, pt2; // each protothread needs one of these



void setup() {
  Serial.begin(9600);
  PT_INIT(&pt1);  // initialise the two
  PT_INIT(&pt2);  // protothread variables
  pinMode(leftRelay, OUTPUT);  //set pins     
  pinMode(rightRelay, OUTPUT);
  pinMode(yMaxLimitLeft,INPUT);
  pinMode(yMaxLimitRight,INPUT);    

  digitalWrite(leftRelay, HIGH);//enable relays
  digitalWrite(rightRelay, HIGH);//enable relays

}

void loop() {

  runLeft(&pt1); //protothreads that controls relay number 1
  runRight(&pt2); //protothreads that controls relay number 2

}

/////////////////////////////////////////////////////////////////////////////
// This function controls the left relay
static int runLeft(struct pt *pt) {

  PT_BEGIN(pt);

  while(1) {

    PT_WAIT_UNTIL(pt, digitalRead(yMaxLimitLeft)==HIGH); //wait until the switch is closed
    Serial.println("left off"); 
    digitalWrite(leftRelay, LOW);//disable relay

    PT_WAIT_UNTIL(pt, digitalRead(yMaxLimitLeft)==LOW); //wait until the switch opens again
    digitalWrite(leftRelay, HIGH);//enable relay

  }   

  PT_END(pt);
}


//this function controls the right relay
static int runRight(struct pt *pt) {
  PT_BEGIN(pt);

    while(1){

      PT_WAIT_UNTIL(pt, digitalRead(yMaxLimitRight)==HIGH); //wait until the switch is closed
      Serial.println("Right off");   
      digitalWrite(rightRelay, LOW);//disable relay

      PT_WAIT_UNTIL(pt, digitalRead(yMaxLimitRight)==LOW); //wait until the switch opens again
      digitalWrite(rightRelay, HIGH);//enable relay
    }


  PT_END(pt);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM