添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

我正使用Node.js製作一個Raspberry Pi的GPIO的控制應用,可以接收LoRa模組傳過來的封包,並針對封包內容控制GPIO開關,主要有三個功能
1.GPIO開啟
2.GPIO關閉
3.將GPIO開啟一段設定時間後自動關閉(使用Javascript setTimeout,在設定時間後呼叫GPIO關閉的函式)

這三個功能都正常運作。

現在的問題在setTimeout函式,在setTimeout循環中,想要隨時能終止它(例如設定15秒後關閉GPIO,但想要提前終止setTimeout)。

嘗試用了clearTimeout,似乎沒有作用(中途呼叫關閉GPIO的函式,必須等到15秒後同時得到兩個輸出),附上程式輸出及程式碼片段,請教各位大大問題出在哪邊?

程式輸出:

// timeout單位為毫秒
// 打開GPIO 15 秒,呼叫deviceTurnOn(15000)
Received:0, the solenoid valve has been opened!                                
Received packet: !20!96 0 0 0 53 0 0 28 11 3 TurnOn15s RSSI: -40 SNR:   6
// setTimeout的輸出,15秒時間到後自動呼叫deviceTurnOff()函式
Received:1, the solenoid valve has been closed!                                 
// 中途呼叫deviceTurnOff()函式
Received:1, the solenoid valve has been closed!                                
Received packet: !18!96 0 0 0 53 0 0 29 9 3 TurnOff RSSI: -41 SNR:   7 
var turnOffTimeout;
// 打開GPIO
function deviceTurnOn(timeout) {
    // 檢查是否帶關閉延遲時間
    if (timeout == -1) {
        console.log(`Received:0, the solenoid valve has been opened!`);
        // 控制GPIO開啟
        OutputDevice.writeSync(0);
    else {
        // 帶關閉延遲時間time
        console.log(`Received:0, the solenoid valve has been opened!`);
        // 控制GPIO開啟
        OutputDevice.writeSync(0);
        // 清除存在的計時器
        clearTimeout(turnOffTimeout);
        // 設定延遲
        turnOffTimeout = setTimeout(deviceTurnOff, timeout);
// 關閉GPIO
function deviceTurnOff() {
    console.log(`Received:1, the solenoid valve has been closed!`);
    // 控制GPIO關閉
    OutputDevice.writeSync(1);
    // 清除計時器
    clearTimeout(turnOffTimeout);
                            

從程式來看倒是看不出什麼大問題。唯一一個程式碼我是建議拉上來
就是deviceTurnOn()內的clearTimeout。可以將其放在一開始的前頭來。
確保每一次運行ON(無論有無時間)都會確定其clearTimeout的運行,不至於造成2次setTimeout

這可能是我認為你唯一的問題了。

簡單描述程式的流程大致上是:
1.透過LoRa模組接收訊息,判斷訊息封包內容是否包含TurnOn、TurnOff、TurnOn{時間}
2.依據訊息封包內容呼叫TurnOn、TurnOff對應的Function
3.對硬體GPIO進行控制

這些功能目前都正常,唯獨隨時終止turnOffTimeout是有問題的,或許是其他程式寫法影響到?