【问题标题】:Arduino double clap sensing code breakingArduino双拍感知密码破解
【发布时间】:2019-06-04 04:44:25
【问题描述】:

我正在制作一个程序,当我拍两下时会打开我的灯。我将项目编码为: 1. 听声音(第一次鼓掌) 2. 听安静(拍手之间的休息)这是为了避免错误的触发(说话等)。 3. 听第二次噪音(第二次拍手)。

代码运行并正常工作,但它有几个我正在努力寻找/修复的断点。我知道如果我发出声音,然后我就安静了,然后我重复发出另一个声音,并且代码迅速连续地卡在第一个 while 循环中,或者完全停止进入第一个 while 循环。当我说话时,代码经常会中断。

如果有人愿意为我节省一些时间和精力,我已经提供了代码。我会很感激所有建议,因为我还是个初学者。

bool quiet = false;
bool loud = false;
int runtime = 1000;
int start = millis();
bool clap = false;
bool clap2 = false;
void setup() {

    Serial.begin(9600);
    pinMode(2, INPUT);
}

void loop() {

    int mic = digitalRead(2);
    if (mic == 0) {
        Serial.println("loud");
        clap = true;
    } else {
        Serial.println("quiet");
    }
    if (clap == true) {
        clap = false;
        Serial.println("clap");
        start = millis();
        delay(500);
        while (start >= millis() - runtime && loud != true) {
            mic = digitalRead(2);
            if (mic == 0) {
                Serial.println("noise detected!");
                loud = true;
            } else {
                Serial.println("scilence");
                quiet = true;
            }

        }
    } else {
        delay(1);
    }
    if (quiet == true && loud == false) {
        quiet = false;
        Serial.println("listening for second clap...");
        delay(500);
        start = millis();
        while (start >= millis() - runtime) {
            mic = digitalRead(2);
            if (mic == 0) {
                clap2 = true;
            } else {
                delay(1);
            }
        }
    } else {
        loud = false;
        quiet = false;
    }
    if (clap2 == true) {
        clap2 = false;
        Serial.println("clap 2");
        delay(1000);
    } else {
        delay(1);
    }
}

【问题讨论】:

    标签: arduino arduino-uno arduino-ide


    【解决方案1】:

    欢迎来到 StackOverflow!

    从您发布的程序来看,我认为您过于复杂了 ;)。首先,delay() 函数是一个阻塞函数:在延迟时间流逝期间什么都不会发生。因此,通常建议比较时间以了解您是否等待足够长的时间:然后您可以在此期间执行其他任务。

    我会为您的loop() 函数提出类似的建议:

    if(digitalRead(2)==0) //loud
    {
        unsigned long first_clap_time = millis();
        unsigned long elapsed_time = 0;
        bool silence = false;
        bool exit = false;
        while (elapsed_time < 5000 || exit)  // allow a max delay of 5sec
        {
            if (digitalRead(2)!=0) silence = true;
            elapsed_time = millis() - first_clap_time;
            if (digitalRead(2)==0 && elapsed_time > 500 && silence) 
            {
                Serial.println("Two claps detected!");  //if a second clap is detected 500 milliseconds after the first, and before 5 sec, and a silence was detected
                exit = true;
            }
        }      
    }
    

    这应该只能检测到两个拍手,间隔在 500 毫秒到 5 秒之间(当然要调整)。我无法测试这个程序,所以请随时提供反馈!

    希望对你有帮助,

    【讨论】:

    • 您的代码运行良好,我想我理解您所说的比较时间而不是使用延迟功能。我将来一定会使用这些信息!唯一的问题是我需要代码来检测拍手,然后确保周围环境安静,然后再检测到另一次拍手。我发现如果我可以让代码在第二次拍手之前检测到静音,我可以避免大多数错误触发,比如说话。你认为这是可能的吗?
    • 我很高兴听到这个消息!我编辑了我的答案,等待检测到静音,然后再触发第二次拍手(乍一看我没有看到这个要求)。请注意,它会在非常短暂的沉默中起作用......但是对于很长的沉默的修改并不重!
    • 非常感谢您的回答!你真的帮了我,但我遇到了一个问题。该程序根据需要运行,直到我运行 if 语句多次使序列看起来像这样:first clapTwo claps detected! Two claps detected! Two claps detected! Two claps detected! Two claps detected! Two claps detected! Two claps detected! Two claps detected! 我试图通过添加语句使程序运行一次:
    • 成功了吗?
    猜你喜欢
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 2015-10-18
    • 1970-01-01
    相关资源
    最近更新 更多