UNPKG

nixfilter-rpi-gpio

Version:

Filter for sending binary signal sequences via the GPIO pin of a Raspberry Pi

71 lines (58 loc) 2.68 kB
`#!/usr/bin/env node 'use strict'` # Require the "nixfilter" module nixfilter = require('nixfilter') # Import/Require the "nixfilter-logicsignal" module nixfilter_logicsignal = require('nixfilter-logicsignal') # Import/Require the "rpio" module rpio = require('rpio') # Define the filter and register it on the module nixfilter.filter module, description: 'Send logic/binary signals via a GPIO pin of a Raspberry Pi. The logic/binary signals are read as lines from STDIN, as comma-separated integer values representing durations in nanoseconds. Negative values indicate "inactive"/"low" levels, positive values indicate "active"/"high" levels. For example, the input line "360000,-1080000,+1080000,360000" would output a binary signal of 360µs "high" level, followed by 1080µs "low" level, followed by 1080µs "high" level, followed by 360µs "low" level.' input_reader: nixfilter_logicsignal.reader.logic_signal() output_writer: null add_arguments: (argument_parser) -> argument_parser.addArgument ['--latency', '-l'], type: 'int' defaultValue: 65 help: 'The latency overhead (in microseconds) for every signal. This depends on the Raspberry Pi being used; on the Raspberry Pi 3B+, this is about 65. (default: 65)' argument_parser.addArgument ['--inactive_state', '-i'], choices: ['low', 'high'] defaultValue: 'low' help: 'The GPIO pin\'s inactive state, if no signal is being sent (default: low)' argument_parser.addArgument ['gpio_pin_id'], type: 'int' help: 'The numerical ID of the GPIO pin to use for outputting the signals' return setup: (args) -> if (@args.inactive_state is 'low') @inactive_state = rpio.LOW @active_state = rpio.HIGH else @inactive_state = rpio.HIGH @active_state = rpio.LOW # Set the GPIO pin to its "inactive" state and open it rpio.open(@args.gpio_pin_id, rpio.OUTPUT, @inactive_state) output_timings: (signal_timings) -> # Reduce timings by latency timings = [-200] for timing in signal_timings timings.push(Math.max((Math.abs(timing // 1000) - @args.latency), 1) * (if (timing > 0) then 1 else -1)) # Setup local variables to ensure the "for" loop runs as fast as possible gpio_pin_id = @args.gpio_pin_id inactive_state = @inactive_state active_state = @active_state # Output the signal for timing in timings if (timing > 0) rpio.write(gpio_pin_id, active_state) rpio.usleep(timing) else rpio.write(gpio_pin_id, inactive_state) rpio.usleep(-timing) # Set the GPIO pin to it's "inactive" state again rpio.write(gpio_pin_id, inactive_state) return on_input: (logic_signal) -> @output_timings(logic_signal.get_timings()) return