natevw / node-nrf

Pure-JavaScript nRF24L01 driver library
117 stars 31 forks source link

node-nrf

nRF24L01+ driver library for node.js on platforms like the Raspberry Pi and others.

Making this inexpensive radio chip easy to use from node.js helps bridge the wider Internet with small/cheap "things" — other embedded devices like Arduino, Teensy, good ol'fashioned AVR chips, … — where the costs of WiFi/Bluetooth/Zigbee radios can quickly add up! This fulfills a critical dependency of my Microstates idea, for just one example.

See also?

Not to be confused with node-rf24 which was/is an unfinished (and broken by recent V8 and libuv changes) wrapper around the RasPi port of the C++ RF24 library.

In contrast, this module is implemented in pure JavaScript on top of native SPI bindings. It also provides a cleaner, node-friendly interface.

Installation

npm install nrf

Usage

Streams!

var radio = require('nrf').connect(spiDev, cePin, irqPin);
radio.channel(0x4c).dataRate('1Mbps').crcBytes(2).autoRetransmit({count:15, delay:4000});
radio.begin(function () {
    var rx = radio.openPipe('rx', 0xF0F0F0F0E1),
        tx = radio.openPipe('tx', 0xF0F0F0F0D2);
    rx.pipe(tx);        // echo back everything
});

The nRF24L01+ radios provide "logic pipes" which can be used as node.js streams. These are opened for a given receiver address according to their primary direction. However, since the transceiver hardware supports sending data payloads with its acknowlegement packets, the both primary directions provide duplex streams — acknowlegement payload data can be read from a 'tx' stream if the ackPayloads option is set true, and written to any 'rx' stream.

TBD: expand this section ["non"-stream usage, pipe options, optional callbacks, buffering and splitting/joining streams from 32-byte chunks, etc.]

API

Initialization

Transceiver configuration

Sending/receiving

Pipe details

The nRF24 radios use "logical channels" for communications within a physical channel. Basically a pipe address is sent ahead of every data transmission on a particular channel (frequency); a receiver of the "same pipe" listens for this address and upon detecting a match attempts to process the data packet which follows. The transceiver hardware can be configured for automatic acknowlegdment/retransmission of received/unacknowleged packets (respectively). The radio.openPipe(mode, addr, opts) method returns a standard node.js Duplex stream interface wrapping these hardware features.

Note that, while you can .pipe() to these streams as any other, node-nrf will not split data into packets for you, and will get upset if passed more than 32 bytes of data! Make sure all your writes to the stream fit the necessary MTU; TBD I imagine the common "transfer an arbitrarily large stream of data" case could be handled by a simple [object mode?] transform stream, find or provide a recommended module.

Low-level methods

Effective use of these methods requires proficiency with both the library internals and the transceiver's data sheet documentation. They are exposed only because What's The Worst That Could Happen™.

TBD: radio.execCommand(cmd,data,cb) / radio.getStates(list,cb) / radio.setStates(vals, cb) / radio.setCE(state, block) / radio.pulseCE(block) / radio.reset(states, cb) / radio.blockMicroseconds(us) / radio.readPayload(opts, cb) / radio.sendPayload(data, opts, cb)

Troubleshooting

node-nrf (or pi-spi) not working after using C++ RF24 library

The C++ RF24 library for RasPi toggles the SPI chip select pin manually, which breaks the Linux SPI driver. Reload it to fix, before using node-nrf:

sudo modprobe -r spi_bcm2708
sudo modprobe spi_bcm2708

or

sudo modprobe -r spi_bcm2835
sudo modprobe spi_bcm2835

See this comment for a bit more discussion.

TBD: gather more advice (or link to a wiki page?)

License

TBD: [BSD-2-Clause template]