首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Raspberry pi邻近检测节点pi

Raspberry pi邻近检测节点pi
EN

Stack Overflow用户
提问于 2016-06-18 02:50:35
回答 2查看 298关注 0票数 1

我有一个运动和接近感应器连接到树莓派上。我想要发生的是,当运动传感器检测到运动时,它会从接近感应器获得读数,以查看该人在特定距离内is...once该人有多近,就会显示一条消息。

运动传感器被触发,我从接近传感器获得读数,然而,接近传感器陷入循环,值永远不会更新(即使有人在它上面)。

运动:

代码语言:javascript
复制
import gpio from 'gpio';
import proximity from './proximity';

const gpio4 = gpio.export(4, {
  direction: 'in',
});

// bind to the "change" event
gpio4.on('change', (val) => {
  // value will report either 1 or 0 (number) when the value changes
  if (val === 1) {
    console.log('checking proximity');
    proximity.getDistance();
  }
});

接近度:

代码语言:javascript
复制
import gpio from 'gpio';

// pin 38 GPIO 20 - for trigger
const trig = gpio.export(38, {
  direction: 'out'
});

// pin 37 GPIO 26 - for echo
const echo = gpio.export(37, {
  direction: 'in'
});

function getDistance() {
  const speedSound = 34000;
  // resetting trigger
  trig.set(0);
  setTimeout(500);
  console.log("initial trig value (0): " + trig.value); // should be 0
  responsiveVoice.speak('');
  const timestamp = moment().add(30, 's');
  let start = 0;
  let end = 0;

  trig.set();
  setTimeout(10);
  trig.set(0);

  while (echo.value === 0) {
    start = new Date().getTime() / 1000;
    console.log('Echo is ' + echo.value);
  }

  while (echo.value === 1) {
    end = new Date().getTime() / 1000;
    console.log('Echo is ' + echo.value);
    let timeDiff = end - start;
    let distance = (timeDiff * speedSound) / 2;

    console.log('Distance = ' + distance);

    if (distance < 60) {
      console.log('User is within 2 ft. Enable voice');
      return true;
    } else {
      return false;
    }
  }
}

module.exports = {
  getDistance
};

我需要做什么才能在不陷入无限循环的情况下正确地工作呢?

EN

回答 2

Stack Overflow用户

发布于 2016-06-18 03:11:29

您不能执行while循环,期望其他代码运行并更改您正在测试的变量。Javascript是单线程的,只要您在while循环中,就不会运行其他代码,因此您的变量永远不会更改,因此您会有一个无限循环。

所以,就像这样:

代码语言:javascript
复制
while (echo.value === 0) {
    start = new Date().getTime() / 1000;
    console.log('Echo is ' + echo.value);
}

是一个无限循环,如果echo.value启动=== 0的话。只要那个while循环还在运行,echo.value就永远不会改变它的值--因此它最终会变成一个无限循环。这就是单一三位一体和事件驱动的本质。

Javascript是一种事件驱动语言。当前执行线程一直运行到完成,然后(也只有在那时) JS引擎从事件队列中拉出下一个事件,并运行与该事件关联的代码。因此,等待某些外部代码更改某些变量的while循环在Javascript中永远不会工作,因为只要while循环还在运行,外部代码就永远不会运行。

相反,您应该使用本地触发的事件或使用setInterval()每隔一段时间轮询该值(这取决于您的邻近接口是如何工作的)。

另外,下面这样一行代码:

代码语言:javascript
复制
setTimeout(500);

什么都不做。首先,setTimeout()需要两个参数。第一个应该是在将来某个时候调用的函数。第二个参数应该是以毫秒为单位的时间值。而且,setTimeout()根本不会暂停执行。它所做的就是安排一个计时器在将来的某个时间触发,然后它会立即执行下一行代码。在Javascript中没有等待。相反,您可以安排一些回调在将来的某个时候运行。

正确的解决方案取决于您的接近感应器接口是如何工作的(在您的问题中没有完全描述)。如果它本身是事件驱动的(这将是理想的),那么你可以只订阅它的一个事件,每次该事件触发时,你可以检查该值并决定应该执行什么操作。这将不涉及任何计时器或任何循环。你可能想保存一些状态,这样当下一个事件触发时,你就知道最近发生了什么,但如果事情是事件驱动的,你就不会进入循环或使用计时器。

如果接口不是事件驱动的,那么您可能需要使用循环的setInterval()计时器“轮询”状态。在这种情况下,您选择某个时间间隔(例如每秒),然后检查接近度值,然后根据您看到的值决定采取什么操作。setInterval()的工作原理是这样的:

代码语言:javascript
复制
// poll once per second
setInterval(function() {
    // put some code here that will run every second
}, 1000);

// code here will run immediately - the timer callback runs some time in the future
票数 2
EN

Stack Overflow用户

发布于 2016-06-18 03:14:12

因为它被困在while循环中,所以您可以定义一个每秒(或任何时间间隔)递归调用自身的函数来检查echo的值。

您只需要将while循环替换为如下所示的内容。

代码语言:javascript
复制
while (echo.value === 0) {
  start = new Date().getTime() / 1000;
  console.log('Echo is ' + echo.value);
}

while (echo.value === 1) {
  end = new Date().getTime() / 1000;
  console.log('Echo is ' + echo.value);
  let timeDiff = end - start;
  let distance = (timeDiff * speedSound) / 2;

  console.log('Distance = ' + distance);

  if (distance < 60) {
    console.log('User is within 2 ft. Enable voice');
    responsiveVoice.speak('Hello, I am Jarvis; welcome to Cardinal Solutions. Please check in.');
    return true;
  } else {
    return false;
  }
}

变成了

代码语言:javascript
复制
function checkEchoValue() {
  if(echo.value === 0) {
    console.log("Echo value is zero.");
    start = new Date().getTime() / 1000;
  } else {
    console.log('Echo value is non-zero');

    end = new Date().getTime() / 1000;
    let timeDiff = end - start;
    let distance = (timeDiff * speedSound) / 2;

    console.log('Distance = ' + distance);

    if (distance < 60) {
      console.log('User is within 2 ft. Enable voice');
      responsiveVoice.speak('Hello, I am Jarvis; welcome to Cardinal Solutions. Please check in.');
    }
  }

  setTimeout(checkEchoValue, 1000); 
  //calls this method again in a second
}

当您真正想要开始检查值时(可能是while循环现在所在的位置),请确保至少调用一次checkEchoValue()。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37888457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档