2016-06-17 4 views
1

У меня есть датчик движения и близости, подключенный к малине pi. То, что я хочу сделать, - это когда датчик движения обнаруживает движение, он получает показание от датчика приближения, чтобы увидеть, насколько близко человек ... когда человек попадает на определенное расстояние, отображается сообщение.Raspberry pi обнаружение близости nodejs

Датчик движения срабатывает, и я получаю считывание с датчика приближения, однако датчик приближения попадает в петлю, и значение никогда не обновляется (даже если кто-то прямо на нем).

движение:

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(); 
    } 
}); 

близость:

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 
}; 

Что мне нужно сделать, чтобы получить это работает правильно, не застревая в бесконечном цикле?

+0

Что такое эхо. стоимость? Я уверен, что вы застряли в одном из них, когда петли. Как echo.value изменяется от 0 до 1 и наоборот? –

+0

@HamiltonLucas, если датчик приближения обнаруживает что-то echo.value = 1, если нет, то это 0. Я основываю код на этом коде python: http://www.raspberrypi-spy.co.uk/2012/12/ultrasasonic-distance-measurement-using-python-part-1/если я начинаю с ничего перед датчиком, я получаю echo.value = 0, и он застревает в этом цикле, даже когда я что-то перемещаю, наоборот, если я начну с чего-то перед ним, я получаю echo.value = 1, и когда я отвожу его от датчика, он все еще застревает в этом цикле. – erichardson30

+0

Для начала это не делает ничего полезного и, вероятно, не того, что вы хотите : 'setTimeout (500);'. Это не ждет 500 мс, прежде чем продолжить. Фактически, он ничего не делает. Первый аргумент для 'setTimeout()' - это функция, которая будет называться в будущем. Второй аргумент - это время ожидания перед вызовом этой функции. Следующая строка кода после 'setTimeout()' выполняется немедленно. Он не ждет значения тайм-аута. – jfriend00

ответ

2

Вы не можете выполнить цикл while, ожидая выполнения другого кода, и измените переменную, которую вы тестируете. Javascript является однопоточным, и пока вы находитесь в цикле while, НИКАКИЙ другой код не будет работать, поэтому ваша переменная никогда не изменится и, следовательно, у вас будет бесконечный цикл.

Так, что-то вроде этого:

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(), чтобы опросить значение каждый раз в то время (это зависит от того, как работает ваш бесконтактный интерфейс).


Кроме того, строка кода, как это:

setTimeout(500); 

абсолютно ничего не делает. Во-первых, setTimeout() ожидает два аргумента. Первая должна быть функцией вызова в будущем. Второй аргумент должен быть значением времени в ms. И, setTimeout() не приостанавливает выполнение вообще. Все, что он делает, это запланировать таймер, чтобы запустить некоторое время в будущем, а затем он немедленно выполняет следующую строку кода. В Javascript нет ожиданий. Вместо этого вы планируете некоторый обратный вызов для запуска в будущем.


Правильное решение здесь зависит от того, как работает ваш сенсорный интерфейс (что не полностью описано в вашем вопросе). Если это так, это событие, управляемое событиями (что было бы идеально), тогда вы можете просто подписаться на одно из своих событий, и каждый раз, когда это событие срабатывает, вы можете проверить значение и решить, какое действие должно быть выполнено. Это не связано ни с какими-либо таймерами или с циклом.Вы можете сохранить какое-то состояние, поэтому, когда следующее событие срабатывает, вы знаете, что произошло недавно, но вы не заходите в циклы или не используете таймеры, если события управляются событиями.

Если интерфейс не управляется событиями, вам может потребоваться «опрос» состояния с использованием повторяющегося таймера setInterval(). В этом случае вы выбираете некоторый интервал времени (скажем каждую секунду), и вы проверяете значение близости, а затем решаете, какое действие следует принимать на основе значения, которое вы видите. setInterval() работает так:

// 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 
0

Потому что это застрять в петлях в то время, вы можете вместо того, чтобы определить функцию, которая рекурсивно вызывает себя каждый второй (или любой другой интервал), чтобы проверить значение эхо.

Вам просто нужно заменить ваши циклы while чем-то вроде того, что я проиллюстрировал ниже.

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; 
    } 
} 

становится

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 
} 

Обязательно позовите checkEchoValue(), по крайней мере один раз, когда вы на самом деле хотите, чтобы начать проверку значений (вероятно, где ваше время петли теперь.)