• Stars
    star
    117
  • Rank 301,828 (Top 6 %)
  • Language
    JavaScript
  • Created about 11 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pure-JavaScript nRF24L01 driver library

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

  • var radio = nrf.connect(spiDev, cePin, irqPin) — Initialize a radio object using the given hardware pinouts. Under Linux, spiDev is a device like "/dev/spidev0.0" and must be accessible by your process's user. cePin and irqPin are GPIO port numbers (irqPin is optional but highly recommended — without it the library must resort to polling which is slower and more processor/power intensive) and these GPIO ports must also be accessible by your process's user. This does essentially no communication with (and no configuration of) the radio; use the configuration methods below and radio.begin() to set up.

  • radio.reset(cb) — Resets the transciever to its default settings and flushes its transmit/receive queues. Most of this (i.e. queue flushing and low-level settings) is done by .begin() and so calling reset is not necessary if the five transceiver configuration options below (channel/dataRate/transmitPower/crcBytes/autoRetransmit) are being written anyway.

Transceiver configuration

  • radio.channel(num, cb) — Set (or read, when no value is provided) the radio frequency channel. Callback is optional. This must be the same on all transceivers that wish to communicate. Default is 0x02.

  • radio.dataRate(rate, cb) — Set (or read, when no value is provided) the channel data rate. Callback is optional. This must be the same on all transeivers that wish to communicate. Must be one of ['250kbps', '1Mbps','2Mbps']. Default is '2Mbps'.

  • radio.transmitPower(rate, cb) — Set (or read, when no value is provided) the RF output power. Callback is optional. Must be one of ['PA_MIN', 'PA_LOW', 'PA_HIGH', 'PA_MAX']. Default is 'PA_MAX'.

  • radio.crcBytes(numBytes, cb) — Set (or read, when no rate is provided) the size of packet checksums. Callback is optional. This must be the same on all transeivers that wish to communicate. Choose 1 or 2 bytes, or 0 to disable CRC checksums. Default is 1.

  • radio.autoRetransmit(opts, cb) — Set (or read, when no value is provided) the packet retransmission parameters. Callback is optional. Provide a dictionary with one or two keys: delay to set the retry spacing in microseconds (will be rounded to a multiple of 250µs) and count to set the maximum number of retries. (See the datasheet for the minimum delay necessary based on data rate and packet size.) Default is {delay:250,count:3}.

Sending/receiving

  • radio.begin(cb) — Powers up the radio, configures its pipes, and prepares the library to handle actual payload transmission/receipt. Callback is optional, but if not provided you should not attempt to open pipes until the 'ready' event is emitted. (The configuration methods above may be called at any time before/after this method.)

  • radio.openPipe(mode, addr, opts) — Returns a stream representing a "data pipe" on the radio. See pipe details section below.

  • radio.end(cb) — Closes all pipes and powers down the radio. Callback is optional.

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.

  • The mode parameter to radio.openPipe must be 'tx' or 'rx' and determines the primary behavior of the radio data pipe. Because acknowlegement packets can include arbitary payloads, a data pipe of either mode can be used for both receiving and sending. The main difference is that an 'rx' pipe is always listening, but can only send data in acknowlegement to incoming packets; conversely [inversely? contrapositively?] a 'tx' pipe can only receive a single packet of data (sent within a brief window) after each of its own successful transmissions. (See options documentation below.)

  • The addr parameter is simply the aforementioned address of the data pipe, usually as a 5 byte buffer. As a shorthand, you can also pass raw numbers e.g. 0xEF for addresses, but note that the most significant nibble must have bit(s) set for this to work as expected — a literal 0x0000000A in your source code will get processed as the invalid Buffer("a", 'hex') rather than a 3-byte address.

  • For 'rx' mode pipes things are a little more complicated. The nRF24 chip supports listening simultaneously for up to 6 data channel pipes, but four of these logical channel address assignments must differ in only one byte from the first address. Also, the sixth address slot will be temporarily "borrowed" whenever any 'tx'-mode pipe needs to listen for an acknowlegement packet. Basically for 'rx' pipes, pass a 3, 4 or 5 byte Buffer the first time you call it, and it will be assigned a hardware pipe number automatically. Subsequent calls should ideally be single-byte Buffers only, representing the least significant byte in the address of up to four more pipes. If you open another pipe with a 3/4/5-byte address instead (or additionally), be aware that you may miss packets in certain situations. For example if you first open a pipe with address 0x123456, you could also listen for 0x57through 0x5A. You could also open one last 'rx' pipe with address 0x998877 — but if there were open 'tx' pipes as well, and any of them needed to listen for acknowlegements, you could end up occasionally missing transmissions to this sixth address. [TBD diagram of "slots"?]

  • Finally, via the opts parameter you can set a fixed payload size (in bytes, defaults to 'auto') or disable auto-acknowlegement with autoAck:false (defaults to true). Note that if you want to disable auto-acknowlegment, you must also set a payload size — for some reason these are linked in the nRF24 feature set.

  • For 'tx' pipes, the opts parameter also lets you provide individual retryCount, retryDelay, txPower options instead of using the radio.autoRetransmit and radio.transmitPower methods; if you do this you should provide values for every 'tx' pipe you open, to make sure the hardware configuration gets updated between each different transmission. [TBD: what is ackPayloads option supposed to do for `'tx`` pipes?]

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â„¢.

  • radio.powerUp(boolState, cb) — Set (or read, when no value is provided) the power status of the radio. Callback is optional. When the power is off the transceiver hardware uses little power, but takes a little while longer to enter any useful mode. This is set true by radio.begin() and false by radio.end() so it is typically not necessary when using the main API. Default is false.

  • radio.addressWidth(width, cb) — Set (or read, when no value is provided) the receiver address width used. Callback is optional. The address width is determined automatically whenever radio.openPipe() is used so it is not normally necessary to call this when using the main API. Choose 3, 4 or 5 bytes (this library also supports setting 2, at your own risk). Default is 5.

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]

More Repositories

1

fermata

Succinct native REST client, for client-side web apps and node.js. Turns URLs into (optionally: magic!) JavaScript objects.
JavaScript
329
star
2

PeerPouch

PouchDB over WebRTC
JavaScript
194
star
3

pi-spi

Simple RasPi SPI library (node.js)
C++
93
star
4

ipcalf

Gives back your public IP address in plain HTML, plain text, and JSON (w/CORS!)
HTML
72
star
5

fatfs

Standalone FAT16/FAT32 filesystem implementation in JavaScript
JavaScript
47
star
6

evel

[attempt at] safe eval of untrusted JavaScript source code in the browser.
JavaScript
33
star
7

struct-fu

Yet another node.js struct implementation (object↔︎buffer conversion)
JavaScript
27
star
8

ShutterStem

Open, decentralized photo repository based on CouchDB
JavaScript
27
star
9

sendfile

Share files directly with clients/friends/family using PeerPouch (WebRTC).
JavaScript
19
star
10

flatstache.js

Tiny library to expand flat Mustache.js templates (no sections/partials/etc.)
JavaScript
18
star
11

node-chargify

Simple wrapper around Chargify's REST API for node.js
JavaScript
17
star
12

pi-pins

Node.js module for controlling GPIO (with interrupts) for embedded Linux machines like Raspberry Pi and BeagleBone
JavaScript
14
star
13

LocLog

Location logging in CouchDB
JavaScript
13
star
14

node-rf24

Control nRF24L01+ wireless radio communications from a server with SPI/GPIO ports
C++
12
star
15

OpenLayers-Multitouch

Drop-in patch for better Multitouch and scrollwheel support in OpenLayers 2.10
JavaScript
12
star
16

sdcard

Tessel library for the SD card module.
JavaScript
11
star
17

greenhouse

Aquaponics monitoring and on-demand/remote-control fish feeder
Arduino
11
star
18

Metakaolin

Metakaolin is a commonly used starting material for laboratory synthesis of geopolymers.
JavaScript
10
star
19

microstates

REST for the wicking (i.e. garden beds. and the greenhouse, and the refrigerator and the stupid suburban lawn…)
10
star
20

wristmap

Maps on Pebble
JavaScript
9
star
21

gather-stream

Pipe a node.js stream into a buffer (with memory limit, error handling)
JavaScript
8
star
22

putdoc

Upload CouchDB design documents (from traditional couchapp format)
JavaScript
8
star
23

Glob

Barebones blog (CouchDB application)
JavaScript
6
star
24

js-cnc

JavaScript-based CNC controller (primarily intended to send send G-code to Grbl)
HTML
4
star
25

grbl-parallel

An Arduino shield for connecting Grbl to a YooCNC Mach3-style parallel port-based driver
Eagle
4
star
26

World-Wide-WebGL-map-demo

A demonstration of using WebGL to do web-based cartographic drawing on the GPU.
JavaScript
4
star
27

touch-test

Displays which touch and pointer events a mobile or desktop browser provides to HTML5 web apps
3
star
28

RQMS

Relaxed Queue Management System: simple low-latency Node.js job/message distribution manager using CouchDB for reliable persistence
JavaScript
3
star
29

tessel-cloudtester

JavaScript
3
star
30

jsblock

Chrome extension to block certain annoying/tracking scripts (Google Analytics, Tynt, Snap, Intellitxt…)
JavaScript
2
star
31

noscript-dropbox

An extremely rudimentary CouchDB form-based (no JavaScript) uploader, compatible with Netscape Navigator 4.05
JavaScript
2
star
32

twas

It was a dark and…
JavaScript
2
star
33

fermata-couchdb

CouchDB helpers for Fermata
JavaScript
1
star
34

TreeIO

Low-level library for manipulating append-only tree files
1
star
35

ddoc

Load functions from a local CouchApp into your node.js
JavaScript
1
star
36

rooflux

Logging/livestreaming of my solar PV inverter levels
JavaScript
1
star
37

GLRenderToTextureDemo

Objective-C
1
star
38

luseragent

How humans talk about their browsers.
JavaScript
1
star
39

halfstache.js

TODO
1
star
40

makerland-radio

Materials for Radio Workshop at Maker Land 2016
1
star
41

hanfordfriday

For all your Hanford Friday needs.
JavaScript
1
star
42

fishgoblub

Grabs images from an Eye-Fi and puts them into CouchDB.
JavaScript
1
star
43

PuSH-suite

PubSubHubbub v0.4 test suite
JavaScript
1
star
44

simplify-user-agent

User Agent helper library: simplify browser UA strings, match results using custom criteria
JavaScript
1
star
45

loading-docs

[wip]
JavaScript
1
star