Управление моторными реле через Arduino с использованием протопотоков

Я работаю над управлением двумя реле двигателя через Arduino. Настройка следующая:

Каждое реле управляется простой настройкой переключателя. Когда переключатель замкнут, реле активно. Когда переключатель разомкнут, реле неактивно.

Я решил попробовать прототипы, так как хочу, чтобы два переключателя управляли двигателями в параллельном режиме. Для этого я написал следующий код:

 #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);
}

Проблема в следующем. Пока я нажимаю только один переключатель, соответствующее реле реагирует. Однако, когда я нажимаю оба переключателя, срабатывает только одно реле (предположительно, то, которое сработало раньше).

Как исправить код так, чтобы, когда оба переключателя были нажаты, оба реле реагировали одновременно?

Большое спасибо за ваше время и помощь заранее

1 ответ

Пока предикат в PT_WAIT_UNTIL (т.е. digitalRead(yMaxLimitLeft)==HIGH) верно, выполнение будет зависать в цикле while.

Код, вероятно, станет легче рассуждать о том, loop() только отвечает за поддержание прототипов в рабочем состоянии. Если мы переместим первоначальное включение реле в setup(), runLeft/Right может быть переписан, чтобы содержать всю логику, связанную с определенным переключателем + реле. В этом случае второй PT_WAIT_UNTIL С помощью оператора можно дождаться, когда переключатель снова откроется.

#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);
}
Другие вопросы по тегам