【发布时间】:2020-07-31 06:56:32
【问题描述】:
我正在使用 Arduino、IR 发射器和两个 SHARP IR 传感器在我的房间里建造一个访客柜台。 传感器计算我房间里的人数——一个人开灯,更多人什么都不做,零人关灯。 红外发射器工作得很好(它可以打开/关闭灯),所以作为检测,但我有一个问题和一个问题。
我的问题是,是否可以选择创建一个函数并调用它两次,而不是在循环中重复自己?如果是这样,如何?它们大多是对称的,但仍然存在一些差异,例如 flags 和 num_people 操作。
我现在的主要问题是计算 num_people,我发现这行是问题所在:num_people = (num_people > 0) ? num_people-1 : 0;
当我将这一行放在评论中时,我可以计算多个人,但是当我不是时,它会运行代码并计算 1,0,1,0,1,0(仅在进入房间时)。需要说的是,当我出去时,它应该减少 num_people,当它为零时,保持这个数字。
代码在这里:
/*
Smart Light V1.0 Software
==========================
Copyright (C) 2020 Yuval Kedar - KD Tech
The program counts visitors in my room and controls the light using SHARP IR sensors
Board: Arduino Pro Mini
*/
#include "Arduino.h"
#include <IRremote.h>
// TODO: try a dedicated library for the sensors. Raw readings aren't the best way to do that - need to overcome oversampling, debouncing, hysteresis, etc.
#define IR_TRANSMITTER_PIN (3)
#define SENS_1_PIN (A1)
#define SENS_2_PIN (A0)
#define SENS_1_MIN (160)
#define SENS_2_MIN (160)
#define MAX_TIME (1000)
#define IR_KEY (0x68B92)
#define DEBOUNCE_MS (300)
IRsend irsend;
uint8_t num_people = 0;
uint8_t prev_num_people = 0;
bool sens_1_flag = 0;
bool sens_2_flag = 0;
uint32_t timeout;
void setup() {
Serial.begin(115200);
pinMode(SENS_1_PIN, INPUT);
pinMode(SENS_2_PIN, INPUT);
pinMode(IR_TRANSMITTER_PIN, OUTPUT);
Serial.println(F(
"_______________________________\n"
"\n"
" S M A R T R O O M \n"
"_______________________________\n"
"\n"
" Made by KD Technology \n"
"\n"));
}
void loop() {
uint16_t sens_1_val = analogRead(SENS_1_PIN);
uint16_t sens_2_val = analogRead(SENS_2_PIN);
/*
Serial.print("LDR 1: ");
Serial.print(sens_1_val);
Serial.print("\t LDR 2: ");
Serial.println(sens_2_val);
delay(200);
*/
//TODO: there is a duplication here. Create a function and call it twice inside the loop.
//Someone goes in
if (sens_1_val < SENS_1_MIN && sens_2_val > SENS_2_MIN && sens_1_flag == 0 && sens_2_flag == 0) sens_2_flag = 1;
if (sens_1_val > SENS_1_MIN && sens_2_val < SENS_2_MIN && sens_1_flag == 0 && sens_2_flag == 1) {
// TODO: add timeout to while loop. Otherwise, the program will stuck because of a sensor reading.
// timeout = millis() + MAX_TIME;
// while (sens_2_val > SENS_2_MIN && (millis() > timeout));
num_people = num_people+1;
if (num_people == 1 && prev_num_people == 0) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
sens_1_flag = 0;
sens_2_flag = 0;
prev_num_people = num_people;
Serial.print("People in the room: ");
Serial.println(num_people);
delay(DEBOUNCE_MS);
}
//Someone goes out
if (sens_1_val > SENS_1_MIN && sens_2_val < SENS_2_MIN && sens_1_flag == 0 && sens_2_flag == 0) sens_1_flag = 1;
if (sens_1_val < SENS_1_MIN && sens_2_val > SENS_2_MIN && sens_1_flag == 1 && sens_2_flag == 0) {
timeout = millis() + MAX_TIME;
while (sens_1_val > SENS_1_MIN && (millis() > timeout));
num_people = (num_people > 0) ? num_people-1 : 0;
if (num_people == 0 && prev_num_people != 0) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
sens_1_flag = 0;
sens_2_flag = 0;
prev_num_people = num_people;
Serial.print("People in the room: ");
Serial.println(num_people);
delay(DEBOUNCE_MS);
}
}
编辑:
/*
Smart Light V1.0 Software
==========================
Copyright (C) 2020 Yuval Kedar - KD Tech
The program counts visitors in my room and controls the light using SHARP IR sensors
Board: Arduino Pro Mini
*/
#include "Arduino.h"
#include <IRremote.h>
// TODO: try a dedicated library for the sensors. Raw readings aren't the best way to do that - need to overcome oversampling, debouncing, hysteresis, etc.
#define IR_TRANSMITTER_PIN (3)
#define SENS_1_PIN (A1)
#define SENS_2_PIN (A0)
#define SENS_1_MIN (160)
#define SENS_2_MIN (160)
#define MAX_TIME (1000)
#define IR_KEY (0x68B92)
#define DEBOUNCE_MS (300)
IRsend irsend;
uint8_t num_people = 0;
uint8_t prev_num_people = 0;
bool sens_1_flag = 0;
bool sens_2_flag = 0;
uint32_t timeout;
void setup() {
Serial.begin(115200);
pinMode(SENS_1_PIN, INPUT);
pinMode(SENS_2_PIN, INPUT);
pinMode(IR_TRANSMITTER_PIN, OUTPUT);
Serial.println(F(
"_______________________________\n"
"\n"
" S M A R T R O O M \n"
"_______________________________\n"
"\n"
" Made by KD Technology \n"
"\n"));
}
void loop() {
uint16_t sens_1_val = analogRead(SENS_1_PIN);
uint16_t sens_2_val = analogRead(SENS_2_PIN);
/*
Serial.print("LDR 1: ");
Serial.print(sens_1_val);
Serial.print("\t LDR 2: ");
Serial.println(sens_2_val);
delay(200);
*/
//TODO: there is a duplication here. Create a function and call it twice inside the loop.
//Someone goes in
if (sens_1_val < SENS_1_MIN && sens_2_val > SENS_2_MIN && sens_1_flag == 0 && sens_2_flag == 0) sens_2_flag = 1;
if (sens_1_val > SENS_1_MIN && sens_2_val < SENS_2_MIN && sens_1_flag == 0 && sens_2_flag == 1) {
// TODO: add timeout to while loop. Otherwise, the program will stuck because of a sensor reading.
// timeout = millis() + MAX_TIME;
// while (sens_2_val > SENS_2_MIN && (millis() > timeout));
num_people += 1;
if (num_people == 1 && prev_num_people == 0) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
sens_1_flag = 0;
sens_2_flag = 0;
prev_num_people = num_people;
Serial.print("People in the room: ");
Serial.println(num_people);
delay(DEBOUNCE_MS);
}
//Someone goes out
if (sens_1_val > SENS_1_MIN && sens_2_val < SENS_2_MIN && sens_1_flag == 0 && sens_2_flag == 0) sens_1_flag = 1;
if (sens_1_val < SENS_1_MIN && sens_2_val > SENS_2_MIN && sens_1_flag == 1 && sens_2_flag == 0) {
// timeout = millis() + MAX_TIME;
// while (sens_1_val > SENS_1_MIN && (millis() > timeout));
// num_people = (num_people > 0) ? num_people-1 : 0;
if (num_people > 1) num_people -= 1;
if (num_people == 1 && prev_num_people != 0) {
num_people -= 1;
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
sens_1_flag = 0;
sens_2_flag = 0;
prev_num_people = num_people;
Serial.print("People in the room: ");
Serial.println(num_people);
delay(DEBOUNCE_MS);
}
}
不同的方法:
我弄清楚了新机器的状态。我需要通过 4 个状态: 1. sens_1 检测到而 sens_2 没有 2. 两个传感器都检测到 3. sens_2 检测到而 sens_1 没有 4. 他们都没有发现。
这是我的代码:
/*
Smart Light V1.0 Software
==========================
Copyright (C) 2020 Yuval Kedar - KD Tech
The program counts visitors in my room and controls the light using SHARP IR sensors
Board: Arduino Pro Mini
*/
#include "Arduino.h"
#include <IRremote.h>
// TODO: try a dedicated library for the sensors. Raw readings aren't the best way to do that - need to overcome oversampling, debouncing, hysteresis, etc.
#define IR_TRANSMITTER_PIN (3)
#define SENS_1_PIN (A0)
#define SENS_2_PIN (A1)
#define SENS_1_MIN (115)
#define SENS_2_MIN (115)
#define IR_KEY (0x68B92)
#define DEBOUNCE_MS (2000)
IRsend irsend;
int8_t num_people = 0;
uint8_t state = 0;
void setup() {
Serial.begin(115200);
pinMode(SENS_1_PIN, INPUT);
pinMode(SENS_2_PIN, INPUT);
pinMode(IR_TRANSMITTER_PIN, OUTPUT);
Serial.println(F(
"_______________________________\n"
"\n"
" S M A R T R O O M \n"
"_______________________________\n"
"\n"
" Made by KD Technology \n"
"\n"));
}
void loop() {
uint16_t sens_1_val = analogRead(SENS_1_PIN);
uint16_t sens_2_val = analogRead(SENS_2_PIN);
switch (state) {
case 0:
if ((sens_1_val > SENS_1_MIN) && (sens_2_val < SENS_2_MIN)) {
// if (!sens_1_val && sens_2_val) {
state = 4;
Serial.println("0 to 4");
}
if ((sens_2_val > SENS_2_MIN) && (sens_1_val < SENS_1_MIN)) {
// if (!sens_2_val && sens_1_val) {
state = 1;
Serial.println("0 to 1");
}
break;
case 1:
if ((sens_1_val > SENS_1_MIN) && (sens_2_val > SENS_2_MIN)) {
// if (!sens_1_val && !sens_2_val) {
state = 2;
Serial.println("1 to 2");
} else state = 0;
break;
case 2:
if ((sens_1_val > SENS_1_MIN) && (sens_2_val < SENS_2_MIN)) {
// if (!sens_1_val && sens_2_val) {
state = 3;
Serial.println("2 to 3");
} else state = 1;
break;
case 3:
if ((sens_1_val < SENS_1_MIN) && (sens_2_val < SENS_2_MIN)) { //someone went out
// if (sens_1_val && sens_2_val) { //someone went out
num_people -= 1;
if (num_people == 0) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
else if (num_people == -1) num_people = 0;
Serial.print("People in the room: ");
Serial.println(num_people);
// delay(DEBOUNCE_MS);
state = 0;
} else state = 2;
break;
case 4:
if ((sens_1_val > SENS_1_MIN) && (sens_2_val > SENS_2_MIN)) {
// if (!sens_1_val && !sens_2_val) {
state = 5;
Serial.println("4 to 5");
} else state = 0;
break;
case 5:
if ((sens_2_val > SENS_2_MIN) && (sens_1_val < SENS_1_MIN)) {
// if (!sens_2_val && sens_1_val) {
state = 6;
Serial.println("5 to 6");
} else state = 4;
break;
case 6:
if ((sens_1_val < SENS_1_MIN) && (sens_2_val < SENS_2_MIN)) { //someone came in
// if (sens_1_val && sens_2_val) { //someone came in
num_people += 1;
if (num_people == 1) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
Serial.print("People in the room: ");
Serial.println(num_people);
// delay(DEBOUNCE_MS);
state = 0;
} else state = 5;
break;
}
// Serial.print("LDR 1: ");
// Serial.print(sens_1_val);
// Serial.print("\t LDR 2: ");
// Serial.println(sens_2_val);
// delay(DEBOUNCE_MS);
}
我首先用按钮和数字读数检查了代码,它运行良好!但是,当我回到模拟读数时,出现了一个问题:我在每个状态下向串行监视器打印了一个字符串以查找问题并注意到它通过了所有状态,但是当它达到最后一个状态并假设增加\减少 num_people 并打印它,它不会。相反,它会回到状态 0...
【问题讨论】:
-
通常不赞成帖子中的图片,但在这种情况下,它将有助于说明您的代码。并确定您的逻辑是否需要调整。请编辑您的帖子,并附上一张简单的图表/图片,显示(和标记)您的传感器相对于门的布局。包括门的位置,帖子中提到的传感器相对于门的位置。
-
选择 C 或 C++。不必要的双重标记会招来反对票。
-
@ryyker 拼写是结 mi strong sute。评论已修改。
-
我将两个传感器水平(一个并排)安装在门柱的一侧——这样我就可以知道是否有人进出房间(哪个传感器先检测到)跨度>
-
您的状态机很“奇怪”(我的意思是我认为无效)。我不确定是否理解红色过渡,房间里有人可以手动关灯吗?如果是,则必须也可以穿上 if。如果是的话,要确保开/关命令仅在房间内 inside 吗?
标签: c++ arduino sensors infrared