Arduino控制6个不同模式的电磁阀

时间:2016-07-04 02:19:38

标签: c++ arduino

我正在开发一个需要控制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. 
}

1 个答案:

答案 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检查程序。