我有一个无限的for循环,它包含一个连续接收来自LDR的读数的函数。代码是这样的:
.
light_1=sample(1);
.
.
for(::){
light_2=sample(2);
if((light_2 > (light_1))
alarm=1;
delay(1); // wait for 1 second
.
.
.
}etc
light_2是现在被采样的光,并与第一个采样光light_1。
进行比较我想要做的是创建一个计数器,如果light_2大于light_1 3次,则打破循环。但不仅如此,一盏灯将以1秒的间隔闪烁3次。如果光线在4秒内闪烁3次,我希望循环中断。
如果这没有意义,请告诉我,以便我能更好地解释它。
编辑3
我希望它继续正常的采样时间,只有在获得3个读数实例时才会中断循环。但是我还是觉得我应该用一个计时器?请帮忙。
额外信息:我在这里回复了其中一位回答者,也许其他人可以从这个额外的解释中受益:
有两个阶段:
我应该避免使用这么多延迟让第2阶段工作,因为这会影响第1阶段的阅读控制和速度。
如果您需要更多解释,请与我们联系!
答案 0 :(得分:3)
使用某种结构将各种参数组合在一起。这通常被称为“州”。
struct state {
int light_2_greater_than_1;
int other_things;
};
然后更新该对象,并检查其成员。
答案 1 :(得分:3)
这是一个非常简单的例子,说明使用SIGALRM来保持时间独立于你的sample()函数,这是因为sample()需要一些时间才能完成,你现在可以在之前做到这一点=时间(NULL)睡眠/延迟
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <unistd.h>
time_t now;
void alarm_handler(int sig);
struct flash {
time_t first_stamp;
int count;
};
int main(int ac, char *av[]) {
signal(SIGALRM, alarm_handler);
now = time(NULL);
struct flash f = {0,0};
int light = 0;
alarm(1);
for (;;) {
// light = sample..
if (light) {
if (f.count) {
if (f.count > 3 && (now - f.first_stamp) > 4) {
// do_whatever_function or break;
f.count = 0;
f.first_stamp = 0;
} else {
f.count++;
}
} else {
f.first_stamp = now;
f.count = 1;
}
}
sleep(1);
}
return 0;
}
void alarm_handler(int sig) {
now = time(NULL);
alarm(1);
}
编辑: 实际上现在我读它time()不是信号安全,给我一个修改代码的时间
第二次编辑: http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04 实际上它是信号安全的:)
下表定义了一组函数,这些函数应该是信号的可重入或不可中断的,并且应该是异步信号安全的。因此,应用程序可以无限制地调用信号捕获功能: ...时间()
答案 2 :(得分:1)
计数器可以简单如下:
int count = 0;
...
if (condition)
{
count++;
}
现在,要将其合并到循环中,您可能会执行以下操作:
int count = 0;
while (count < THRESHOLD)
{
...
}
答案 3 :(得分:1)
你想要在两次闪光之间检测到3个闪烁的闪烁,恰好是1秒? 所以3秒闪烁2秒(不是4)...? (flash1是开始,1秒后flash2,2秒后flash2。所以3秒闪烁2次。)
这是一个没有计时器的简单代码,没有执行此检测的数组:
light_1=sample(1);
for(::){
// the while loop waits for the first flash, ie : wait for sample(2) > light_1
while(sample(2) <= (light_1))
{
// if you know that a flash lasts n ms, you can add "sleep(n);" in this loop, so you will use less cpu.
}
// now the first flash is emitted, we will wait for 1 second before looking for the second flash
delay(1);
if(sample(3) <= light_1)
continue;
// if after 1 second, there is no flash, ther will not be 3 flashes in 2 seconds.
// so we restart from the first flash (the "continue;" instruction do that)
delay(1); // the second flash was catched, then we wait for 1 second before looking for the third flash.
if(sample(4) <= light_1)
continue;
//so if sample(4 > light_1), we have 3 flashes, each 2 are separated by 1 second then you can do the function you want.
do function...
// once finish the function, we loop back to the beginning to start looking for the first flash again.
}
你必须确保在发射闪光灯时没有拍摄light_1 = sample(1)。 我想到了两种方法:
1 - 如果您知道闪光灯的长度(例如:20毫秒),请使用闪光灯的长度分隔3或4个值,以获得良好的light_1值:
int i;
light_1 = sample(1);
for(i=0 ; i<4 ; i++)
{
light_1 = sample(1) < light_1 ? sample(1) : light_1;
sleep(20); // 20 = 20 ms. you can replace 20 by lenght_of_flash
}
2 - 通过校准。那么你可以使用没有闪光灯获得的值来初始化light_1;
如果你想在不知道周期的情况下在4秒钟内获得3次闪光,我认为有必要使用计时器:
这里是伪代码:
light_1 = sample();
int nb_flashes = 0;
bool fail = false;
clock_t start; to contain the time
for(::)
{
fail = false;
nb_flashes = 0;
start = clock(); //get the time to count 4 seconds.
while(nb_flashes <3)
{
while(sample() <= (light_1))
{
sleep(1);
}
nb_flashes ++;
if( (clock() - start)/CLOCKS_PER_SEC >=4)
{
fail = true; //more than 4 seconds where elapsed... so we restart from the beginning of the for loop.
break; //going outside the while loop
}
while(sample() > light_1 )
sleep(1); //waiting the end of the irst flash.
}
if (fail)
continue; // there was no 3 flashes whithin 4 seconds, so we restart from the beginning of the for loop
else
do function // do the function you want...
}
答案 4 :(得分:1)
也许我弄错了,但是下面的代码不够用吗?
// Data type and initial value for these two vars must be apt for this scenario.
int last_light = 0;
int current_light = 0;
for(uint8_t crescent_flashes = 0; TRUE; last_light = current_light){
current_light = sample();
if(current_light <= last_light){
crescent_flashes = 0;
continue;
}
crescent_flashes++;
if(crescent_flashes == 3){
do_smart_stuff();
crescent_flashes = 0;
}else{
sleep(1second);
}
}
答案 5 :(得分:1)
这个问题比你预期的要大10倍。如果你想自己解决这个问题,那就单独留下键盘,并尝试设计这些东西。
基本上,您只有一个关于灯泡的信息:打开或关闭。对于这种复杂的操作来说,这还不够,例如在指定的时间间隔内检查闪存计数。您必须创建衍生物。
首先,您必须设置某种计数器或时间戳,用于计算时间间隔,如经过时间,两个事件之间的距离等。它可以是时间戳(由操作系统或您正在使用的语言提供),或者如果您的程序是无限循环,您可以将sleep()和counter ++放入其中,并使用它来测量时间(好的,它不太准确,因为它不会与程序运行期间的时间一致,但在这个时间精度上无关紧要。)
您的衍生变体将类似于:
您必须检测并存储这些事件,最少N个,其中N是您的条件中出现的最大数字(例如,如果您想要检测3次闪光,则必须至少存储最后3次闪光)。也许,一个ringbuffer是最好的解决方案。
如果您有一系列检测到的事件,则必须检查每次更改的情况,例如:检查灯泡在最后X秒闪烁。
使用纸张,绘制时间轴,命名和绘制术语(如事件),“在纸上”运行检测算法。
再说一次:你所面临的问题是甚至更大,而不是你先付出的。但是如果你把问题分成更小的问题层(第1层:原子变化 - >事件;第2层:事件 - &gt;事件队列;第3层:事件序列分析),它们是小问题,很容易解决
首先,很难在多层构造中思考,并且很难不混合图层,但如果你有适当的低级图层,你可以在上层做更复杂的魔术,或者建立更复杂的层,比如检测莫尔斯信号。
答案 6 :(得分:1)
我假设您要做的是:在最后4秒内检测到灯闪烁了3次。通过“闪光”,我认为你的意思是灯已关闭,然后它继续。 (当然可能是因为'闪光'你的意思是光必须继续然后关闭,这需要一个更复杂的解决方案,但是因为你还没有给我们一个闪光的含义的定义,我会选择更简单的版本。)
首先,检查您现在的光线读数是否大于或小于过去某个时刻的光线读数,不会告诉您灯光是打开还是关闭。您需要建立一个低阈值,低于该阈值,您将考虑关闭灯光,以及一个高阈值,高于该阈值,您将考虑灯光亮起。当读数变化低于低阈值时,您将忽略它。当读数在两个阈值之间变化时,您也会忽略它。当读数变化超过高阈值时,你猜对了,你再次忽略它。您只关心以下两种情况:
灯泡熄灭,之前的读数低于高阈值,新读数高于高阈值;这意味着灯已经亮了。
灯泡点亮,之前的读数高于低阈值,新读数低于低阈值;这意味着灯已关闭。
如果你不这样做,那么你会得到很多错误的触发因为你的LDR读数会因为穿着高度反光的白色实验室外套走路而变化,或仅仅是因为随机噪音。
由于我们已经采取行动意味着从“关闭”转变为“开启”,因此您实际上只需要关注上面的第一个案例。 (否则,您需要考虑这两种情况。)
因此,您需要做的是拥有一个包含三个条目的数组,您可以在其中存储最后三次闪烁发生的时间。每次发生新的闪存时,您都会丢弃数组第一个元素中的时间值,然后将下两个向下移动,并将新的时间值存储在数组的最后一个元素中。每次执行此操作时,都要检查第一个和最后一个条目之间的差异是否小于或等于4秒。
注意:在任何情况下你都不应该使用睡眠或等待或延迟功能,因为当你的程序处于睡眠状态时,指示灯会闪烁,你会错过它。
答案 7 :(得分:0)
我认为你的描述可能意味着你永远不会破裂(如果你的情况不会在3秒内发生)。这是你想要的吗?我有一种感觉,一旦你采样4次你想要打破,样品2-4高于样品1;这发生在3秒内。
对于您的问题的解释,您可以将计数器创建为具有以下字段的结构:
s1,s2,s3,s4 计数 t1,t2,t3,t4
将所有值初始化为0.在第一个样本到达时,将值存储在s1中,将其值存储在t1中。
迭代:如果新样本&lt; = s1,则将其存储在s1 / t1中。如果没有,将它存储在s2中,将其存储在t2中,将计数增加1,并将t_elapsed存储为(jiffies-t1)。只要新样品> s1和t_elapsed&lt; = 3秒,处理类似并存储在下一个自由sx和tx元素中。如果你在t_elapsed&lt; = 3秒时达到3,请休息。
如果有任何新样本&lt; = s1或t_elapsed&gt; 3秒,向下旋转:s2和t2到s1和t1,s3 / t3到s2 / t2,s4 / t4到s3 / t3。如果s1> = s2,则再次向下旋转。一次(如果)s1
对于算法中经过的时间,这显然不会完全准确。您还面临进程抢占,中断等风险,并且可能想要考虑如果这是可以接受的,或者您想要使用互斥锁等保护您的结构。