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
text/coffeescript
`#!/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')
else
# 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) ->
return