在if语句中将digitalWrite设置为一定的秒数

时间:2016-08-30 07:44:35

标签: arduino

我有一个连接到pH传感器的Raspberry Pi 3,当pH超出设定的pH范围时,将通过i2c发送命令到raspi 3,它应该控制分配酸性或碱性溶液的电机。我如何设置,是raspi程序计算是否将分配酸或碱,然后运行电机的时间。 (现在是1-9秒)。然后它通过i2c向Arduino发送一个号码。

我的问题是Arduino希望电机运转而不是阻止它们。我尝试了“延迟(1000)”等,但电机在关闭之前只运行了一秒钟。

我有一个LED设置,当pH在范围内时为绿色,在低于时为蓝色,在结束时为红色。

我发现延迟()不是一件好事,所以我尝试实现了一个millis()系统,但这使得电机不停地运行。

这是代码。请记住,我几乎没有任何编码经验,而且几乎所有这些都来自其他Stack Overflow问题。

#include <Wire.h>

#define SLAVE_ADDRESS 0x04

//Apologies for this code. It was written by someone with almost no coding experience.

//colors are the led, the acidm & alkm are motors, l and r after it is left and right (cw vs ccw rotation)
int number = 0;
int state = 0;
int blue = 10;
int green = 9;
int red = 8;
int acidml = 5;
int acidmr = 4;
int alkml = 7;
int alkmr = 6;
int ph_lvl = 0;
int rtime = 0;
int mtime = 0;

//delay() seems to mess things up, so this will hopefully avoid it
unsigned long previousMillis = 0;
const long second = 1000;

void setup() {
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    Serial.begin(9600); // start serial for output

    // initialize i2c as slave
    Wire.begin(SLAVE_ADDRESS);

    // define callbacks for i2c communication
    Wire.onReceive(receiveData);

    Serial.println("Ready!");
}

void loop() {
    delay(100);
}

// callback for received data
void receiveData(int byteCount) {

    //this receives the number from the raspi
    while (Wire.available()) {
        number = Wire.read();
        Serial.print("data received: ");
        Serial.println(number);

        digitalWrite(alkmr, LOW);
        digitalWrite(acidmr, LOW);
        unsigned long currentMillis = millis();
        if (number > 20 && number < 30) {
            ph_lvl = 2;
        } else if (number < 20 && number > 10) {
            ph_lvl = 1;
        } else {
            ph_lvl = 0;
        }

        //the following serials are just for debugging
        Serial.println(ph_lvl);
        previousMillis = millis();
        if (ph_lvl == 2) {
            rtime = number - 20;
            digitalWrite(blue, HIGH);
            digitalWrite(alkml, HIGH);
            digitalWrite(acidml, LOW);
            Serial.println(rtime * second);
            mtime = rtime * 1000;
            if (currentMillis - previousMillis >= mtime) {
                previousMillis = currentMillis;
                digitalWrite(alkml, LOW);
                digitalWrite(blue, LOW);
                digitalWrite(green, HIGH);
            }
        } else {
            digitalWrite(blue, LOW);
            digitalWrite(alkml, LOW);
        }
        if (ph_lvl == 1) {
            rtime = number - 10;
            mtime = rtime * 1000;
            digitalWrite(red, HIGH);
            digitalWrite(alkml, LOW);
            digitalWrite(acidml, HIGH);
            Serial.println(rtime);
            Serial.println(mtime);
            if (currentMillis - previousMillis >= mtime) {
                previousMillis = millis();
                digitalWrite(red, LOW);
                digitalWrite(acidml, LOW);
                digitalWrite(green, HIGH);
            }
        } else {
            digitalWrite(red, LOW);
            digitalWrite(acidml, LOW);
        }
        if (ph_lvl == 0) {
            digitalWrite(green, HIGH);
            digitalWrite(blue, LOW);
            digitalWrite(red, LOW);
            digitalWrite(alkml, LOW);
            digitalWrite(acidml, LOW);
        } else {
            digitalWrite(green, LOW);
        }

        //this is old stuff, just for poc to get the hardware working
        if (number == 1) {
          digitalWrite(green, LOW);
          digitalWrite(blue, LOW);
          digitalWrite(red, LOW);
        }
        if (number == 7) {
          digitalWrite(green, HIGH);
          digitalWrite(alkml, LOW);
          digitalWrite(acidml, LOW);
        } else {
          digitalWrite(green, LOW);
        }
        if (number == 6) {
           digitalWrite(blue, HIGH);
           digitalWrite(alkml, HIGH);
          digitalWrite(acidml, LOW);
        } else {
          digitalWrite(blue, LOW);
        }
        if (number == 8) {
           digitalWrite(red, HIGH);
           digitalWrite(alkml, LOW);
           digitalWrite(acidml, HIGH);
        } else {
           digitalWrite(red, LOW);
        }
    }
}

基本上,raspi发送一个数字,如25,这意味着分配碱性5秒钟。这解析正确,但电机只是无限期地运行。 (有些代码已被注释掉,效果很好。)

如何使用if语句让电机在设定的时间内运行? (只是注意,如果if语句是一件坏事,并且有更好的方法来编写我想要做的事情,我很乐意重写代码。)

1 个答案:

答案 0 :(得分:0)

您有时间在错误的地方检查代码。仅当某些新数据到达时才会调用receiveData(),因此仅对条件if (currentMillis - previousMillis >= mtime)进行评估。将rtime / mtime分配给它,但将停止的电机移到loop()

另外,请查看此示例:https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay