计算我的智能房间中访客数量的问题
Problem with counting number of visitors in my smart room
我正在使用 Arduino、红外发射器和两个 SHARP 红外传感器在我的房间里建造一个访客柜台。
传感器计算我房间里的人数——一个人开灯,更多人什么都不做,零人关灯。
IR 发射器工作得很好(它会打开灯 on/off)以便检测,但我有一个问题和一个问题。
我的问题是,是否可以选择创建一个函数并调用它两次而不是在循环中重复自己?如果是这样,如何?它们大多是对称的,但仍然有一些差异,例如标志和 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. none 个检测到。
这是我的代码:
/*
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);
}
我首先用按钮和数字读数检查了代码,它工作得很好!但是,当我回到模拟读数时出现了一个问题:我在每个状态下向串行监视器打印一个字符串以查找问题并注意到它通过了所有状态但是当它到达最后一个状态并假设 increase\decrease num_people 并打印它也没有。相反,它会回到状态 0...
is there an option to make a function and call it twice instead of repeating myself inside the loop? if so, how? they are mostly symmetric, but still have some differences like the flags and num_people manipulating.
可以肯定的是,你的两个部分非常相似,改变 2 个 ifs 中表达式的顺序会更明显。
例如在第二部分你有
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) {
相当于重新排序后的:
if (sens_2_val < SENS_2_MIN && sens_1_val > SENS_1_MIN && sens_2_flag == 0 && sens_1_flag == 0) sens_1_flag = 1;
if (sens_2_val > SENS_2_MIN && sens_1_val < SENS_1_MIN && sens_2_flag == 0 && sens_1_flag == 1) {
因此,将 sens_1_val 与 sens_2_val 和 [= 交换时,正是第一部分中的两个测试105=]SENS_1_MIN与SENS_2_MIN,其余行相同
然后:
void f(int sens1, int sens1_min, int sens2,int sens2_min, int offset, int bling)
{
if (sens1 < sens1_min && sens2 > sens2_min && sens_1_flag == 0 && sens_2_flag == 0) sens_2_flag = 1;
if (sens1 > sens1_min && sens2 < sens2_min && sens_1_flag == 0 && sens_2_flag == 1) {
timeout = millis() + MAX_TIME;
while (sens2 > sens2_min && (millis() > timeout));
if ((num_people += offset) < 0)
num_people = 0;
Serial.print("People in the room: ");
Serial.println(num_people);
sens_1_flag = 0;
sens_2_flag = 0;
delay(DEBOUNCE_MS);
if (num_people == bling) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
}
}
您代码的第一部分由
完成
f(sens_1_val, SENS_1_MIN, sens_2_val, SENS_2_MIN, 1, 1);
sens_1_val = sens_2_val = 0;
第二个是
f(sens_2_val, SENS_2_MIN, sens_1_val, SENS_1_MIN, -1, 0);
sens_1_val = sens_2_val = 0;
我不想将函数中的 sens_x_val 重置为不必提供指针
其余的抱歉,我不明白你的问题,再解释一下
添加状态机后进行编辑
你的状态机很奇怪,我觉得你不需要那么多状态。机器定义取决于灯是否可以由and/or房间外的人手动off/on放置。
如果光仅由您的传感器发出命令,则超时,以防一段时间后没有人出门或进来:
我这里用的是UML表示法,在transition中一个'[]'表示一个guard/condition表示response else transition cannot be done,'/'后面的body在transition完成后执行。
为了处理多人同时出来但传感器只计数一个的情况,我使用了超时。
如果房间里面的人也可以指挥灯,有人进来就强制开灯,房间空了就强制关灯/ 超时后:
编辑,发现初始问题
在您的初始版本中,您的问题在于:
num_people = (num_people > 0) ? num_people-1 : 0;
...
if (num_people == 0) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
因为当你在if中做测试时你不知道你的灯是开还是关,你在第一行丢失了那个信息,你可以错误地决定改变它的状态。
编辑代码后进行编辑
对我来说你的新代码似乎没问题,无论如何你可以不用 prev_num_people.
你在每个in/out之后设置prev_num_people到num_people,所以在这种情况下"come in" :
num_people = num_people+1;
if (num_people == 1 && prev_num_people == 0) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
在增加 num_people 之前你有 prev_num_people == num_people 然后在有之后num_people == 1 意味着 prev_num_people == 0 测试它是没有用的。就这样
if (++num_people == 1) {
/* light is off, put it on */
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
如是"went out"不如做
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!");
}
随便做
if (--num_people == 0) {
/* light is on, put it off */
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
else if (num_people == -1) {
/* light is already off but in past several person
went out at the same time and only one was count */
num_people = 0;
}
所有这些都假设你正确地检测到有人进/出,我无法帮助你,我不知道你的传感器是如何工作的。
请注意,如果您想允许手动更改灯光,您需要记住灯光的状态,NumPerson 不再足以决定当前的状态光。
编辑您的新版本包含:
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!");
}
这是'disturbing'因为当你到达第二个if你才知道你来自哪里感谢prev_num_people(num_people失去了历史),你白做了很多测试
我强烈建议您使用我之前给您的简化版本,而不使用 prev_num_people。代码越简单,越易读,越健壮
编辑以添加模拟
如果我模拟你的传感器,你的代码被“#if 0”禁用:
#include <stdio.h>
int main()
{
int num_people = 0;
int real_people = 0;
int n;
while (scanf("%d", &n) == 1) {
real_people += n;
//Someone goes in
#if 0
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)
#else
if (n > 0)
#endif
{
if (++num_people == 1) {
/* light is off, put it on */
#if 0
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
#else
puts("put light on");
#endif
}
#if 0
sens_1_flag = 0;
sens_2_flag = 0;
Serial.print("People in the room: ");
Serial.println(num_people);
delay(DEBOUNCE_MS);
#else
printf("People supposed the room: %d (real %d)\n", num_people, real_people);
#endif
}
//Someone goes out
#if 0
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)
#else
if (n < 0)
#endif
{
if (--num_people == 0) {
/* light is on, put it off */
#if 0
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
#else
puts("put light off");
#endif
}
else if (num_people == -1) {
/* light is already off but in past several person
went out at the same time and only one was count */
num_people = 0;
}
#if 0
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);
#else
printf("People supposed the room: %d (real %d)\n", num_people, real_people);
#endif
}
}
return 0;
}
输入正数对应"come in"例,负数对应"want out"例。我还加了real_people对应房间真实人数
编译与执行:
pi@raspberrypi:/tmp $ gcc -Wall light.c
pi@raspberrypi:/tmp $ ./a.out
1
put light on
People supposed the room: 1 (real 1)
-1
put light off
People supposed the room: 0 (real 0)
1
put light on
People supposed the room: 1 (real 1)
1
People supposed the room: 2 (real 2)
-1
People supposed the room: 1 (real 1)
1
People supposed the room: 2 (real 2)
-1
People supposed the room: 1 (real 1)
-1
put light off
People supposed the room: 0 (real 0)
2
put light on
People supposed the room: 1 (real 2)
-1
put light off
People supposed the room: 0 (real 1)
-1
People supposed the room: 0 (real 0)
1
put light on
People supposed the room: 1 (real 1)
1
People supposed the room: 2 (real 2)
-2
People supposed the room: 1 (real 0)
^C
pi@raspberrypi:/tmp $
在没有进/出超时的情况下,灯不能从最后熄灭,除非同时有 2 人进来然后 1 人出去然后又 1 人出去
无论如何你看到算法没问题,所以如果你有问题这是在传感器管理中(代码被#if 0#禁用)
如果我是对的,那么你的三元运算符语法是错误的,应该是这样的:
(condition) ? (if_true) : (if_false)
所以应该是这样的:
num_people > 0 ? num_people-- : num_people = 0;
等同于:
if (num_people > 0)
{
num_people--;
}
else
{
num_people = 0;
}
如果你想使用一个函数,为什么不这样呢?
void MyFuntion(uint16_t& SensVal, uint8_t const MinSensVal, uint8_t& NumPeople)
{
timeout = millis() + MAX_TIME;
while (SensVal > MinSensVal && (millis() > timeout));
NumPeople++;
Serial.print("People in the room: ");
Serial.println(num_people);
}
您不必将所有内容都放入函数中,只需要具有相同结构的代码即可。
警告: 这并不是对您问题中单行的回答,而是 simplification/cleanup 您的代码 [沿着您的行建议评论。
我很难理解你的逻辑[所有的复制],所以我把它简化为第一步。当我这样做的时候,其他人已经回复了,所以如果你愿意,你可以合并他们的答案。
我创建了一个 struct
来完全描述每个设备和一些作用于该结构中的值的函数,而不是硬连接所有内容。
无论如何,这是代码。我努力 不 破坏您现有的逻辑,但您可能需要检查一下。希望这种简化能让您更容易地看到真正的问题:
/*
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;
typedef struct {
int sens_id;
int sens_pin;
int sens_min;
int sens_flag;
uint16_t sens_val;
} sens_t;
sens_t sensall[2];
#define s1 (&sensall[0])
#define s2 (&sensall[1])
uint8_t num_people = 0;
uint32_t timeout;
void
sensinit(sens_t *sens,int id,int pin,int min)
{
sens->sens_id = id;
sens->sens_pin = pin;
sens->sens_min = min;
sens->sens_flag = 0;
pinMode(sens->sens_pin,INPUT);
}
void
sensread(sens_t *sens)
{
sens->sens_val = analogRead(sens->sens_pin);
}
void
setup()
{
Serial.begin(115200);
sensinit(s1,1,SENS_1_PIN,SENS_1_MIN);
sensinit(s2,2,SENS_2_PIN,s2->sens_min);
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"));
}
int
sensif(int lt_gt,int v1,int v2)
{
int cond1;
int cond2;
int match;
if (lt_gt) {
cond1 = (s1->sens_val < s1->sens_min);
cond2 = (s2->sens_val > s2->sens_min);
}
else {
cond1 = (s1->sens_val > s1->sens_min);
cond2 = (s2->sens_val < s2->sens_min);
}
match = (cond1 && cond2 && (s1->sens_flag == v1) && (s2->sens_flag == v2));
return match;
}
void
senswait(sens_t *sens,int newval)
{
timeout = millis() + MAX_TIME;
// TODO: add timeout to while loop. Otherwise, the program will stuck
// because of a sensor reading.
while ((sens->sens_val > sens->sens_min) && (millis() > timeout));
#if 0
switch (sens->sens_id) {
case 1:
num_people = (num_people > 0) ? num_people - 1 : 0;
break;
case 2:
num_people = num_people + 1;
break;
}
#else
num_people = newval;
#endif
Serial.print("People in the room: ");
Serial.println(num_people);
// FIXME -- why clear both instead of just one (e.g. sens->sens_flag)???
s1->sens_flag = 0;
s2->sens_flag = 0;
delay(DEBOUNCE_MS);
}
void
loop(void)
{
sensread(s1);
sensread(s2);
#if 0
Serial.print("LDR 1: ");
Serial.print(s1->s1_val);
Serial.print("\t LDR 2: ");
Serial.println(s2->sens_val);
delay(200);
#endif
// Someone goes in
if (sensif(1,0,0))
s2->sens_flag = 1;
if (sensif(0,0,1)) {
senswait(s2,num_people + 1);
if (num_people == 1) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
}
// Someone goes out
if (sensif(0,0,0))
s1->sens_flag = 1;
if (sensif(1,1,0)) {
senswait(s1,(num_people > 0) ? num_people - 1 : 0);
if (num_people == 0) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
}
}
我的问题是,是否可以选择创建一个函数并调用它两次而不是在循环中重复自己?如果是这样,如何?它们大多是对称的,但仍然有一些差异,例如标志和 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. none 个检测到。
这是我的代码:
/*
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);
}
我首先用按钮和数字读数检查了代码,它工作得很好!但是,当我回到模拟读数时出现了一个问题:我在每个状态下向串行监视器打印一个字符串以查找问题并注意到它通过了所有状态但是当它到达最后一个状态并假设 increase\decrease num_people 并打印它也没有。相反,它会回到状态 0...
is there an option to make a function and call it twice instead of repeating myself inside the loop? if so, how? they are mostly symmetric, but still have some differences like the flags and num_people manipulating.
可以肯定的是,你的两个部分非常相似,改变 2 个 ifs 中表达式的顺序会更明显。
例如在第二部分你有
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) {
相当于重新排序后的:
if (sens_2_val < SENS_2_MIN && sens_1_val > SENS_1_MIN && sens_2_flag == 0 && sens_1_flag == 0) sens_1_flag = 1;
if (sens_2_val > SENS_2_MIN && sens_1_val < SENS_1_MIN && sens_2_flag == 0 && sens_1_flag == 1) {
因此,将 sens_1_val 与 sens_2_val 和 [= 交换时,正是第一部分中的两个测试105=]SENS_1_MIN与SENS_2_MIN,其余行相同
然后:
void f(int sens1, int sens1_min, int sens2,int sens2_min, int offset, int bling)
{
if (sens1 < sens1_min && sens2 > sens2_min && sens_1_flag == 0 && sens_2_flag == 0) sens_2_flag = 1;
if (sens1 > sens1_min && sens2 < sens2_min && sens_1_flag == 0 && sens_2_flag == 1) {
timeout = millis() + MAX_TIME;
while (sens2 > sens2_min && (millis() > timeout));
if ((num_people += offset) < 0)
num_people = 0;
Serial.print("People in the room: ");
Serial.println(num_people);
sens_1_flag = 0;
sens_2_flag = 0;
delay(DEBOUNCE_MS);
if (num_people == bling) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
}
}
您代码的第一部分由
完成 f(sens_1_val, SENS_1_MIN, sens_2_val, SENS_2_MIN, 1, 1);
sens_1_val = sens_2_val = 0;
第二个是
f(sens_2_val, SENS_2_MIN, sens_1_val, SENS_1_MIN, -1, 0);
sens_1_val = sens_2_val = 0;
我不想将函数中的 sens_x_val 重置为不必提供指针
其余的抱歉,我不明白你的问题,再解释一下
添加状态机后进行编辑
你的状态机很奇怪,我觉得你不需要那么多状态。机器定义取决于灯是否可以由and/or房间外的人手动off/on放置。
如果光仅由您的传感器发出命令,则超时,以防一段时间后没有人出门或进来:
我这里用的是UML表示法,在transition中一个'[]'表示一个guard/condition表示response else transition cannot be done,'/'后面的body在transition完成后执行。
为了处理多人同时出来但传感器只计数一个的情况,我使用了超时。
如果房间里面的人也可以指挥灯,有人进来就强制开灯,房间空了就强制关灯/ 超时后:
编辑,发现初始问题
在您的初始版本中,您的问题在于:
num_people = (num_people > 0) ? num_people-1 : 0; ... if (num_people == 0) { irsend.sendSony(IR_KEY, 20); Serial.println("BLING!"); }
因为当你在if中做测试时你不知道你的灯是开还是关,你在第一行丢失了那个信息,你可以错误地决定改变它的状态。
编辑代码后进行编辑
对我来说你的新代码似乎没问题,无论如何你可以不用 prev_num_people.
你在每个in/out之后设置prev_num_people到num_people,所以在这种情况下"come in" :
num_people = num_people+1; if (num_people == 1 && prev_num_people == 0) { irsend.sendSony(IR_KEY, 20); Serial.println("BLING!"); }
在增加 num_people 之前你有 prev_num_people == num_people 然后在有之后num_people == 1 意味着 prev_num_people == 0 测试它是没有用的。就这样
if (++num_people == 1) {
/* light is off, put it on */
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
如是"went out"不如做
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!"); }
随便做
if (--num_people == 0) {
/* light is on, put it off */
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
else if (num_people == -1) {
/* light is already off but in past several person
went out at the same time and only one was count */
num_people = 0;
}
所有这些都假设你正确地检测到有人进/出,我无法帮助你,我不知道你的传感器是如何工作的。
请注意,如果您想允许手动更改灯光,您需要记住灯光的状态,NumPerson 不再足以决定当前的状态光。
编辑您的新版本包含:
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!"); }
这是'disturbing'因为当你到达第二个if你才知道你来自哪里感谢prev_num_people(num_people失去了历史),你白做了很多测试
我强烈建议您使用我之前给您的简化版本,而不使用 prev_num_people。代码越简单,越易读,越健壮
编辑以添加模拟
如果我模拟你的传感器,你的代码被“#if 0”禁用:
#include <stdio.h>
int main()
{
int num_people = 0;
int real_people = 0;
int n;
while (scanf("%d", &n) == 1) {
real_people += n;
//Someone goes in
#if 0
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)
#else
if (n > 0)
#endif
{
if (++num_people == 1) {
/* light is off, put it on */
#if 0
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
#else
puts("put light on");
#endif
}
#if 0
sens_1_flag = 0;
sens_2_flag = 0;
Serial.print("People in the room: ");
Serial.println(num_people);
delay(DEBOUNCE_MS);
#else
printf("People supposed the room: %d (real %d)\n", num_people, real_people);
#endif
}
//Someone goes out
#if 0
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)
#else
if (n < 0)
#endif
{
if (--num_people == 0) {
/* light is on, put it off */
#if 0
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
#else
puts("put light off");
#endif
}
else if (num_people == -1) {
/* light is already off but in past several person
went out at the same time and only one was count */
num_people = 0;
}
#if 0
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);
#else
printf("People supposed the room: %d (real %d)\n", num_people, real_people);
#endif
}
}
return 0;
}
输入正数对应"come in"例,负数对应"want out"例。我还加了real_people对应房间真实人数
编译与执行:
pi@raspberrypi:/tmp $ gcc -Wall light.c
pi@raspberrypi:/tmp $ ./a.out
1
put light on
People supposed the room: 1 (real 1)
-1
put light off
People supposed the room: 0 (real 0)
1
put light on
People supposed the room: 1 (real 1)
1
People supposed the room: 2 (real 2)
-1
People supposed the room: 1 (real 1)
1
People supposed the room: 2 (real 2)
-1
People supposed the room: 1 (real 1)
-1
put light off
People supposed the room: 0 (real 0)
2
put light on
People supposed the room: 1 (real 2)
-1
put light off
People supposed the room: 0 (real 1)
-1
People supposed the room: 0 (real 0)
1
put light on
People supposed the room: 1 (real 1)
1
People supposed the room: 2 (real 2)
-2
People supposed the room: 1 (real 0)
^C
pi@raspberrypi:/tmp $
在没有进/出超时的情况下,灯不能从最后熄灭,除非同时有 2 人进来然后 1 人出去然后又 1 人出去
无论如何你看到算法没问题,所以如果你有问题这是在传感器管理中(代码被#if 0#禁用)
如果我是对的,那么你的三元运算符语法是错误的,应该是这样的:
(condition) ? (if_true) : (if_false)
所以应该是这样的:
num_people > 0 ? num_people-- : num_people = 0;
等同于:
if (num_people > 0)
{
num_people--;
}
else
{
num_people = 0;
}
如果你想使用一个函数,为什么不这样呢?
void MyFuntion(uint16_t& SensVal, uint8_t const MinSensVal, uint8_t& NumPeople)
{
timeout = millis() + MAX_TIME;
while (SensVal > MinSensVal && (millis() > timeout));
NumPeople++;
Serial.print("People in the room: ");
Serial.println(num_people);
}
您不必将所有内容都放入函数中,只需要具有相同结构的代码即可。
警告: 这并不是对您问题中单行的回答,而是 simplification/cleanup 您的代码 [沿着您的行建议评论。
我很难理解你的逻辑[所有的复制],所以我把它简化为第一步。当我这样做的时候,其他人已经回复了,所以如果你愿意,你可以合并他们的答案。
我创建了一个 struct
来完全描述每个设备和一些作用于该结构中的值的函数,而不是硬连接所有内容。
无论如何,这是代码。我努力 不 破坏您现有的逻辑,但您可能需要检查一下。希望这种简化能让您更容易地看到真正的问题:
/*
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;
typedef struct {
int sens_id;
int sens_pin;
int sens_min;
int sens_flag;
uint16_t sens_val;
} sens_t;
sens_t sensall[2];
#define s1 (&sensall[0])
#define s2 (&sensall[1])
uint8_t num_people = 0;
uint32_t timeout;
void
sensinit(sens_t *sens,int id,int pin,int min)
{
sens->sens_id = id;
sens->sens_pin = pin;
sens->sens_min = min;
sens->sens_flag = 0;
pinMode(sens->sens_pin,INPUT);
}
void
sensread(sens_t *sens)
{
sens->sens_val = analogRead(sens->sens_pin);
}
void
setup()
{
Serial.begin(115200);
sensinit(s1,1,SENS_1_PIN,SENS_1_MIN);
sensinit(s2,2,SENS_2_PIN,s2->sens_min);
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"));
}
int
sensif(int lt_gt,int v1,int v2)
{
int cond1;
int cond2;
int match;
if (lt_gt) {
cond1 = (s1->sens_val < s1->sens_min);
cond2 = (s2->sens_val > s2->sens_min);
}
else {
cond1 = (s1->sens_val > s1->sens_min);
cond2 = (s2->sens_val < s2->sens_min);
}
match = (cond1 && cond2 && (s1->sens_flag == v1) && (s2->sens_flag == v2));
return match;
}
void
senswait(sens_t *sens,int newval)
{
timeout = millis() + MAX_TIME;
// TODO: add timeout to while loop. Otherwise, the program will stuck
// because of a sensor reading.
while ((sens->sens_val > sens->sens_min) && (millis() > timeout));
#if 0
switch (sens->sens_id) {
case 1:
num_people = (num_people > 0) ? num_people - 1 : 0;
break;
case 2:
num_people = num_people + 1;
break;
}
#else
num_people = newval;
#endif
Serial.print("People in the room: ");
Serial.println(num_people);
// FIXME -- why clear both instead of just one (e.g. sens->sens_flag)???
s1->sens_flag = 0;
s2->sens_flag = 0;
delay(DEBOUNCE_MS);
}
void
loop(void)
{
sensread(s1);
sensread(s2);
#if 0
Serial.print("LDR 1: ");
Serial.print(s1->s1_val);
Serial.print("\t LDR 2: ");
Serial.println(s2->sens_val);
delay(200);
#endif
// Someone goes in
if (sensif(1,0,0))
s2->sens_flag = 1;
if (sensif(0,0,1)) {
senswait(s2,num_people + 1);
if (num_people == 1) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
}
// Someone goes out
if (sensif(0,0,0))
s1->sens_flag = 1;
if (sensif(1,1,0)) {
senswait(s1,(num_people > 0) ? num_people - 1 : 0);
if (num_people == 0) {
irsend.sendSony(IR_KEY, 20);
Serial.println("BLING!");
}
}
}