我正在开发一个需要控制6个电磁阀的项目。我决定使用arduino来实现这一目标。我的项目要求我用不同的时间打开/关闭任意数量的这种阀门。例如,一种模式可能是阀门1,2,3打开2.5秒而阀门4,5,6关闭,然后阀门4,5,6打开2.5,而1,2,3打开,因此上。现在,当我尝试实现一个功能,我可以使用IR遥控器选择不同的模式时,我陷入困境。我不知道如何调整时间并使其在中期同步。这是我到目前为止编写的代码。在代码的底部,您可以看到我用来获取上面提到的模式的示例。 chooseOption变量旨在用于选择将执行哪种开/关阀模式。
#include <IRremote.h>
int input_pin = 28; //set D10 as input signal pin
IRrecv irrecv(input_pin);
decode_results signals;
class Flasher
{
public:
Flasher(int pin, long on, long off)
{
ledPin = pin;
pinMode(ledPin, OUTPUT);
OnTime = on;
OffTime = off;
ledState = LOW;
previousMillis = 0;
digitalWrite(ledPin, HIGH);
}
void setTimes(long newOn, long newOff);
void Update()
{
// check to see if it's time to change the state of the LED
unsigned long currentMillis = millis();
if((ledState == LOW) && (currentMillis - previousMillis >= OnTime))
{
ledState = HIGH; // Turn it off
previousMillis = currentMillis; // Remember the time
digitalWrite(ledPin, ledState); // Update the actual LED
}
else if ((ledState == HIGH) && (currentMillis - previousMillis >= OffTime))
{
ledState = LOW; // turn it on
previousMillis = currentMillis; // Remember the time
digitalWrite(ledPin, ledState); // Update the actual LED
}
}
private:
int ledPin;
long OnTime;
long OffTime;
int ledState;
unsigned long previousMillis;
};
void Flasher::setTimes(long newOn, long newOff)
{
OffTime = newOff;
OnTime = newOn;
}
unsigned long time;
int onT = 2500;
int offT = 2500;
//Flasher led1(portNo, OnTime, OffTime)
Flasher led1(22, onT, offT);
Flasher led2(23, onT, offT);
Flasher led3(24, onT, offT);
Flasher led4(25, onT, offT);
Flasher led5(26, onT, offT);
Flasher led6(27, onT, offT);
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // enable input from IR receiver
}
int chooseOption =0;
void loop()
{
time = millis();
if (irrecv.decode(&signals))
{
if(signals.value == 0x9716BE3F)
{
chooseOption = 1;
}
else if(signals.value == 0x3D9AE3F7)
{
chooseOption = 2;
}
irrecv.resume(); // get the next signal
}
//So here for example I can do something like
if(time > 5000)
{
led1.Update();
led3.Update();
led5.Update();
}
if(time >7500)
{
led2.Update();
led4.Update();
led6.Update();
//and pumps 1 3 and 5 are on for 2.5 secs and then pumps 2,4 and 6 are on and so on.
}
答案 0 :(得分:1)
我认为你的程序应该是这样的:
//(I don't explain IRremote implementations, since yours is good)
#define xor(a,b) (( a && (!b)) || ((!a) && b))
#define n_ports 6 //not to waste memory
#define input_pin 28
byte ports[n_ports] = {22, 23, 24, 25, 26, 27}; //you can also use int if you prefer
int i=0; // counter variable
bool b_pattern[7];
void setup() {
for(i=0;i<n_ports;i++)
pinMode(ports[i], OUTPUT);
//IRremote initialization
}
void loop() {
time = millis();
//(IRremote implementations)
switch(chooseOption) { //for different patterns
case 0: //here some examples
time = time%5000;//notice the "time%5000": it's to get 5 seconds periods, you can set it as you want
b_pattern[0] = time<2500; //that's a weird boolean, shall be the same as HIGH and LOW
//if it doesnt work, just put an if construct
for(i=0;i<3;i++)
digitalWrite(ports[i], b_pattern[0] );
for(;i<6;i++) //yes, I'm ignoring n_ports checking *_*
digitalWrite(ports[i], !b_pattern[0] );
break;
case 1:
time = time%5000;
b_pattern[0] = time<1666; // 1/3 of 5 second-pattern
b_pattern[1] = time<2500; // 1/2
b_pattern[2] = time<3333; // 2/3
for(i=0;i<3;i++)
digitalWrite(ports[i], xor(b_pattern[0], b_pattern[2]) );
for(;i<4;i++)
digitalWrite(ports[i], !xor(b_pattern[0], b_pattern[2]) );
for(;i<6;i++)
digitalWrite(ports[i], b_pattern[1]);
break;
case 2:
time = time%6000;
b_pattern[0] = time<1000;
b_pattern[1] = time<1500;
b_pattern[2] = time<2000;
b_pattern[3] = time<3000;
b_pattern[4] = time<4000;
b_pattern[5] = time<4500;
b_pattern[6] = time<5000; //VERY weird but logic, let's simplify
b_pattern[1] = xor(b_pattern[1], xor(b_pattern[3], b_pattern[5]));
b_pattern[0] = xor(xor(xor(b_pattern[0], b_pattern[2]),xor(b_pattern[3], b_pattern[4])), b_pattern[6]);
for(i=0;i<3;i++)
digitalWrite( ports[i], b_pattern[1]);
for(;i<6;i++)
digitalWrite( ports[i], b_pattern[0]);
break;
}
}
要更改触发端口组,请更改端口阵列中的顺序。我还建议你先用leds检查程序。