This commit is contained in:
joan 2014-11-20 15:36:16 +00:00
parent 67ff6379b4
commit 408d0f1314
17 changed files with 554 additions and 103 deletions

4
README
View File

@ -28,6 +28,10 @@ TEST (optional)
* All the tests make extensive use of gpio 4 (pin P1/J8-7).*
* Ensure that either nothing or just a LED is connected to *
* gpio 4 before running any of the tests. *
* *
* Some tests are statistical in nature and so may on *
* occasion fail. Repeated failures on the same test or *
* many failures in a group of tests indicate a problem. *
************************************************************
To test the library do

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 21+
This version is for pigpio version 23+
*/
#include <stdio.h>
@ -51,6 +51,9 @@ cmdInfo_t cmdInfo[]=
{PI_CMD_BS1, "BS1", 111, 1}, // gpioWrite_Bits_0_31_Set
{PI_CMD_BS2, "BS2", 111, 1}, // gpioWrite_Bits_32_53_Set
{PI_CMD_GDC, "GDC", 112, 2}, // gpioGetPWMdutycycle
{PI_CMD_GPW, "GPW", 112, 2}, // gpioGetServoPulsewidth
{PI_CMD_HELP, "H", 101, 5}, // cmdUsage
{PI_CMD_HELP, "HELP", 101, 5}, // cmdUsage
@ -218,6 +221,9 @@ BR2 Read bank 2 gpios.\n\
BS1 bits Set specified gpios in bank 2.\n\
BS2 bits Set specified gpios in bank 2.\n\
\n\
GDC u Get PWM dutycycle for gpio.\n\
GPW u Get servo pulsewidth for gpio.\n\
\n\
H/HELP Display command help.\n\
\n\
HWVER Get hardware version.\n\
@ -457,6 +463,8 @@ static errInfo_t errInfo[]=
{PI_SPI_XFER_FAILED , "spi xfer/read/write failed"},
{PI_BAD_POINTER , "bad (NULL) pointer"},
{PI_NO_AUX_SPI , "need a B+ for auxiliary SPI"},
{PI_NOT_PWM_GPIO , "gpio is not in use for PWM"},
{PI_NOT_SERVO_GPIO , "gpio is not in use for servo pulses"},
};
@ -577,7 +585,7 @@ int cmdParse(
break;
case 112: /* I2CC
case 112: /* GDC GPW I2CC
I2CRB MG MICS MILS MODEG NC NP PFG PRG
PROCD PROCP PROCS PRRG R READ SLRC SPIC
WVDEL WVSC WVSM WVSP WVTX WVTXR

View File

@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
*/
/*
This version is for pigpio version 16+
This version is for pigpio version 23+
*/
#ifndef COMMAND_H
@ -38,7 +38,7 @@ This version is for pigpio version 16+
#include "pigpio.h"
#define CMD_MAX_PARAM 512
#define CMD_MAX_EXTENSION 8192
#define CMD_MAX_EXTENSION (1<<16)
#define CMD_UNKNOWN_CMD -1
#define CMD_BAD_PARAMETER -2

View File

@ -479,7 +479,7 @@ Arduino style: analogWrite
.br
This and the servo functionality use the DMA and PWM or PCM peripherals
to control and schedule the pulse lengths and duty cycles.
to control and schedule the pulse lengths and dutycycles.
.br
@ -507,6 +507,31 @@ gpioPWM(23, 0); // Sets gpio23 full off.
.EE
.IP "\fBint gpioGetPWMdutycycle(unsigned user_gpio)\fP"
.IP "" 4
Returns the PWM dutycycle setting for the gpio.
.br
.br
.EX
user_gpio: 0-31
.br
.EE
.br
.br
Returns between 0 (off) and range (fully on) if OK, otherwise
PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO.
.br
.br
Range defaults to 255.
.IP "\fBint gpioSetPWMrange(unsigned user_gpio, unsigned range)\fP"
.IP "" 4
Selects the dutycycle range to be used for the gpio. Subsequent calls
@ -859,7 +884,7 @@ Firstly set the desired PWM frequency using \fBgpioSetPWMfrequency\fP.
.br
Then set the PWM range using \fBgpioSetPWMrange\fP to 1E6/frequency.
Doing this allows you to use units of microseconds when setting
the servo pulse width.
the servo pulsewidth.
.br
@ -886,6 +911,26 @@ gpioSetPWMrange(25, 2500);
Thereafter use the PWM command to move the servo,
e.g. gpioPWM(25, 1500) will set a 1500 us pulse.
.IP "\fBint gpioGetServoPulsewidth(unsigned user_gpio)\fP"
.IP "" 4
Returns the servo pulsewidth setting for the gpio.
.br
.br
.EX
user_gpio: 0-31
.br
.EE
.br
.br
Returns , 0 (off), 500 (most anti-clockwise) to 2500 (most clockwise)
if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_SERVO_GPIO.
.IP "\fBint gpioSetAlertFunc(unsigned user_gpio, gpioAlertFunc_t f)\fP"
.IP "" 4
Registers a function to be called (a callback) when the specified
@ -6023,6 +6068,12 @@ A 16-bit word value.
#define PI_CMD_SERDA 82
.br
.br
#define PI_CMD_GDC 83
.br
#define PI_CMD_GPW 84
.br
.br
#define PI_CMD_NOIB 99
.br
@ -6221,6 +6272,10 @@ A 16-bit word value.
.br
#define PI_NO_AUX_SPI -91 // need a B+ for auxiliary SPI
.br
#define PI_NOT_PWM_GPIO -92 // gpio is not in use for PWM
.br
#define PI_NOT_SERVO_GPIO -93 // gpio is not in use for servo pulses
.br
.br
@ -6258,9 +6313,9 @@ A 16-bit word value.
.br
#define PI_DEFAULT_UPDATE_MASK_R2 0xFBC7CF9C
.br
#define PI_DEFAULT_UPDATE_MASK_R3 0x80400FFFFFFCLL
#define PI_DEFAULT_UPDATE_MASK_R3 0x0080400FFFFFFCLL
.br
#define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL
.br
.EE

View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* pigpio version 22 */
/* pigpio version 23 */
#include <stdio.h>
#include <string.h>
@ -746,7 +746,7 @@ typedef struct
uint8_t is;
uint8_t pad;
uint16_t width;
uint16_t range; /* duty cycles specified by 0 .. range */
uint16_t range; /* dutycycles specified by 0 .. range */
uint16_t freqIdx;
} gpioInfo_t;
@ -1338,6 +1338,10 @@ static int myDoCommand(uint32_t *p, unsigned bufSize, char *buf)
}
break;
case PI_CMD_GDC: res = gpioGetPWMdutycycle(p[1]); break;
case PI_CMD_GPW: res = gpioGetServoPulsewidth(p[1]); break;
case PI_CMD_HELP: break;
case PI_CMD_HWVER: res = gpioHardwareRevision(); break;
@ -6068,6 +6072,8 @@ int gpioInitialise(void)
struct sockaddr_in server;
char * portStr;
unsigned port;
struct sched_param param;
clock_gettime(CLOCK_REALTIME, &libStarted);
@ -6089,6 +6095,7 @@ int gpioInitialise(void)
i = gpioHardwareRevision();
if (i == 0) gpioMask = PI_DEFAULT_UPDATE_MASK_R0;
else if (i == 17) gpioMask = PI_DEFAULT_UPDATE_MASK_COMPUTE;
else if (i < 4) gpioMask = PI_DEFAULT_UPDATE_MASK_R1;
else if (i < 16) gpioMask = PI_DEFAULT_UPDATE_MASK_R2;
else gpioMask = PI_DEFAULT_UPDATE_MASK_R3;
@ -6110,6 +6117,10 @@ int gpioInitialise(void)
fdMem = -1;
}
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
sched_setscheduler(0, SCHED_FIFO, &param);
initClock(1); /* initialise main clock */
libInitialised = 1;
@ -6409,6 +6420,23 @@ int gpioPWM(unsigned gpio, unsigned val)
return 0;
}
/* ----------------------------------------------------------------------- */
int gpioGetPWMdutycycle(unsigned gpio)
{
DBG(DBG_USER, "gpio=%d", gpio);
CHECK_INITED;
if (gpio > PI_MAX_USER_GPIO)
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
if (gpioInfo[gpio].is != GPIO_PWM)
SOFT_ERROR(PI_NOT_PWM_GPIO, "not a PWM gpio (%d)", gpio);
return gpioInfo[gpio].width;
}
/* ----------------------------------------------------------------------- */
@ -6588,6 +6616,24 @@ int gpioServo(unsigned gpio, unsigned val)
}
/* ----------------------------------------------------------------------- */
int gpioGetServoPulsewidth(unsigned gpio)
{
DBG(DBG_USER, "gpio=%d", gpio);
CHECK_INITED;
if (gpio > PI_MAX_USER_GPIO)
SOFT_ERROR(PI_BAD_USER_GPIO, "bad gpio (%d)", gpio);
if (gpioInfo[gpio].is != GPIO_SERVO)
SOFT_ERROR(PI_NOT_SERVO_GPIO, "not a servo gpio (%d)", gpio);
return gpioInfo[gpio].width;
}
/* ----------------------------------------------------------------------- */
int gpioWaveClear(void)

View File

@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
#include <stdint.h>
#include <pthread.h>
#define PIGPIO_VERSION 22
#define PIGPIO_VERSION 23
/*TEXT
@ -119,8 +119,10 @@ gpioRead Read a gpio
gpioWrite Write a gpio
gpioPWM Start/stop PWM pulses on a gpio
gpioGetPWMdutycycle Get dutycycle setting on a gpio
gpioServo Start/stop servo pulses on a gpio
gpioGetServoPulsewidth Get pulsewidth setting on a gpio
gpioDelay Delay for a number of microseconds
@ -504,8 +506,8 @@ typedef void *(gpioThreadFunc_t) (void *);
#define PI_NUM_AUX_SPI_CHANNEL 3
#define PI_NUM_STD_SPI_CHANNEL 2
#define PI_MAX_I2C_DEVICE_COUNT 8192
#define PI_MAX_SPI_DEVICE_COUNT 8192
#define PI_MAX_I2C_DEVICE_COUNT (1<<16)
#define PI_MAX_SPI_DEVICE_COUNT (1<<16)
#define PI_SPI_FLAGS_BITLEN(x) ((x&63)<<16)
#define PI_SPI_FLAGS_RX_LSB(x) ((x&1)<<15)
@ -765,7 +767,7 @@ Returns 0 if OK, otherwise PI_BAD_USER_GPIO or PI_BAD_DUTYCYCLE.
Arduino style: analogWrite
This and the servo functionality use the DMA and PWM or PCM peripherals
to control and schedule the pulse lengths and duty cycles.
to control and schedule the pulse lengths and dutycycles.
The [*gpioSetPWMrange*] function may be used to change the default
range of 255.
@ -780,6 +782,22 @@ gpioPWM(23, 0); // Sets gpio23 full off.
D*/
/*F*/
int gpioGetPWMdutycycle(unsigned user_gpio);
/*D
Returns the PWM dutycycle setting for the gpio.
. .
user_gpio: 0-31
. .
Returns between 0 (off) and range (fully on) if OK, otherwise
PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO.
Range defaults to 255.
D*/
/*F*/
int gpioSetPWMrange(unsigned user_gpio, unsigned range);
/*D
@ -964,7 +982,7 @@ Firstly set the desired PWM frequency using [*gpioSetPWMfrequency*].
Then set the PWM range using [*gpioSetPWMrange*] to 1E6/frequency.
Doing this allows you to use units of microseconds when setting
the servo pulse width.
the servo pulsewidth.
E.g. If you want to update a servo connected to gpio25 at 400Hz
@ -979,6 +997,20 @@ e.g. gpioPWM(25, 1500) will set a 1500 us pulse.
D*/
/*F*/
int gpioGetServoPulsewidth(unsigned user_gpio);
/*D
Returns the servo pulsewidth setting for the gpio.
. .
user_gpio: 0-31
. .
Returns , 0 (off), 500 (most anti-clockwise) to 2500 (most clockwise)
if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_SERVO_GPIO.
D*/
/*F*/
int gpioSetAlertFunc(unsigned user_gpio, gpioAlertFunc_t f);
/*D
@ -3795,6 +3827,9 @@ PARAMS*/
#define PI_CMD_SERW 81
#define PI_CMD_SERDA 82
#define PI_CMD_GDC 83
#define PI_CMD_GPW 84
#define PI_CMD_NOIB 99
/*DEF_E*/
@ -3951,6 +3986,8 @@ after this command is issued.
#define PI_SPI_XFER_FAILED -89 // spi xfer/read/write failed
#define PI_BAD_POINTER -90 // bad (NULL) pointer
#define PI_NO_AUX_SPI -91 // need a B+ for auxiliary SPI
#define PI_NOT_PWM_GPIO -92 // gpio is not in use for PWM
#define PI_NOT_SERVO_GPIO -93 // gpio is not in use for servo pulses
/*DEF_E*/
@ -3970,8 +4007,8 @@ after this command is issued.
#define PI_DEFAULT_UPDATE_MASK_R0 0xFFFFFFFF
#define PI_DEFAULT_UPDATE_MASK_R1 0x03E7CF93
#define PI_DEFAULT_UPDATE_MASK_R2 0xFBC7CF9C
#define PI_DEFAULT_UPDATE_MASK_R3 0x80400FFFFFFCLL
#define PI_DEFAULT_UPDATE_MASK_R3 0x0080400FFFFFFCLL
#define PI_DEFAULT_UPDATE_MASK_COMPUTE 0x00FFFFFFFFFFFFLL
/*DEF_E*/
#endif

View File

@ -109,7 +109,10 @@ read Read a gpio
write Write a gpio
set_PWM_dutycycle Start/stop PWM pulses on a gpio
get_PWM_dutycycle Get PWM dutycycle set on a gpio
set_servo_pulsewidth Start/Stop servo pulses on a gpio
get_servo_pulsewidth Get servo pulsewidth set on a gpio
callback Create gpio level change callback
wait_for_edge Wait for gpio level change
@ -244,9 +247,8 @@ import time
import threading
import os
import atexit
import codecs
VERSION = "1.12"
VERSION = "1.13"
exceptions = True
@ -390,6 +392,10 @@ _PI_CMD_SERR =80
_PI_CMD_SERW =81
_PI_CMD_SERDA=82
_PI_CMD_GDC =83
_PI_CMD_GPW =84
_PI_CMD_NOIB= 99
@ -487,6 +493,8 @@ PI_UNKNOWN_COMMAND =-88
PI_SPI_XFER_FAILED =-89
_PI_BAD_POINTER =-90
PI_NO_AUX_SPI =-91
PI_NOT_PWM_GPIO =-92
PI_NOT_SERVO_GPIO =-93
# pigpio error text
@ -580,6 +588,9 @@ _errors=[
[PI_SPI_XFER_FAILED , "SPI xfer/read/write failed"],
[_PI_BAD_POINTER , "bad (NULL) pointer"],
[PI_NO_AUX_SPI , "need a B+ for auxiliary SPI"],
[PI_NOT_PWM_GPIO , "gpio is not in use for PWM"],
[PI_NOT_SERVO_GPIO , "gpio is not in use for servo pulses"],
]
class _socklock:
@ -648,12 +659,23 @@ def tickDiff(t1, t2):
tDiff += (1 << 32)
return tDiff
if sys.version < '3':
# A couple of hacks to cope with different string handling
# between various Python versions
# 3 != 2.7.8 != 2.7.3
if sys.hexversion < 0x03000000:
def _b(x):
return x
else:
def _b(x):
return codecs.latin_1_encode(x)[0]
return x.encode('latin-1')
if sys.hexversion < 0x02070800:
def _str(x):
return buffer(x)
else:
def _str(x):
return x
def u2i(number):
"""
@ -996,6 +1018,26 @@ class pi():
return _u2i(_pigpio_command(
self.sl, _PI_CMD_PWM, user_gpio, int(dutycycle)))
def get_PWM_dutycycle(self, user_gpio):
"""
Returns the PWM dutycycle being used on the gpio.
user_gpio:= 0-31.
Returns the PWM dutycycle.
...
pi.set_PWM_dutycycle(4, 25)
print(pi.get_PWM_dutycycle(4))
25
pi.set_PWM_dutycycle(4, 203)
print(pi.get_PWM_dutycycle(4))
203
...
"""
return _u2i(_pigpio_command(self.sl, _PI_CMD_GDC, user_gpio, 0))
def set_PWM_range(self, user_gpio, range_):
"""
Sets the range of PWM values to be used on the gpio.
@ -1110,6 +1152,26 @@ class pi():
return _u2i(_pigpio_command(
self.sl, _PI_CMD_SERVO, user_gpio, int(pulsewidth)))
def get_servo_pulsewidth(self, user_gpio):
"""
Returns the servo pulsewidth being used on the gpio.
user_gpio:= 0-31.
Returns the servo pulsewidth.
...
pi.set_servo_pulsewidth(4, 525)
print(pi.get_servo_pulsewidth(4))
525
pi.set_servo_pulsewidth(4, 2130)
print(pi.get_servo_pulsewidth(4))
2130
...
"""
return _u2i(_pigpio_command(self.sl, _PI_CMD_GPW, user_gpio, 0))
def notify_open(self):
"""
Returns a notification handle (>=0).
@ -2616,7 +2678,7 @@ class pi():
_pigpio_command(self.sl, _PI_CMD_PROCP, script_id, 0, False))
if bytes > 0:
data = self._rxbuf(bytes)
pars = struct.unpack('11i', data)
pars = struct.unpack('11i', _str(data))
status = pars[0]
params = pars[1:]
else:

View File

@ -438,6 +438,25 @@ Notes
The \fBset_PWM_range\fP function may be used to change the
default range of 255.
.IP "\fBint get_PWM_dutycycle(unsigned user_gpio)\fP"
.IP "" 4
Return the PWM dutycycle in use on a gpio.
.br
.br
.EX
user_gpio: 0-31.
.br
.EE
.br
.br
Returns 0 if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO.
.IP "\fBint set_PWM_range(unsigned user_gpio, unsigned range)\fP"
.IP "" 4
Set the range of PWM values to be used on the gpio.
@ -712,7 +731,7 @@ Firstly set the desired PWM frequency using \fBset_PWM_frequency\fP.
.br
Then set the PWM range using \fBset_PWM_range\fP to 1E6/Hz.
Doing this allows you to use units of microseconds when setting
the servo pulse width.
the servo pulsewidth.
.br
@ -738,6 +757,25 @@ Thereafter use the \fBset_PWM_dutycycle\fP function to move the servo,
e.g. set_PWM_dutycycle(25, 1500) will set a 1500 us pulse.
.br
.IP "\fBint get_servo_pulsewidth(unsigned user_gpio)\fP"
.IP "" 4
Return the servo pulsewidth in use on a gpio.
.br
.br
.EX
user_gpio: 0-31.
.br
.EE
.br
.br
Returns 0 if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_SERVO_GPIO.
.IP "\fBint notify_open(void)\fP"
.IP "" 4
Get a free notification handle.

View File

@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
/* PIGPIOD_IF_VERSION 10 */
/* PIGPIOD_IF_VERSION 11 */
#include <stdio.h>
#include <stdlib.h>
@ -548,6 +548,9 @@ int gpio_write(unsigned gpio, unsigned level)
int set_PWM_dutycycle(unsigned user_gpio, unsigned dutycycle)
{return pigpio_command(gPigCommand, PI_CMD_PWM, user_gpio, dutycycle);}
int get_PWM_dutycycle(unsigned user_gpio)
{return pigpio_command(gPigCommand, PI_CMD_GDC, user_gpio, 0);}
int set_PWM_range(unsigned user_gpio, unsigned range)
{return pigpio_command(gPigCommand, PI_CMD_PRS, user_gpio, range);}
@ -566,6 +569,9 @@ int get_PWM_frequency(unsigned user_gpio)
int set_servo_pulsewidth(unsigned user_gpio, unsigned pulsewidth)
{return pigpio_command(gPigCommand, PI_CMD_SERVO, user_gpio, pulsewidth);}
int get_servo_pulsewidth(unsigned user_gpio)
{return pigpio_command(gPigCommand, PI_CMD_GPW, user_gpio, 0);}
int notify_open(void)
{return pigpio_command(gPigCommand, PI_CMD_NO, 0, 0);}

View File

@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
#include "pigpio.h"
#define PIGPIOD_IF_VERSION 10
#define PIGPIOD_IF_VERSION 11
/*TEXT
@ -115,8 +115,10 @@ gpio_read Read a gpio
gpio_write Write a gpio
set_PWM_dutycycle Start/stop PWM pulses on a gpio
get_PWM_dutycycle Get the PWM dutycycle in use on a gpio
set_servo_pulsewidth Start/stop servo pulses on a gpio
get_servo_pulsewidth Get the servo pulsewidth in use on a gpio
callback Create gpio level change callback
callback_ex Create gpio level change callback
@ -449,6 +451,18 @@ The [*set_PWM_range*] function may be used to change the
default range of 255.
D*/
/*F*/
int get_PWM_dutycycle(unsigned user_gpio);
/*D
Return the PWM dutycycle in use on a gpio.
. .
user_gpio: 0-31.
. .
Returns 0 if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_PWM_GPIO.
D*/
/*F*/
int set_PWM_range(unsigned user_gpio, unsigned range);
/*D
@ -598,7 +612,7 @@ Firstly set the desired PWM frequency using [*set_PWM_frequency*].
Then set the PWM range using [*set_PWM_range*] to 1E6/Hz.
Doing this allows you to use units of microseconds when setting
the servo pulse width.
the servo pulsewidth.
E.g. If you want to update a servo connected to gpio 25 at 400Hz
@ -611,6 +625,18 @@ Thereafter use the [*set_PWM_dutycycle*] function to move the servo,
e.g. set_PWM_dutycycle(25, 1500) will set a 1500 us pulse.
D*/
/*F*/
int get_servo_pulsewidth(unsigned user_gpio);
/*D
Return the servo pulsewidth in use on a gpio.
. .
user_gpio: 0-31.
. .
Returns 0 if OK, otherwise PI_BAD_USER_GPIO or PI_NOT_SERVO_GPIO.
D*/
/*F*/
int notify_open(void);
/*D

80
pigs.1
View File

@ -351,6 +351,78 @@ ERROR: no permission to update one or more gpios
.br
.IP "\fBGDC u\fP - Get gpio PWM dutycycle"
.IP "" 4
.br
This command returns the PWM dutycycle in use on gpio \fBu\fP.
.br
Upon success the dutycycle is returned. On error a negative
status code will be returned.
.br
\fBExample\fP
.br
.EX
$ pigs p 4 129
.br
$ pigs gdc 4
.br
129
.br
.br
pigs gdc 5
.br
-92
.br
ERROR: gpio is not in use for PWM
.br
.EE
.br
.IP "\fBGPW u\fP - Get gpio servo pulsewidth"
.IP "" 4
.br
This command returns the servo pulsewidth in use on gpio \fBu\fP.
.br
Upon success the servo pulsewidth is returned. On error a negative
status code will be returned.
.br
\fBExample\fP
.br
.EX
$ pigs s 4 1235
.br
$ pigs gpw 4
.br
1235
.br
.br
$ pigs gpw 9
.br
-93
.br
ERROR: gpio is not in use for servo pulses
.br
.EE
.br
This command returns
.br
.IP "\fBH/HELP \fP - Display command help"
.IP "" 4
This command displays a brief list of the commands and their parameters.
@ -1194,7 +1266,7 @@ $ pigs np 0
.IP "" 4
.br
This command starts PWM on gpio \fBu\fP with duty cycle \fBv\fP. The duty cycle
This command starts PWM on gpio \fBu\fP with dutycycle \fBv\fP. The dutycycle
varies from 0 (off) to range (fully on). The range defaults to 255.
.br
@ -1203,7 +1275,7 @@ will be returned.
.br
This and the servo functionality use the DMA and PWM or PCM peripherals
to control and schedule the pulse lengths and duty cycles.
to control and schedule the pulsewidths and dutycycles.
.br
The \fBPRS\fP command may be used to change the default range of 255.
@ -1290,7 +1362,7 @@ $ pigs pfg 4
.br
.br
pigs pfg 34
$ pigs pfg 34
.br
ERROR: gpio not 0-31
.br
@ -1800,7 +1872,7 @@ Upon success nothing is returned. On error a negative status code
will be returned.
.br
The servo pulse width may be 0 (off), 500 (most anti-clockwise)
The servo pulsewidth may be 0 (off), 500 (most anti-clockwise)
to 2500 (most clockwise).
.br

View File

@ -3,7 +3,7 @@
from distutils.core import setup
setup(name='pigpio',
version='1.12',
version='1.13',
author='joan',
author_email='joan@abyz.co.uk',
maintainer='joan',

View File

@ -7,6 +7,10 @@ sudo ./x_pigpio
* All the tests make extensive use of gpio 4 (pin P1-7). *
* Ensure that either nothing or just a LED is connected to *
* gpio 4 before running any of the tests. *
* *
* Some tests are statistical in nature and so may on *
* occasion fail. Repeated failures on the same test or *
* many failures in a group of tests indicate a problem. *
************************************************************
*/
@ -87,7 +91,7 @@ void t2cb(int gpio, int level, uint32_t tick)
void t2()
{
int f, r, rr, oc;
int dc, f, r, rr, oc;
printf("PWM dutycycle/range/frequency tests.\n");
@ -99,49 +103,55 @@ void t2()
gpioSetAlertFunc(GPIO, t2cb);
gpioPWM(GPIO, 0);
dc = gpioGetPWMdutycycle(GPIO);
CHECK(2, 2, dc, 0, 0, "get PWM dutycycle");
time_sleep(0.5); /* allow old notifications to flush */
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 2, f, 0, 0, "set PWM dutycycle, callback");
CHECK(2, 3, f, 0, 0, "set PWM dutycycle, callback");
gpioPWM(GPIO, 128);
dc = gpioGetPWMdutycycle(GPIO);
CHECK(2, 4, dc, 128, 0, "get PWM dutycycle");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 3, f, 40, 5, "set PWM dutycycle, callback");
CHECK(2, 5, f, 40, 5, "set PWM dutycycle, callback");
gpioSetPWMfrequency(GPIO, 100);
f = gpioGetPWMfrequency(GPIO);
CHECK(2, 4, f, 100, 0, "set/get PWM frequency");
CHECK(2, 6, f, 100, 0, "set/get PWM frequency");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 5, f, 400, 1, "callback");
CHECK(2, 7, f, 400, 1, "callback");
gpioSetPWMfrequency(GPIO, 1000);
f = gpioGetPWMfrequency(GPIO);
CHECK(2, 6, f, 1000, 0, "set/get PWM frequency");
CHECK(2, 8, f, 1000, 0, "set/get PWM frequency");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 7, f, 4000, 1, "callback");
CHECK(2, 9, f, 4000, 1, "callback");
r = gpioGetPWMrange(GPIO);
CHECK(2, 8, r, 255, 0, "get PWM range");
rr = gpioGetPWMrealRange(GPIO);
CHECK(2, 9, rr, 200, 0, "get PWM real range");
gpioSetPWMrange(GPIO, 2000);
r = gpioGetPWMrange(GPIO);
CHECK(2, 10, r, 2000, 0, "set/get PWM range");
CHECK(2, 10, r, 255, 0, "get PWM range");
rr = gpioGetPWMrealRange(GPIO);
CHECK(2, 11, rr, 200, 0, "get PWM real range");
gpioSetPWMrange(GPIO, 2000);
r = gpioGetPWMrange(GPIO);
CHECK(2, 12, r, 2000, 0, "set/get PWM range");
rr = gpioGetPWMrealRange(GPIO);
CHECK(2, 13, rr, 200, 0, "get PWM real range");
gpioPWM(GPIO, 0);
}
@ -200,7 +210,7 @@ void t3()
float on, off;
int t;
int t, v;
int pw[3]={500, 1500, 2500};
int dc[4]={20, 40, 60, 80};
@ -212,32 +222,38 @@ void t3()
for (t=0; t<3; t++)
{
gpioServo(GPIO, pw[t]);
v = gpioGetServoPulsewidth(GPIO);
CHECK(3, t+t+1, v, pw[t], 0, "get servo pulsewidth");
time_sleep(1);
t3_reset = 1;
time_sleep(4);
on = t3_on;
off = t3_off;
CHECK(3, 1+t, (1E3*(on+off))/on, 2E7/pw[t], 1,
CHECK(3, t+t+2, (1E3*(on+off))/on, 2E7/pw[t], 1,
"set servo pulsewidth");
}
gpioServo(GPIO, 0);
gpioSetPWMfrequency(GPIO, 1000);
f = gpioGetPWMfrequency(GPIO);
CHECK(3, 4, f, 1000, 0, "set/get PWM frequency");
CHECK(3, 7, f, 1000, 0, "set/get PWM frequency");
rr = gpioSetPWMrange(GPIO, 100);
CHECK(3, 5, rr, 200, 0, "set PWM range");
CHECK(3, 8, rr, 200, 0, "set PWM range");
for (t=0; t<4; t++)
{
gpioPWM(GPIO, dc[t]);
v = gpioGetPWMdutycycle(GPIO);
CHECK(3, t+t+9, v, dc[t], 0, "get PWM dutycycle");
time_sleep(1);
t3_reset = 1;
time_sleep(2);
on = t3_on;
off = t3_off;
CHECK(3, 6+t, (1E3*on)/(on+off), 1E1*dc[t], 1,
CHECK(3, t+t+10, (1E3*on)/(on+off), 1E1*dc[t], 1,
"set PWM dutycycle");
}

View File

@ -5,11 +5,14 @@
#* All the tests make extensive use of gpio 4 (pin P1-7). *
#* Ensure that either nothing or just a LED is connected to *
#* gpio 4 before running any of the tests. *
#* *
#* Some tests are statistical in nature and so may on *
#* occasion fail. Repeated failures on the same test or *
#* many failures in a group of tests indicate a problem. *
#************************************************************
import sys
import time
import codecs
import struct
import pigpio
@ -17,9 +20,19 @@ import pigpio
GPIO=4
def STRCMP(r, s):
if r != codecs.latin_1_encode(s)[0]:
print(r, codecs.latin_1_encode(s)[0])
if sys.hexversion > 0x03000000:
if type(r) == type(""):
r = bytearray(r, 'latin-1')
if type(s) == type(""):
s = bytearray(s, 'latin-1')
if r != s:
print(r, s)
return 0
else:
return 1
@ -87,52 +100,59 @@ def t2():
t2cb = pi.callback(GPIO, pigpio.EITHER_EDGE, t2cbf)
pi.set_PWM_dutycycle(GPIO, 0)
dc = pi.get_PWM_dutycycle(GPIO)
CHECK(2, 2, dc, 0, 0, "get PWM dutycycle")
time.sleep(0.5) # allow old notifications to flush
oc = t2_count
time.sleep(2)
f = t2_count - oc
CHECK(2, 2, f, 0, 0, "set PWM dutycycle, callback")
CHECK(2, 3, f, 0, 0, "set PWM dutycycle, callback")
pi.set_PWM_dutycycle(GPIO, 128)
dc = pi.get_PWM_dutycycle(GPIO)
CHECK(2, 4, dc, 128, 0, "get PWM dutycycle")
time.sleep(1)
oc = t2_count
time.sleep(2)
f = t2_count - oc
CHECK(2, 3, f, 40, 10, "set PWM dutycycle, callback")
CHECK(2, 5, f, 40, 10, "set PWM dutycycle, callback")
pi.set_PWM_frequency(GPIO,100)
f = pi.get_PWM_frequency(GPIO)
CHECK(2, 4, f, 100, 0, "set/get PWM frequency")
CHECK(2, 6, f, 100, 0, "set/get PWM frequency")
time.sleep(1)
oc = t2_count
time.sleep(2)
f = t2_count - oc
CHECK(2, 5, f, 400, 5, "callback")
CHECK(2, 7, f, 400, 5, "callback")
pi.set_PWM_frequency(GPIO,1000)
f = pi.get_PWM_frequency(GPIO)
CHECK(2, 6, f, 1000, 0, "set/get PWM frequency")
CHECK(2, 8, f, 1000, 0, "set/get PWM frequency")
time.sleep(1)
oc = t2_count
time.sleep(2)
f = t2_count - oc
CHECK(2, 7, f, 4000, 5, "callback")
CHECK(2, 9, f, 4000, 5, "callback")
r = pi.get_PWM_range(GPIO)
CHECK(2, 8, r, 255, 0, "get PWM range")
rr = pi.get_PWM_real_range(GPIO)
CHECK(2, 9, rr, 200, 0, "get PWM real range")
pi.set_PWM_range(GPIO, 2000)
r = pi.get_PWM_range(GPIO)
CHECK(2, 10, r, 2000, 0, "set/get PWM range")
CHECK(2, 10, r, 255, 0, "get PWM range")
rr = pi.get_PWM_real_range(GPIO)
CHECK(2, 11, rr, 200, 0, "get PWM real range")
pi.set_PWM_range(GPIO, 2000)
r = pi.get_PWM_range(GPIO)
CHECK(2, 12, r, 2000, 0, "set/get PWM range")
rr = pi.get_PWM_real_range(GPIO)
CHECK(2, 13, rr, 200, 0, "get PWM real range")
pi.set_PWM_dutycycle(GPIO, 0)
t3_reset=True
@ -175,6 +195,10 @@ def t3():
for x in pw:
t += 1
pi.set_servo_pulsewidth(GPIO, x)
v = pi.get_servo_pulsewidth(GPIO)
CHECK(3, t, v, int(x), 0, "get servo pulsewidth")
t += 1
time.sleep(1)
t3_reset = True
time.sleep(4)
@ -187,15 +211,19 @@ def t3():
pi.set_servo_pulsewidth(GPIO, 0)
pi.set_PWM_frequency(GPIO, 1000)
f = pi.get_PWM_frequency(GPIO)
CHECK(3, 4, f, 1000, 0, "set/get PWM frequency")
CHECK(3, 7, f, 1000, 0, "set/get PWM frequency")
rr = pi.set_PWM_range(GPIO, 100)
CHECK(3, 5, rr, 200, 0, "set PWM range")
CHECK(3, 8, rr, 200, 0, "set PWM range")
t = 5
t = 8
for x in dc:
t += 1
pi.set_PWM_dutycycle(GPIO, x*100)
v = pi.get_PWM_dutycycle(GPIO)
CHECK(3, t, v, int(x*100), 0, "get PWM dutycycle")
t += 1
time.sleep(1)
t3_reset = True
time.sleep(2)
@ -684,9 +712,9 @@ def tb():
b = pi.i2c_read_byte_data(h, 48)
CHECK(11, 7, b, 2, 0, "i2c read byte data")
exp = "[aB\x08cD\xAAgHj\xFD]"
exp = b"[aB\x08cD\xAAgHj\xFD]"
e = pi.i2c_write_device(h, '\x1D' + exp)
e = pi.i2c_write_device(h, b'\x1D'+ exp)
CHECK(11, 8, e, 0, 0, "i2c write device")
e = pi.i2c_write_device(h, '\x1D')
@ -706,10 +734,9 @@ def tb():
b = pi.i2c_read_byte_data(h, 0x1d)
CHECK(11, 14, b, 0x55, 0, "i2c read byte data")
exps = b"[1234567890#]"
exp = "[1234567890#]"
e = pi.i2c_write_block_data(h, 0x1C, exps)
e = pi.i2c_write_block_data(h, 0x1C, exp)
CHECK(11, 15, e, 0, 0, "i2c write block data")
e = pi.i2c_write_device(h, '\x1D')

View File

@ -7,6 +7,10 @@ sudo ./x_pigpiod_if
* All the tests make extensive use of gpio 4 (pin P1-7). *
* Ensure that either nothing or just a LED is connected to *
* gpio 4 before running any of the tests. *
* *
* Some tests are statistical in nature and so may on *
* occasion fail. Repeated failures on the same test or *
* many failures in a group of tests indicate a problem. *
************************************************************
*/
@ -84,7 +88,7 @@ void t2cb(unsigned gpio, unsigned level, uint32_t tick)
void t2()
{
int f, r, rr, oc;
int dc, f, r, rr, oc;
printf("PWM dutycycle/range/frequency tests.\n");
@ -96,49 +100,55 @@ void t2()
callback(GPIO, EITHER_EDGE, t2cb);
set_PWM_dutycycle(GPIO, 0);
dc = get_PWM_dutycycle(GPIO);
CHECK(2, 2, dc, 0, 0, "get PWM dutycycle");
time_sleep(0.5); /* allow old notifications to flush */
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 2, f, 0, 0, "set PWM dutycycle, callback");
CHECK(2, 3, f, 0, 0, "set PWM dutycycle, callback");
set_PWM_dutycycle(GPIO, 128);
dc = get_PWM_dutycycle(GPIO);
CHECK(2, 4, dc, 128, 0, "get PWM dutycycle");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 3, f, 40, 5, "set PWM dutycycle, callback");
CHECK(2, 5, f, 40, 5, "set PWM dutycycle, callback");
set_PWM_frequency(GPIO, 100);
f = get_PWM_frequency(GPIO);
CHECK(2, 4, f, 100, 0, "set/get PWM frequency");
CHECK(2, 6, f, 100, 0, "set/get PWM frequency");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 5, f, 400, 1, "callback");
CHECK(2, 7, f, 400, 1, "callback");
set_PWM_frequency(GPIO, 1000);
f = get_PWM_frequency(GPIO);
CHECK(2, 6, f, 1000, 0, "set/get PWM frequency");
CHECK(2, 8, f, 1000, 0, "set/get PWM frequency");
oc = t2_count;
time_sleep(2);
f = t2_count - oc;
CHECK(2, 7, f, 4000, 1, "callback");
CHECK(2, 9, f, 4000, 1, "callback");
r = get_PWM_range(GPIO);
CHECK(2, 8, r, 255, 0, "get PWM range");
rr = get_PWM_real_range(GPIO);
CHECK(2, 9, rr, 200, 0, "get PWM real range");
set_PWM_range(GPIO, 2000);
r = get_PWM_range(GPIO);
CHECK(2, 10, r, 2000, 0, "set/get PWM range");
CHECK(2, 10, r, 255, 0, "get PWM range");
rr = get_PWM_real_range(GPIO);
CHECK(2, 11, rr, 200, 0, "get PWM real range");
set_PWM_range(GPIO, 2000);
r = get_PWM_range(GPIO);
CHECK(2, 12, r, 2000, 0, "set/get PWM range");
rr = get_PWM_real_range(GPIO);
CHECK(2, 13, rr, 200, 0, "get PWM real range");
set_PWM_dutycycle(GPIO, 0);
}
@ -176,7 +186,7 @@ void t3()
int pw[3]={500, 1500, 2500};
int dc[4]={20, 40, 60, 80};
int f, rr;
int f, rr, v;
float on, off;
int t;
@ -188,32 +198,38 @@ void t3()
for (t=0; t<3; t++)
{
set_servo_pulsewidth(GPIO, pw[t]);
v = get_servo_pulsewidth(GPIO);
CHECK(3, t+t+1, v, pw[t], 0, "get servo pulsewidth");
time_sleep(1);
t3_reset = 1;
time_sleep(4);
on = t3_on;
off = t3_off;
CHECK(3, 1+t, (1000.0*(on+off))/on, 20000000.0/pw[t], 1,
CHECK(3, t+t+2, (1000.0*(on+off))/on, 20000000.0/pw[t], 1,
"set servo pulsewidth");
}
set_servo_pulsewidth(GPIO, 0);
set_PWM_frequency(GPIO, 1000);
f = get_PWM_frequency(GPIO);
CHECK(3, 4, f, 1000, 0, "set/get PWM frequency");
CHECK(3, 7, f, 1000, 0, "set/get PWM frequency");
rr = set_PWM_range(GPIO, 100);
CHECK(3, 5, rr, 200, 0, "set PWM range");
CHECK(3, 8, rr, 200, 0, "set PWM range");
for (t=0; t<4; t++)
{
set_PWM_dutycycle(GPIO, dc[t]);
v = get_PWM_dutycycle(GPIO);
CHECK(3, t+t+9, v, dc[t], 0, "get PWM dutycycle");
time_sleep(1);
t3_reset = 1;
time_sleep(2);
on = t3_on;
off = t3_off;
CHECK(3, 6+t, (1000.0*on)/(on+off), 10.0*dc[t], 1,
CHECK(3, t+t+10, (1000.0*on)/(on+off), 10.0*dc[t], 1,
"set PWM dutycycle");
}

20
x_pigs
View File

@ -1,6 +1,6 @@
#!/bin/bash
VERSION=22
VERSION=23
GPIO=4
@ -16,6 +16,10 @@ GPIO=4
# export PIGPIO_ADDR=pi_host # to specify the Pi if testing remotely
# ./x_pigs
#
# Some tests are statistical in nature and so may on occasion fail.
# Repeated failures on the same test or many failures in a group
# of tests indicate a problem.
#
s=$(pigs bc1 0)
if [[ $s = "" ]]; then echo "BC1 ok"; else echo "BC1 fail ($s)"; fi
@ -42,7 +46,7 @@ s=$(pigs bs2 0)
if [[ $s = "" ]]; then echo "BS2 ok"; else echo "BS2 fail ($s)"; fi
s=$(pigs h)
if [[ ${#s} = 4684 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
if [[ ${#s} = 4778 ]]; then echo "HELP ok"; else echo "HELP fail (${#s})"; fi
s=$(pigs hwver)
if [[ $s -ne 0 ]]; then echo "HWVER ok"; else echo "HWVER fail ($s)"; fi
@ -144,10 +148,16 @@ if [[ $s = "" ]]; then echo "PUD-e ok"; else echo "PUD-e fail ($s)"; fi
s=$(pigs p $GPIO 128)
if [[ $s = "" ]]; then echo "PWM-a ok"; else echo "PWM-a fail ($s)"; fi
s=$(pigs gdc $GPIO)
if [[ $s = 128 ]]; then echo "GDC-a ok"; else echo "GDC-a fail ($s)"; fi
s=$(pigs pwm $GPIO 64)
if [[ $s = "" ]]; then echo "PWM-b ok"; else echo "PWM-b fail ($s)"; fi
s=$(pigs GDC $GPIO)
if [[ $s = 64 ]]; then echo "GDC-b ok"; else echo "GDC-b fail ($s)"; fi
s=$(pigs pwm $GPIO 0)
if [[ $s = "" ]]; then echo "PWM-c ok"; else echo "PWM-c fail ($s)"; fi
s=$(pigs gdc $GPIO)
if [[ $s = 0 ]]; then echo "GDC-c ok"; else echo "GDC-c fail ($s)"; fi
s=$(pigs m $GPIO r)
if [[ $s = "" ]]; then echo "PWM-d ok"; else echo "PWM-d fail ($s)"; fi
@ -164,10 +174,16 @@ if [[ $s = "" ]]; then echo "READ-e ok"; else echo "READ-e fail ($s)"; fi
s=$(pigs s $GPIO 500)
if [[ $s = "" ]]; then echo "SERVO-a ok"; else echo "SERVO-a fail ($s)"; fi
s=$(pigs gpw $GPIO)
if [[ $s = 500 ]]; then echo "GPW-a ok"; else echo "GPW-a fail ($s)"; fi
s=$(pigs servo $GPIO 2500)
if [[ $s = "" ]]; then echo "SERVO-b ok"; else echo "SERVO-b fail ($s)"; fi
s=$(pigs gpw $GPIO)
if [[ $s = 2500 ]]; then echo "GPW-b ok"; else echo "GPW-b fail ($s)"; fi
s=$(pigs servo $GPIO 0)
if [[ $s = "" ]]; then echo "SERVO-c ok"; else echo "SERVO-c fail ($s)"; fi
s=$(pigs gpw $GPIO)
if [[ $s = 0 ]]; then echo "GPW-c ok"; else echo "GPW-c fail ($s)"; fi
s=$(pigs w $GPIO 1)
if [[ $s = "" ]]; then echo "SERVO-d ok"; else echo "SERVO-d fail ($s)"; fi

24
x_pipe
View File

@ -1,6 +1,6 @@
#!/bin/bash
VERSION=22
VERSION=23
GPIO=4
@ -15,6 +15,10 @@ GPIO=4
# sudo pigpiod # if not already running
# ./x_pipe # on the Pi running pigpiod
#
# Some tests are statistical in nature and so may on occasion fail.
# Repeated failures on the same test or many failures in a group
# of tests indicate a problem.
#
echo "bc1 0" >/dev/pigpio
read -t 1 s </dev/pigout
@ -194,12 +198,21 @@ if [[ $s = 0 ]]; then echo "PUD-e ok"; else echo "PUD-e fail ($s)"; fi
echo "p $GPIO 128" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PWM-a ok"; else echo "PWM-a fail ($s)"; fi
echo "gdc $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 128 ]]; then echo "GDC-a ok"; else echo "GDC-a fail ($s)"; fi
echo "pwm $GPIO 64" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PWM-b ok"; else echo "PWM-b fail ($s)"; fi
echo "GDC $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 64 ]]; then echo "GDC-b ok"; else echo "GDC-b fail ($s)"; fi
echo "pwm $GPIO 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PWM-c ok"; else echo "PWM-c fail ($s)"; fi
echo "gdc $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "GDC-c ok"; else echo "GDC-c fail ($s)"; fi
echo "m $GPIO r" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "PWM-d ok"; else echo "PWM-d fail ($s)"; fi
@ -223,12 +236,21 @@ if [[ $s = 0 ]]; then echo "READ-e ok"; else echo "READ-e fail ($s)"; fi
echo "s $GPIO 500" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SERVO-a ok"; else echo "SERVO-a fail ($s)"; fi
echo "gpw $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 500 ]]; then echo "GPW-a ok"; else echo "GPW-a fail ($s)"; fi
echo "servo $GPIO 2500" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SERVO-b ok"; else echo "SERVO-b fail ($s)"; fi
echo "GPW $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 2500 ]]; then echo "GPW-b ok"; else echo "GPW-b fail ($s)"; fi
echo "servo $GPIO 0" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SERVO-c ok"; else echo "SERVO-c fail ($s)"; fi
echo "gpw $GPIO" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "GPW-c ok"; else echo "GPW-c fail ($s)"; fi
echo "w $GPIO 1" >/dev/pigpio
read -t 1 s </dev/pigout
if [[ $s = 0 ]]; then echo "SERVO-d ok"; else echo "SERVO-d fail ($s)"; fi