diff --git a/README b/README index 9aeb5c4..381a237 100644 --- a/README +++ b/README @@ -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 diff --git a/command.c b/command.c index 23f372b..3cb325a 100644 --- a/command.c +++ b/command.c @@ -26,7 +26,7 @@ For more information, please refer to */ /* -This version is for pigpio version 21+ +This version is for pigpio version 23+ */ #include @@ -40,7 +40,7 @@ This version is for pigpio version 21+ cmdInfo_t cmdInfo[]= { - /* num str vfyt retv */ + /* num str vfyt retv */ {PI_CMD_BC1, "BC1", 111, 1}, // gpioWrite_Bits_0_31_Clear {PI_CMD_BC2, "BC2", 111, 1}, // gpioWrite_Bits_32_53_Clear @@ -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 diff --git a/command.h b/command.h index fa3cd2b..b448f36 100644 --- a/command.h +++ b/command.h @@ -26,7 +26,7 @@ For more information, please refer to */ /* -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 diff --git a/pigpio.3 b/pigpio.3 index 79dd075..786e5f7 100644 --- a/pigpio.3 +++ b/pigpio.3 @@ -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 diff --git a/pigpio.c b/pigpio.c index c3bb00e..48e0f9f 100644 --- a/pigpio.c +++ b/pigpio.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* pigpio version 22 */ +/* pigpio version 23 */ #include #include @@ -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); @@ -6088,10 +6094,11 @@ int gpioInitialise(void) { i = gpioHardwareRevision(); - if (i == 0) gpioMask = PI_DEFAULT_UPDATE_MASK_R0; - 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; + 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; gpioMaskSet = 1; } @@ -6110,6 +6117,10 @@ int gpioInitialise(void) fdMem = -1; } + param.sched_priority = sched_get_priority_max(SCHED_FIFO); + + sched_setscheduler(0, SCHED_FIFO, ¶m); + 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) diff --git a/pigpio.h b/pigpio.h index fe3a5cb..cab4513 100644 --- a/pigpio.h +++ b/pigpio.h @@ -31,7 +31,7 @@ For more information, please refer to #include #include -#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 diff --git a/pigpio.py b/pigpio.py index 0a8e60e..8210a22 100644 --- a/pigpio.py +++ b/pigpio.py @@ -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: diff --git a/pigpiod_if.3 b/pigpiod_if.3 index f82eba5..63cdab4 100644 --- a/pigpiod_if.3 +++ b/pigpiod_if.3 @@ -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. diff --git a/pigpiod_if.c b/pigpiod_if.c index 553eb40..9eddd5a 100644 --- a/pigpiod_if.c +++ b/pigpiod_if.c @@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to */ -/* PIGPIOD_IF_VERSION 10 */ +/* PIGPIOD_IF_VERSION 11 */ #include #include @@ -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);} diff --git a/pigpiod_if.h b/pigpiod_if.h index fbbae54..f80bbe7 100644 --- a/pigpiod_if.h +++ b/pigpiod_if.h @@ -30,7 +30,7 @@ For more information, please refer to #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 diff --git a/pigs.1 b/pigs.1 index 251312d..d9b2917 100644 --- a/pigs.1 +++ b/pigs.1 @@ -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 diff --git a/setup.py b/setup.py index 503b49e..32452ba 100644 --- a/setup.py +++ b/setup.py @@ -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', diff --git a/x_pigpio.c b/x_pigpio.c index 0050823..c7f1c88 100644 --- a/x_pigpio.c +++ b/x_pigpio.c @@ -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"); } diff --git a/x_pigpio.py b/x_pigpio.py index 005206e..3f0f4ac 100755 --- a/x_pigpio.py +++ b/x_pigpio.py @@ -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') diff --git a/x_pigpiod_if.c b/x_pigpiod_if.c index 7570849..8234009 100644 --- a/x_pigpiod_if.c +++ b/x_pigpiod_if.c @@ -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"); } diff --git a/x_pigs b/x_pigs index 2ecf346..a46ed26 100755 --- a/x_pigs +++ b/x_pigs @@ -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 diff --git a/x_pipe b/x_pipe index 7967345..b4aa471 100755 --- a/x_pipe +++ b/x_pipe @@ -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/pigpio read -t 1 s /dev/pigpio +read -t 1 s /dev/pigpio read -t 1 s /dev/pigpio +read -t 1 s /dev/pigpio read -t 1 s /dev/pigpio +read -t 1 s /dev/pigpio read -t 1 s /dev/pigpio read -t 1 s /dev/pigpio +read -t 1 s /dev/pigpio read -t 1 s /dev/pigpio +read -t 1 s /dev/pigpio read -t 1 s /dev/pigpio +read -t 1 s /dev/pigpio read -t 1 s