我正在做一个关于控制两个传感器(超声波和红外)的项目,并使用 Arduino 管理它们。 IR接收器内部有一个滤波器系统,因此它以 36 kHz 的频率接收。我使用模块 srf04 来处理超声波。如果我编写的程序只需要控制一个传感器,它就可以工作。但我必须将这两个信号插入一个结果。所以我使用了原型(prototype)线程!但它不起作用...错误是什么?
这是代码:
#include <pt.h>
int iro = 8, iri = 4, us = 12, distanza, us_vcc = 13, ir_vcc = 7;
long durata;
static struct pt pt1, pt2, pt3;
static int irthread(struct pt *pt) {
PT_BEGIN(pt);
while(1) {
PT_WAIT_UNTIL(pt, 1>0);
digitalWrite(iro, HIGH);
delayMicroseconds(9);
digitalWrite(iro, LOW);
delayMicroseconds(9);
}
PT_END(pt);
}
static int usthread(struct pt *pt) {
static unsigned long timer = 0;
PT_BEGIN(pt);
while(1) {
PT_WAIT_UNTIL(pt, millis() - timer > 200);
timer = millis();
pinMode(us, OUTPUT);
digitalWrite(us, LOW);
delayMicroseconds(5);
digitalWrite(us, HIGH);
delayMicroseconds(10);
digitalWrite(us, LOW);
pinMode(us, INPUT);
durata = pulseIn(us, HIGH);
distanza = durata/58;
}
PT_END(pt);
}
static int leggithread(struct pt *pt) {
static unsigned long timer = 0;
PT_BEGIN(pt);
while(1) {
PT_WAIT_UNTIL(pt, millis() - timer > 200);
timer = millis();
Serial.print(distanza);
Serial.print("cm ");
if (digitalRead(iri) == LOW)
Serial.println("ir si");
else
Serial.println("ir no");
}
PT_END(pt);
}
void setup() {
pinMode(iro, OUTPUT);
pinMode(iri, INPUT);
pinMode(us_vcc, OUTPUT);
digitalWrite(us_vcc, HIGH);
pinMode(ir_vcc, OUTPUT);
digitalWrite(ir_vcc, HIGH);
Serial.begin(9600);
PT_INIT(&pt1);
PT_INIT(&pt2);
PT_INIT(&pt3);
}
void loop() {
irthread(&pt1);
usthread(&pt2);
leggithread(&pt3);
}
每个线程的单个代码部分都可以工作。
<小时/>更新
我解决了我的问题(消除了irthread()
),代码现在是这样的:
#include <pt.h>
int iro = 8, iri = 4, us = 12, distanza, us_vcc = 13, ir_vcc = 7;
long durata;
static struct pt pt1, pt2;
static int usthread(struct pt *pt) {
static unsigned long timer = 0;
PT_BEGIN(pt);
while(1) {
PT_WAIT_UNTIL(pt, millis() - timer > 200);
timer = millis();
pinMode(us, OUTPUT);
digitalWrite(us, LOW);
delayMicroseconds(5);
digitalWrite(us, HIGH);
delayMicroseconds(10);
digitalWrite(us, LOW);
pinMode(us, INPUT);
durata = pulseIn(us, HIGH);
}
PT_END(pt);
}
static int leggithread(struct pt *pt) {
static unsigned long timer = 0;
PT_BEGIN(pt);
while(1) {
PT_WAIT_UNTIL(pt, millis() - timer > 200);
timer = millis();
distanza = durata/58;
Serial.print(distanza);
Serial.print("cm ");
if(digitalRead(iri) == LOW)
Serial.println("ir si");
else
Serial.println("ir no");
}
PT_END(pt);
}
void setup() {
pinMode(iro, OUTPUT);
tone(iro, 36000);
pinMode(iri, INPUT);
pinMode(us_vcc, OUTPUT);
digitalWrite(us_vcc, HIGH);
pinMode(ir_vcc, OUTPUT);
digitalWrite(ir_vcc, HIGH);
Serial.begin(9600);
PT_INIT(&pt1);
PT_INIT(&pt2);
}
void loop() {
usthread(&pt1);
leggithread(&pt2);
}
现在的问题是超声波传感器。如果我在没有原型(prototype)线程的单个程序中控制它,它可以到达 3 米距离的物体。现在,即使我把东西放在 1 米处,“距离”最大也为 15 厘米。错误是什么?
最佳答案
在irthread()
中,宏PT_WAIT_UNTIL
的第二个参数始终计算为true:
PT_WAIT_UNTIL(pt, 1>0);
因此程序将陷入 irthread() 的无限循环中,因为在这种情况下宏 PT_WAIT_UNTIL 的部分结果类似于 if(!(1>0)) return 0;
;语句 return 0
永远不会被调用。
它适用于 usthread()
和 leggithread()
,因为第二个参数在前 200 毫秒内为 false 并且变量被设置为在单次为 true 后的 200 毫秒内再次为 false。
一些背景信息位于 How protothreads really work 。
关于pthreads - Arduino 原型(prototype)线程的一些问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6230878/