I'm using pigpio bit-banging script (download, GitHub) that interprets the pulse durations generated by the DH22 Temperature/Humidity sensor. It sets a 200 ms pigpio watchdog to the GPIO pin and attaches a callback, passing the tick count and new level.

Here's a generic example:

def cbf(gpio, level, tick):
    print(gpio, level, tick)

pi.set_watchdog(22, 1000) # 1000 ms watchdog on GPIO 22

cb1 = pi.callback(22, pigpio.EITHER_EDGE, cbf)

For the next 1000 milliseconds, a transition in either direction on pin 22 will result in a call to cbf(), passing the new level and the tick number (microseconds).

If I understand correctly, in pigpio one can set up one watchdog per GPIO pin, so there could in principle be many running at the same time.

My question is what are these watchdogs? Are they CPU threads, or are they running in the GPIO electronics itself, or something else? Like real dogs, can they compete, conflict, or collide (say two watchdogged GPIO pins experience edges at exactly the same time), or do they get along nicely with each other?

This is from pigpio.c and may be of some help:

int gpioSetWatchdog(unsigned gpio, unsigned timeout)
   DBG(DBG_USER, "gpio=%d timeout=%d", gpio, timeout);


   if (gpio > PI_MAX_USER_GPIO)
      SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);

   if (timeout > PI_MAX_WDOG_TIMEOUT)
         "gpio %d, bad timeout (%d)", gpio, timeout);

   gpioAlert[gpio].wdTick   = systReg[SYST_CLO];
   gpioAlert[gpio].wdSteadyUs = timeout*1000;

   if (timeout) wdogBits |= (1<<gpio);
   else         wdogBits &= (~(1<<gpio));

   return 0; 

1 Answer 1


They are emulated watchdogs, done in software using software timing techniques. Based on the way the library is written, there is little chance of conflict.

If two pins experience a level change at the same time, and are detected in the same pigpio thread cycle, their callbacks will be executed in some arbitrary order, so if they have side-effects that impact each other, there may be a conflict in this way.

There is a chance, if your callback is particularly heavy, that you will experience significant system load if they are regularly triggered.

The author of this library is on rpi.SE so I was hesitant to answer. This is my understanding of the code.

I believe there is a generic worker thread that is running on a tight loop and calling static void alertEmit (at least once per sample) every cycle.

Expired Watchdogs are checked there Lines 5796-5825 and trigger the callback you register

if (wdogBits)
      for (b=0; b<=PI_MAX_USER_GPIO; b++)
         if (gpioAlert[b].wdSteadyUs)
            diff = eTick - gpioAlert[b].wdTick;

            if (diff >= gpioAlert[b].wdSteadyUs)
               timeoutBits |= (1<<b);

               gpioAlert[b].wdTick = eTick;

               if (gpioAlert[b].func)
                  if (gpioAlert[b].ex)
                     (gpioAlert[b].func)(b, PI_TIMEOUT, eTick,
                     (gpioAlert[b].func)(b, PI_TIMEOUT, eTick);

Watchdog timeout is reset on level change, by calling static void alertWdogCheck(gpioSample_t *sample, int numSamples)

This generic worker thread is defined as the task function static void * pthAlertThread(void *x) . The host pthread is created in Initialization Code and so only one exists per library instance.

  • Thank you for this clear, thorough and well sourced answer! This is really helpful to me. By introducing the code and pointing to key sections, it's much easier for a C-noob like myself to get their feet wet.
    – uhoh
    Feb 7, 2018 at 4:33
  • 1
    You are welcome. All credit goes to @joan for implementation. I am sure there is something I am missing
    – crasic
    Feb 7, 2018 at 4:57
  • I've just noticed that I haven't accepted this, sorry for the oversight!
    – uhoh
    Mar 13, 2018 at 5:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.