UNPKG

pigpio-client

Version:

A nodejs client for pigpio socket interface.

88 lines (59 loc) 7.78 kB
<h1>PIGPIO Client</h1> <p>Pigpio client uses the pigpiod socket interface running on a remote or localhost Raspberry Pi to control its GPIO pins. For the underlying detail of the pigpio socket interface see http://abyz.co.uk/rpi/pigpio/sif.html</p> <h3>Usage</h3> <pre><code>const PigpioClient = require(&#39;pigpio-client&#39;); const myPi = new PigpioClient.pigpio({host:&#39;localhost&#39;, port:8888}); const myPin = myPi.gpio(25); myPin.modeset(&#39;input&#39;); // no callback var pinLevel; myPin.read((err,val)=&gt;{ // read callback executes after modeSet if (err) errorHandler(err); else pinLevel = val; }); // get notifications on GPIO25 myPin.notify((buf)=&gt; { //buf is Buffer object containing 16-bit sequence, 16-bit flags, 32-bit tick, 32-bit level }); // you should monitor for errors myPi.on(&#39;error&#39;, (err)=&gt; { console.log(err.message); // or err.stack });</code></pre> <p>Most pigpio-client methods are asynchronous and accept an optional callback function. Asynchronous methods called without providing a callback function will emit &#39;error&#39; if a pigpio exeception is raised. The application must supply an &#39;error&#39; event handler in such cases. Arguments to callback are: <em>(err, res, ...ext)</em>.</p> <p>By default, network request and response to/from pigiod are ordered allowing pigpio commands to be sent back- to-back without a callback (see usage example above). Network socket requests can be pipelined, with the pipelining property set to true in the constructor, but now the application must assure responses are received in the corret order - usually done by chaining callbacks.</p> <h3>Constructor</h3> <p><strong>pigpioClient({host: &#39;192.168.1.12&#39;, port: 8765, pipelining: true})</strong>:</p> <p>Constructs a pigpio Client connected to 192.168.1.12:8765 with pipelining enabled. Defaults are host=localhost, port=8888, pipelining=false. On success, returns pigpio client object.</p> <h2>Methods</h2> <p><strong>pi.getInfo()</strong> Returns useful information about rpi hardware and pigpiod.<br/><strong>pi.getCurrentTick(cb)</strong><br/><strong>pi.readBank1(cb)</strong><br/><strong>pi.end(cb)</strong> Ends communications on command and notifications socket. Callback issued after &#39;close&#39; event is received from both sockets.<br/><strong>pi.destroy()</strong> Runs socket.destroy() on both network sockets. Todo: other cleanup.<br/><strong>pi.gpio(gpio_pin)</strong> Construct a gpio object referring to gpio_pin.</p> <p><strong>gpio.modeSet(mode, cb)</strong> Set mode of gpio to &#39;in[put]&#39; or &#39;out[put]&#39;.<br/><strong>gpio.modeGet(cb)</strong> Returns the mode of gpio as argument to callback.<br/><strong>gpio.pullUpDown(pud, cb)</strong> Sets the pullup or pulldown resistor for gpio.<br/><strong>gpio.read(cb))</strong> Returns the gpio level as argument to callback.<br/><strong>gpio.write(level, cb)</strong> Set the gpio level.<br/><strong>gpio.analogWrite(dutyCycle, cb)</strong> </p> <p><strong>gpio.waveClear(cb)</strong> clear all waveforms (wave IDs are all reset).<br/><strong>gpio.waveCreate(cb)</strong> Returns a wave id of waveform created from previous calls to waveAddPulse(). Wave ID is the argument of callback.<br/><strong>gpio.waveBusy(cb)</strong> Returns 1 if true, 0 if false, &lt;0 if error.<br/><strong>gpio.waveNotBusy(interval, cb)</strong> Executes callback when waveform ends. Polls at interval msec or 25msec if not specified.<br/><em>Note, this is a global indication of waveform generation. Not specific to gpio!</em><br/><strong>gpio.waveAddPulse([Pulse_t], cb)</strong> Add array of <em>Pulse_t</em> to gpio of current waveform. <em>Pulse_t</em> is [gpioOn, gpioOff, delay]<br/><strong>gpio.waveChainTx([wids], {loop:x, delay:y})</strong> Transmit a chain of wids. Options object specifies loop and delay (between loop) values.<br/><em>Note: waveClear, waveCreate and waveBusy are not gpio specific. These methods are made available to the gpio object for convenience and as a reminder that only a single waveform can be active.</em> <strong>(Is this true?)</strong><br/><strong>gpio.waveSendSync(wid, cb)</strong> Synchronizes the wave id to the currently active waveform.<br/><strong>gpio.waveSendOnce(wid, cb)</strong> Delete this wave id. Note: Bad things can happen if wid is currently active.<br/><strong>gpio.waveTxAt(cb)</strong> Return currently active wave id, no wave being transmitted (9999) or wave not found (9998).<br/><strong>gpio.waveDelete(wid, cb)</strong> Delete the wave id.</p> <h3>Notifications</h3> <p>The pigpio-client object automatically opens a second connection to pigpiod for notifications on gpio pins. This is done by issuing the &#39;NOIB&#39; (notification open in-band) command to the command socket.</p> <p><strong>pi.startNotifications(bits, cb)</strong><br/><strong>pi.pauseNotifications(cb)</strong><br/><strong>pi.stopNotifications(id)</strong> </p> <p><strong>gpio.notify(callback)</strong> Registers a notification callback for this gpio. Callback is called whenever the gpio state changes. Callback arguments are <em>level</em> and <em>tick</em> where <em>tick</em> represents the system&#39;s time since boot.<br/><strong>gpio.endNotify()</strong> Unregisters the notification on gpio. For convenience, a null <em>tick</em> value is sent. Useful for stream objects that wrap the notifier callback. </p> <h3>Bit_Bang_Serial Methods</h3> <p><strong>gpio.serialReadOpen(baudRate, dataBits, cb)</strong> <br/><strong>gpio.serialRead(count, cb)</strong> Callback returns (err,len,array)<br/><strong>gpio.serialReadClose(cb)</strong><br/><strong>gpio.serialReadInvert(mode, cb)</strong> Mode is &#39;invert&#39; || &#39;normal&#39;.<br/><strong>waveAddSerial(baud,bits,delay,data,cb)</strong> </p> <h3>Serialport</h3> <p><strong>pi.serialport(rx,,tx,dtr)</strong> Construct serial port using gpio pins rx,tx,dtr.<br/><strong>serialport.open(baudrate,databits,cb)</strong> Callback arg is null if sucessful, error message otherwise.<br/><strong>serialport.read(cb)</strong> Callback arg is null if no data available, else buffer object.<br/><strong>serialport.write(data)</strong> Data is string or buffer or array.<br/><strong>serialport.close(cb)</strong> Close serialport.<br/><strong>serialport.end(cb)</strong> Close bb<em>serial</em>read, disable outputs and undef serialport. </p> <h3>Bugs</h3> <ul><li>waveChainTx will fail if widArray is odd length!, see fixme comment</li></ul> <h3>Todo</h3> <ul><li>Implement error codes decoder.</li><li>How to keep request as a private method?</li><li>Simplify callback arguments to just err, res instead of err, res, ...len. Res may be scalar or array.</li><li>Notifications socket: check for notification errors response (res[3])? See pigpio python code.</li><li>test for callback queue underflow?</li><li>Use waveSendSync in serialport.write to improve performance.</li><li>Make serialport.read similar to readable.read api</li><li>Add true flow control and modem support to serialport.read</li></ul> <h3>Ideas</h3> <ul><li>Waveforms should be accessible through a lock to gpio objects exclusive access during waveform creation/initialization, building or deletion.</li><li>gpio objects keep track of their wave ids and delete them when gpio.end(). Avoids global clear waves.</li><li>use gpio.waveTxAt to determine if another gpio wave is active (not in set of owned wave ids).</li><li>keep track of gpio in use/avaiable, prevent overlapping gpio objects.</li></ul> <h4>Running pigpiod with permissions</h4> <pre><code>$ sudo pigiod -s 1 # 1 microsecond sampling\ -f # disable local pipe interface (ie pigs)\ -n 10.0.0.13 # only allow host from my secure subnet</code></pre>