er0603
er0603

Reputation: 21

How to make clearTimeout work properly to cancel(break) setTimeout loop?

I'm using Node.js to build an application that can read USB LoRa module data and control the Raspberry Pi GPIO pins.

There are three main functions:

  1. Set GPIO to turn on (given pin 0 signal)

  2. Set GPIO off (given pin 1 signal)

  3. Set GPIO to turn off after a period of time (using the setTimeout function)

The main functions are working well.

The problem is that in the setTimeout loop, I want to terminate it at any time.

I tried to use clearTimeout to cancel the setTimeout loop, but it doesn't seem to work. Am I doing something wrong?

For example.

Using the string "TurnOn15s" in the packet received by LoRa. I can't terminate the timeout at any time. I have to wait until the end of 15 seconds to turn off the GPIO pins. If I call the deviceTurnOff(1) function during the timeout execution, I will get two outputs after the end of the loop.

The program output is as follows:

// Output by `deviceTurnOn(0,15000)` from received LoRa packet.
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

// Output by `setTimeout` function.
Received:1, the solenoid valve has been closed!                                 

// Output by deviceTurnOff(1) from received LoRa packet.
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 

Here is the partial code:

var turnOffTimeout = null; // turnOffTimeout

// Control Raspberry Pi GPIO pins.
function deviceTurnOn(controlValueType, timeout) {

  // Do Turn On Raspberry Pi GPIO pins.
  if (timeout == -1) {

    // if no time string in the packet.
    console.log(`Received:${controlValueType}, the solenoid valve has been opened!`);
    OutputDevice.writeSync(controlValueType);
  } else {

    // if contains time string in the packet.
    console.log(`Received:${controlValueType}, the solenoid valve has been opened!`);
    OutputDevice.writeSync(controlValueType);
    turnOffTimer(timeout);
  }
}

// Control Raspberry Pi GPIO pins.
function deviceTurnOff(controlValueType) {

  // Do Turn Off Raspberry Pi GPIO pins.
  console.log(`Received:${controlValueType}, the solenoid valve has been closed!`);
  OutputDevice.writeSync(controlValueType);
  // clearTimeout
  if (turnOffTimeout) {
    clearTimeout(turnOffTimeout);
  }
}


// Raspberry Pi GPIO pins turn off timeout.
function turnOffTimer(timeout) {
  turnOffTimeout = setTimeout(function() {
    deviceTurnOff(1);
  }, timeout);
}

Contains three functions: deviceTurnOn, deviceTurnOff, turnOffTimer

The format of the function call is

deviceTurnOff(1);
deviceTurnOn(0,timeout);

// Timeout is milliseconds

Update;

I tried to modify my program as follows, I get the same output as the previous version code, the problem is still not solved.

 var turnOffTimeout = null; // turnOffTimeout

    // Control Raspberry Pi GPIO pins.
    function deviceTurnOn(controlValueType, timeout) {
        // Do Turn On Raspberry Pi GPIO pins.

        if (timeout == -1) {

            // if no time string in the packet.
            console.log(`Received:${controlValueType}, the solenoid valve has been opened!`);
            OutputDevice.writeSync(controlValueType);
        }
        else {

            // if contains time string in the packet.
            console.log(`Received:${controlValueType}, the solenoid valve has been opened!`);
            OutputDevice.writeSync(controlValueType);
            // clearTimeout.
            clearTimeout(turnOffTimeout);
            // set new timeout.
            turnOffTimeout = setTimeout(function () {
                deviceTurnOff(1);
            }, timeout);
        }
    }

    // Control Raspberry Pi GPIO pins.
    function deviceTurnOff(controlValueType) {

        // Do Turn Off Raspberry Pi GPIO pins.
        console.log(`Received:${controlValueType}, the solenoid valve has been closed!`);
        clearTimeout(turnOffTimeout);
        OutputDevice.writeSync(controlValueType);

    }

Upvotes: 2

Views: 1357

Answers (1)

Larry Williamson
Larry Williamson

Reputation: 1142

Make sure you clearTimeout when starting AND stopping, you also don't need to check to see of a timeout is set. Also there's really no need for a third function just to cancel a timer, since clearTimeout already exists:

var timeout;
var timeout_ms = 10000;

var stop = function(){
 clearTimeout(timeout);
 turnOff();
}

var start(){
 clearTimeout(timeout); // clear existing t/o just in case
 timeout = setTimeout(turnOff,timeout_ms);
 turnOn();
}

Upvotes: 2

Related Questions