Git Product home page Git Product logo

sx127x-node-driver's Introduction

npm version npm

sx127x-driver

Node.js driver for Semtech SX1276/77/78/79 based LoRa radios.

Based on node-sx127x, built on top of @fivdi's onoff and spi-device modules.

Prerequisites

  • Linux
  • SPI hardware with driver installed and enabled
    • for raspberry pi, uncomment dtparam=spi=on in /boot/config.txt
  • Node.js

Hardware Wiring

Semtech SX1276/77/78/79 Generic Linux Raspberry Pi
VCC 3.3V 3.3V
GND GND GND
SCK SCK SCK (pin 11)
MISO MISO MISO (pin 10)
MOSI MOSI MOSI (pin 9)
NSS Chip enable/select CS0 (pin 8) or CS1 (pin 7)
NRESET GPIO pin GPIO pin
DIO0 GPIO pin GPIO pin

Installation

npm install sx127x-driver

API

Initialize

let SX127x = require('sx127x-driver');

let options = {
  // ...
};

let sx127x = new SX127x(options);

Supported options:

Name Default Description
spiBus 0 SPI bus to use
spiDevice 0 SPI chip select/enable to use
resetPin 24 GPIO pin number of reset pin
dio0Pin 25 GPIO pin number of DIO0 pin
frequency 915e6 Frequency of radio in Hz, see setFrequency for supported values (make sure your chip supports the frequency you chose)
spreadingFactor 7 Spreading factor of radio, see setSpreadingFactor for supported values (spreading factors are orthogonal, so make sure they match when trying to communicate from one chip to another)
signalBandwidth 125E3 Signal bandwidth of radio in Hz, see setSignalBandwidth for supported values
codingRate 4 / 5 Coding rate of radio, see setCodingRate for supported values
preambleLength 8 Preamble length of radio, see setPreambleLength for supported values
syncWord 0x12 Sync word of radio, see setSyncWord for supported values
txPower 17 TX power of radio, see setTxPower for supported values
crc false Enable or disable CRC usage
tempCompensationFactor false compensation factor for temperature measurements in degrees celsius (+- some degrees)
debug false enable / disable debug output
invertIqReg false inverts IQ register on call to open()

Open

Open and configure the device:

try {
  await sx127x.open();
} catch(err) {
  console.log('Failure to open device: ' + err)
}

Close

Close the device:

try {
  await sx127x.close();
} catch (err) {
  console.log('Close failure: ' + err);
  process.exit();
}

Sending data

try {
  await sx127x.write(new Buffer('hello ' + count++));
  console.log("successfully sent")
} catch (err) {
  console.log('Fail to send: ' + err);
} 

Blocking receive

try {
  let packetLength = await sx127x.receiveSingle();
  if (packetLength > 0) {
    let incoming = "";

    while (await sx127x.available()) {
      incoming += String.fromCharCode(await sx127x.read());
    }
  }
} catch (err) {
  console.log('Fail to receive: ' + err);
}

Interrupt receive

try {
   await sx127x.open();
   await sx127x.setContinuousReceiveMode();
} catch(err) {
   console.log('Fail to put into continuous receive mode: ' + err)
}

sx127x.on('data', function(data, rssi, snr) {
   console.log('data: ' +  data.toString() + ", rssi: " + rssi);
});

Sleep mode

Put the radio in sleep mode.

try {
  await sx127x.sleep();
} catch (err) {
  console.log('Fail to put into sleep mode: ' + err);
}

Stand by mode

Put the radio in stand by mode.

try {
  await sx127x.standBy();
} catch (err) {
  console.log('Fail to put into stand by: ' + err);
}

Radio parameters

TX Power

Change the TX power of the radio.

try {
  await sx127x.setTxPower(txPower);
} catch (err) {
  console.log(err);
}
  • txPower - TX power in dB, defaults to 17

Supported values are between 2 and 17.

Frequency

Change the frequency of the radio.

try {
  await sx127x.setFrequency(frequency);
} catch (err) {
  console.log(err);
}
  • frequency - frequency in Hz (433E6, 866E6, 915E6)

Spreading Factor

Change the spreading factor of the radio.

try {
  await sx127x.setSpreadingFactor(spreadingFactor);
} catch (err) {
  console.log(err);
}
  • spreadingFactor - spreading factor, defaults to 7

Supported values are between 6 and 12. If a spreading factor of 6 is set, implicit header mode must be used to transmit and receive packets.

Signal Bandwidth

Change the signal bandwidth of the radio.

try {
  await sx127x.setSignalBandwidth(signalBandwidth);
} catch (err) {
  console.log(err);
}
  • signalBandwidth - signal bandwidth in Hz, defaults to 125E3.

Supported values are 7.8E3, 10.4E3, 15.6E3, 20.8E3, 31.25E3, 41.7E3, 62.5E3, 125E3, 250E3 and 500E3.

Coding Rate

Change the coding rate of the radio.

try {
  await sx127x.setCodingRate(codingRate);
} catch (err) {
  console.log(err);
}
  • codingRate - coding rate, defaults to 4/5

Supported values are 4/5, 4/6, 4/7 and 4/8.

Preamble Length

Change the preamble length of the radio.

try {
  await sx127x.setPreambleLength(preambleLength);
} catch (err) {
  console.log(err);
}
  • preambleLength - preamble length in symbols, defaults to 8

Supported values are between 6 and 65535.

Sync Word

Change the sync word of the radio.

try {
  await sx127x.setSyncWord(syncWord);
} catch (err) {
  console.log(err);
}
  • syncWord - byte value to use as the sync word, defaults to 0x34

CRC

Enable or disable CRC usage, by default a CRC is not used.

try {
  await sx127x.setCrc(crc);
} catch (err) {
  console.log(err);
}
  • crc - true to enable CRC, false to disable

Other functions

Random

Generate a random byte, based on the Wideband RSSI measurement.

try {
  let random = await sx127x.readRandom(crc);
} catch (err) {
  console.log(err);
}

Examples

See examples folder.

License

This library is licensed under the MIT Licence.

sx127x-node-driver's People

Contributors

sandeepmistry avatar xtrinch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

sx127x-node-driver's Issues

Error on sx127x.open()

I just installed the package on RasPi B v1.2

When testing the examples I get the following in sender.js I believe the first error is being thrown on _spiOpen and when _spi.transfer is being called, it throws the next error.

Any suggestions for troubleshooting this error?

{ [Error: ENOENT, No such file or directory] errno: 2, code: 'ENOENT', syscall: 'open' }
Debug sx127x: Sending: hello 0
Error: Spi not defined
at SX127x._readRegister (/home/pi/sx127x-node-driver/lib/sx127x.js:472:11)
at SX127x.write (/home/pi/sx127x-node-driver/lib/sx127x.js:427:36)
at send (/home/pi/sx127x-node-driver/examples/sender.js:29:17)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:6870) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.

Allowing DIO pin number 0

There are a number of devices (e.g. FrendlyARM NanoPi NEO) where there is a valid GPIO number of 0. We have found that passing 0 as an option to at least the resetPin it does not register, because:

this._resetPin = options.resetPin || 24;

will resolve to 24. It may be better to use options.hasOwnProperty('resetPin') to determine whether present in the options passed to the constructor, rather than || with a default.

setCodingRate logic incorrect

Hello,
I raised this on node-sx127x a few years back and is the same issue here. The logic to determine coding rate is incorrect, it should be:

if (cr <= (4/8)) { denominator = 8; } else if (cr <= (4/7)) { denominator = 7; } else if (cr <= (4/6)) { denominator = 6; } else { denominator = 5; }

ERR_INVALID_ARG_TYPE

(node:2612) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received type number (6)
at Object.writeFileSync (fs.js:1517:5)
at exportGpio (/root/project/node_modules/sx127x-driver/node_modules/onoff/onoff.js:18:8)
at new Gpio (/root/project/node_modules/sx127x-driver/node_modules/onoff/onoff.js:172:36)
at SX127x.open (/root/project/node_modules/sx127x-driver/lib/sx127x.js:110:20)
at run (/root/project/lora.js:15:22)
at Object. (/root/project/lora.js:21:1)
at Module._compile (internal/modules/cjs/loader.js:1072:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
at Module.load (internal/modules/cjs/loader.js:937:32)
at Function.Module._load (internal/modules/cjs/loader.js:778:12)
(Use node --trace-warnings ... to show where the warning was created)
(node:2612) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:2612) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

const SX127x = require('sx127x-driver');

const sx127x = new SX127x({
    frequency: 433E6,
    dio0Pin: 6,
    resetPin: 13,
    spreadingFactor: 7,
    signalBandwidth: 125E3,
    codingRate: 4 / 5,
    preambleLength: 10,
    txPower: 20,
});

const run = async () => {
        await sx127x.open();
        await sx127x.write(Buffer.from("This is a test"));
        console.log("successfully sent");
        await sx127x.close();
};

run().then(r => {});
node -v
v14.17.4
npm -v
7.20.3

Bandwidth - supported value readme addition

Actually also supports 500E3 and the code has been checked, so the text following needs it added:
Supported values are 7.8E3, 10.4E3, 15.6E3, 20.8E3, 31.25E3, 41.7E3, 62.5E3, 125E3, and 250E3.

install error

─>$ yarn add sx127x-driver                                                                                                                                                             master ✖ ✱ ◼
yarn add v1.22.15
info No lockfile found.
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
[-/4] ⠈ waiting...
[2/4] ⠈ spi-device
[-/4] ⠈ waiting...
error /home/lei/github/lora_gateway/node_modules/sx127x-driver/node_modules/spi-device: Command failed.
Exit code: 1
Command: node-gyp rebuild
Arguments: 
Directory: /home/lei/github/lora_gateway/node_modules/sx127x-driver/node_modules/spi-device
Output:
gyp info it worked if it ends with ok
gyp info using [email protected]
gyp info using [email protected] | linux | x64
gyp info find Python using Python version 3.9.7 found at "/usr/bin/python3"
gyp info spawn /usr/bin/python3
gyp info spawn args [
gyp info spawn args   '/usr/lib/node_modules/node-gyp/gyp/gyp_main.py',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'make',
gyp info spawn args   '-I',
gyp info spawn args   '/home/lei/github/lora_gateway/node_modules/sx127x-driver/node_modules/spi-device/build/config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/usr/lib/node_modules/node-gyp/addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/home/lei/.cache/node-gyp/16.11.1/include/node/common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=/home/lei/.cache/node-gyp/16.11.1',
gyp info spawn args   '-Dnode_gyp_dir=/usr/lib/node_modules/node-gyp',
gyp info spawn args   '-Dnode_lib_file=/home/lei/.cache/node-gyp/16.11.1/<(target_arch)/node.lib',
gyp info spawn args   '-Dmodule_root_dir=/home/lei/github/lora_gateway/node_modules/sx127x-driver/node_modules/spi-device',
gyp info spawn args   '-Dnode_engine=v8',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--no-parallel',
gyp info spawn args   '--generator-output',
gyp info spawn args   'build',
gyp info spawn args   '-Goutput_dir=.'
gyp info spawn args ]
gyp info spawn make
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
make: 进入目录“/home/lei/github/lora_gateway/node_modules/sx127x-driver/node_modules/spi-device/build”
  CXX(target) Release/obj.target/spi/src/spi.o
  CXX(target) Release/obj.target/spi/src/spidevice.o
  CXX(target) Release/obj.target/spi/src/open.o
  CXX(target) Release/obj.target/spi/src/close.o
  CXX(target) Release/obj.target/spi/src/transfer.o
  CXX(target) Release/obj.target/spi/src/getoptions.o
In file included from ../../../../nan/nan.h:292,
                 from ../src/getoptions.cc:4:
../../../../nan/nan_new.h: In instantiation of ‘typename Nan::imp::Factory<T>::return_t Nan::New(A0) [with T = v8::Uint32; A0 = long unsigned int; typename Nan::imp::Factory<T>::return_t = v8::Local<v8::Uint32>]’:
../src/getoptions.cc:35:25:   required from here
../../../../nan/nan_new.h:208:30: 错误:对重载的‘New(long unsigned int&)’的调用有歧义
  208 |   return imp::Factory<T>::New(arg0);
      |          ~~~~~~~~~~~~~~~~~~~~^~~~~~
In file included from ../../../../nan/nan_new.h:189,
                 from ../../../../nan/nan.h:292,
                 from ../src/getoptions.cc:4:
../../../../nan/nan_implementation_12_inl.h:177:1: 附注:candidate: ‘static Nan::imp::FactoryBase<v8::Uint32>::return_t Nan::imp::Factory<v8::Uint32>::New(int32_t)’
  177 | Factory<v8::Uint32>::New(int32_t value) {
      | ^~~~~~~~~~~~~~~~~~~
../../../../nan/nan_implementation_12_inl.h:183:1: 附注:candidate: ‘static Nan::imp::FactoryBase<v8::Uint32>::return_t Nan::imp::Factory<v8::Uint32>::New(uint32_t)’
  183 | Factory<v8::Uint32>::New(uint32_t value) {
      | ^~~~~~~~~~~~~~~~~~~
make: *** [spi.target.mk:119:Release/obj.target/spi/src/getoptions.o] 错误 1
make: 离开目录“/home/lei/github/lora_gateway/node_modules/sx127x-driver/node_modules/spi-device/build”
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/lib/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (node:events:390:28)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
gyp ERR! System Linux 5.14.12-arch1-1
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/lei/github/lora_gateway/node_modules/sx127x-driver/node_modules/spi-device
gyp ERR! node -v v16.11.1

Support for RX IQ inversion

For public LoRaWAN networks like TTN, it is standard practice to invert the receive LoRa I/Q (effectively stopping end devices communicating with each other directly). It would be good if this could be added (potentially as an option but we have currently added it into open):

var REG_INVERT_IQ = 0x33;

and

SX127x.prototype.open = async function()
{
...
await this.sleep();
let regInvertIQ = await this._readRegister(REG_INVERT_IQ);
regInvertIQ |= 0x40;
await this._writeRegister(REG_INVERT_IQ, regInvertIQ);

This has been tested and works well with a sx1276 device.

Cheers
Rob

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.