我有一个连接到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语句是一件坏事,并且有更好的方法来编写我想要做的事情,我很乐意重写代码。)
答案 0 :(得分:0)
您有时间在错误的地方检查代码。仅当某些新数据到达时才会调用receiveData()
,因此仅对条件if (currentMillis - previousMillis >= mtime)
进行评估。将rtime / mtime分配给它,但将停止的电机移到loop()
另外,请查看此示例:https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay