npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@csllc/can-usb-com

v6.1.1

Published

NodeJS interface to the GridConnect CAN-USB-COM adapter

Readme

NodeJS CAN-USB-COM Module

This module provides a nodejs interface to the gridconnect CAN-USB Converter.

The module implements the device-specific serial protocol and is not compatible with any other device or adapter.

This package is published as @csllc/can-usb-com. It was forked from the unscoped can-usb-com package (version 5.x and earlier), which uses serialport 9 and does not work on current NodeJS versions.

The module communicates with the adapter through serialport, which supports Windows, macOS and Linux. NodeJS 20 or later is required, and Node 24 or later is recommended.

Getting Started

The following assumes that NodeJS is already installed. To install this module, use

npm install @csllc/can-usb-com

The usb device appears as a serial port; depending on your platform you may or may not need to install drivers. If a serial port does not appear when you plug in the board, refer to the board installation documents and/or download drivers from https://gridconnect.com/usb-can-interface.html and correct the problem. Note: on Windows, connecting the can-usb-com may cause the mouse to act erratically. To correct this, go to Device Manager, Ports, and choose the COM port that represents the CAN-USB-COM device. Under Properties | Advanced, there is a checkbox called 'Serial Enumerator'. Uncheck that box and the problem will go away.

Simple script to use the board (change the COM port number as required):

const Can = require('@csllc/can-usb-com');

// Use default settings (do not filter messages)
let board = new Can();


// Handle each incoming message
board.on('data', function( msg ) {
  console.log( 'Msg: ', msg.id.toString(16), msg.ext, msg.buf );
});

// Open the com port and configure...
board.open( 'COM3' )

.then( function() {

  console.log('Listening....');

  // listen for 5 seconds, then end the script
  setTimeout( function() {
    board.close();
    process.exit(0); 
  }, 5000 );

  // send an extended (29-bit ID) message with some data.
  board.write( { id: 0x10EF8001, ext: true, buf: [0x49, 0x2B, 0x06, 0x00, 0x02] });

})
.catch( function( err ) {
  // If anything goes wrong, report the error and exit
  console.error( err );
  board.close();
  process.exit(-1);
});

Streaming

The CAN-USB-COM extends the NodeJS stream interface, so it can be piped to other stream instances. See basic.test.js in the test folder.

Examples

Several complete examples can be found in the example folder.

Configuration

The constructor accepts an object that specifies the desired configuration. The board/ports are set up before the 'open' command resolves (so once the open operation is complete, the CAN interface is ready to use).

The options are as shown in the following example (if you are happy with the option, you can omit it from the options object and the default will be used).

let board = new Can({

  // Serial port baud rate
  baudRate: 115200,

  // bit rate on the CAN bus
  canRate: 250000,

  // typical CAN sample point
  samplePoint: 75,

  // filters for incoming packets
  filters: [
  ],

  // useful for testing, each sent packet is also received
  loopback: false,
  });

Filters

By default, all CAN packets are captured. You can limit the number of incoming frames by using filters. They are specified as an array of up to 10 filter definitions. A filter has these fields:

{
  // true if the filter applies to 29-bit CAN IDs
  ext: true,

  // The ID to accept.  May also be specified as a range:
  // for example '10FF1100 10FF11FF'
  id: '10FF1122'
}

Events

The board object emits the following events:

  • open when the serial port is successfully opened
  • error if an error occurs (like the serial port could not be opened)
  • data when an incoming CANBUS frame is received
  • write when an outgoing CANBUS frame is sent to the device (the event occurs before the frame is actually put on the wire)
  • status when the status of the port changes (see Status)
  • close when the port is closed

To listen for the events, use the typical NodeJS EventEmitter pattern:

  board.on('open', function(){
    console.log( 'Port opened');
  })

  board.on('data', function(pgn){
    console.log( pgn );
  })

  board.on('close', function(err){
    if( err && err.disconnected ) {
      console.log( 'Port Disconnected' );
    }
    else {
      console.log( 'Port Closed by application' );
    }
  })

  board.on('error', function(err){
    console.log( 'Serial Port error: ', err );
  })

API

API functions generally return Promises, which are resolved or rejected when the request is complete. Refer to NodeJS Promise documentation for details on how to chain requests together, detect errors, etc. Refer to the CAN-USB-COM protocol document for additional details on the use of the commands and valid parameter ranges.

Error Statistics

errorStats() returns a Promise that resolves with an object that has the same fields as in the other CAN adapter modules used by @csllc/cs-canbus-universal (see its documentation). The CAN-USB-COM doesn't report bus errors or the state of its CAN controller, so only these fields have values; the rest are null:

{
  since: Date,   // when counting started (when the port was opened); null if never opened
  txFrames: 0,   // frames sent
  rxFrames: 0,   // frames received
  ...
}

With loopback enabled, frames the adapter echoes back are counted as received as well as sent.

Status

status() returns a Promise that resolves with the status of the port. The object has the same fields in all of the CAN adapter modules used by @csllc/cs-canbus-universal; a field whose value is not available is null. Whenever the status changes, a status event is emitted with the new status.

{
  port: 'COM9',              // the port that is open (as passed to open()); null if closed
  connection: 'connected', // 'closed', 'connected', or 'disconnected' (the adapter stopped responding, e.g. was unplugged, while the port was open)
  state: 'error-active',   // 'error-active', 'error-warning', 'error-passive', 'bus-off', 'stopped', 'sleeping', or null
  bitrate: 250000,         // bit rate in use, in bit/s
}

state is the same as in Error Statistics, and is null unless connection is 'connected'. A port that is 'disconnected' stays that way until it is closed; isConnected() returns false for it.

can.on('status', (status) => {
  console.log(status.connection, status.state);
});

In this module:

  • The CAN-USB-COM doesn't report the state of its CAN controller, so state is always null.
  • bitrate is the canRate option that the adapter was configured with.
  • The adapter is taken to be disconnected when the serial port is closed because the device went away (the close event's error has disconnected set). The serial port is already closed then, so isOpen() returns false, but the status stays 'disconnected' until close() or open() is called.
  • Status changes are noticed from serial port events, so no periodic check is needed.

Development

Please note the following if you wish to update or modify this package:

  • eslint rules are included, please lint any changes.
  • Confirm that unit tests are working. To run the tests, use the 'npm test' command.

npm test runs test/basic.test.js, which uses a mock serial port binding (test/MockBinding.js) and needs no hardware. The mock is supplied through the Binding constructor option; any object implementing the serialport v10+ binding interface (list() and open()) can be used there.

npm run test:hardware runs test/filter.test.js against real hardware. In order to run it, you will need at least one CAN-USB-COM device connected to your computer. I think you may have to have the CAN-USB-COM device connected to a properly terminated bus. However, do not run the tests on a bus with active traffic, since receiving unexpected CAN packets will probably confuse the tests.

The local folder holds older ad hoc test scripts. They are not part of the npm package and are not linted.

Distribution

The module is plain JavaScript. Its only native code is in serialport's @serialport/bindings-cpp dependency, which ships its own prebuilt Node-API binaries, so nothing needs to be compiled when the module is installed.

Releasing

Releases are published by the GitHub Actions workflow in .github/workflows/release.yml, which runs when a version tag is pushed:

  1. Run the hardware tests locally with a CAN-USB-COM adapter connected: npm run test:hardware (the CI runners have no CAN hardware, so they only run the unit tests)
  2. npm version patch (or minor / major), which updates package.json and creates the tag vX.Y.Z
  3. git push --follow-tags

The workflow lints the code and runs the unit tests on Windows, macOS and Linux with NodeJS 20, 22 and 24, and checks that the serialport native binding loads on each. It then publishes the package to npm. Publishing uses npm trusted publishing, so no npm token is stored in GitHub; the package's trusted publisher on npmjs.com must name this repository and the workflow file release.yml.

Licensing and Dependencies

This project is licensed under the MIT license - see the LICENSE file for details.

It uses serialport (@serialport/stream and @serialport/bindings-cpp), which is also MIT licensed.