Управление моторными реле через 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);
}