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 🙏

© 2024 – Pkg Stats / Ryan Hefner

m2m-can

v1.0.9

Published

A simple can-bus communication system based on socketCAN.

Downloads

41

Readme

m2m-can

Version npm Custom badge

m2m-can is a basic can-bus library based on SocketCAN using a simple and easy API. Open and connect the can interface to the can-bus. Once connected, your device can start sending or receiving data to/from the can-bus.

  1. Supported devices
  2. Node.js version requirement
  3. Setup Raspberry Pi to use can-bus (using MCP2515 CAN module)
  4. Installation
  5. Quick Tour

Supported devices

  • Raspberry Pi Models: B+, 2, 3, Zero & Zero W, Compute Module 3, 3B+, 3A+, 4B (generally all 40-pin models)

Node.js version requirement

  • Node.js versions: 10.x, 11.x, 12.x, 14.x, 16.x. Ideally the latest LTS version.

Installation

$ npm install m2m-can

Raspberry Pi peripheral access (GPIO, I2C, SPI and PWM).

For projects requiring raspberry pi peripheral access such as GPIO, I2C, SPI and PWM, you will need to install array-gpio module.

$ npm install array-gpio

Quick Tour

On can-bus communication, each device should either be sending or receiving data to/from other devices on the network but not both.

Master application

'use strict';

const can = require('m2m-can');

let temp = null, random = null;

/* temperature can-bus device frame id */
const temp_id = '025';

/* random can-bus device frame id */
const random_id = '035';

/* master can-bus frame id or can node id */
const master_id = '00C';

/* open can0 interface, set bitrate to 500000 Hz */
// defaults to txqueuelen = 1000, rs = 100
can.open('can0', 500000, function(err){
  if(err) return console.error('can0 interface open error', err.message);
  // if can0 was opened successfully, you'll see an output - ip link set can0 up with txqueuelen 1000 and bitrate 500000 - success

  // read all frame data from CAN bus from all frame id's sending data to CAN bus
  can.read('can0', function(err, fdata){
    if(err) return console.log('can read error', err.message);
    console.log('read all frame data', fdata);
  });

  // read only random frame data from CAN bus using the random_id
  can.read('can0', {id:random_id}, function(err, fdata){
    if(err) return console.log('can read error', err.message);
    console.log('can-random frame data', fdata);
    // { id: '035', len: 3, data: [ 12, 52 ], filter: '035', change: true }   
    // data[0] - integer value
    // data[1] - integer value    
    random = fdata.data[0].toString() + fdata.data[1].toString();
    console.log('random data', random); // 1252
  });

  // read only temperature frame data from CAN bus using the temp_id
  can.read('can0', {id:temp_id} , function(err, fdata){
    if(err) return console.log('can read error', err.message);
    console.log('can-temp frame data', fdata);
    // { id: '025', len: 2, data: [ 18, 94 ], filter: '025', change: true }
    // data[0] - integer value
    // data[1] - fractional value    
    temp = fdata.data[0] + '.' + fdata.data[1];
    console.log('temperature data', temp); // 18.94
  });
});

Slave1 application

'use strict';

const can = require('m2m-can');
const r = require('array-gpio');

/* using the built-in MCP9808 chip library for capturing temperature data using i2c */
let i2c =  require('./node_modules/array-gpio/examples/i2c9808.js');

/* setup gpio output pins for led status indicator using array-gpio */
let led1 = r.out(33); // set gpio output pin 33 for can device status led
let led2 = r.out(35); // set gpio output pin 35 for data change status led

/* can-bus temperature device id */
const temp_id = '025';

can.open('can0', 500000, function(err){
  if(err) return console.error('can0 interface open error', err.message);

  led1.on();
  led2.off();

  // watch for changes in your data
  can.watch('can0', {id:temp_id}, (err, data) => { // watch interval defaults to 100 ms
    if(err) return console.error('can watch error', err.message);

    // set payload property to your data source
    data.payload = i2c.getTemp();

    // if temp data value has changed, send data to CAN bus from temp_id
    if(data.change === true){
      console.log('send temp data', data.payload);
      led2.pulse(200);
      can.send('can0', temp_id, data.payload);
    }
    else{
      console.log('no data change');
    }
  });
});

Slave2 application

'use strict';

const can = require('m2m-can');
const r = require('array-gpio');

/* setup can bus device led status indicator using array-gpio */
let led1 = r.out(33); // can device status
let led2 = r.out(35); // data change status

// can-bus device random id
const random_id = '035';

can.open('can0', 500000, function(err){
  if(err) return console.error('can0 interface open error', err.message);

    led1.on();
    led2.off();

    can.watch('can0', {id:random_id}, (err, data) => {
       if(err) return console.error('can watch error', err.message);

       data.payload = 1010 + Math.floor(( Math.random() * 200) + 100);

       // if random value has changed, send data to CAN bus from random_id
       // since a new value will be generated everytime, it will always send data to CAN bus   
       if(data.change){
         console.log('send random data', data.payload);
         can.send('can0', random_id, data.payload);
         led2.pulse(200);
       }
       else{
         console.log('no data change');
       }
    });
});

Can-bus setup

Pin Connection

RPI GPIO Header         MCP2515 CAN Module

PIN  NAME              PIN

#01   3.3V  ------------------  VCC

#06   GND  -----------------  GND

#19   SPI_MOSI  ----------  SI

#21   SPI_MISO  ----------  SO

#22   GPIO25  -------------  INT

#23   SPI_SCLK  ----------  SCK/CLK

#24   SPI_CE0  ------------  CS

  1. Open the Raspberry Pi config.txt file using an editor.
$ sudo mousepad /boot/config.txt

  or

$ sudo leafpad /boot/config.txt
  1. Uncomment the following section to enable SPI.
dtparam=spi=on
  1. Add the following as additional SPI setup.
dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25
  1. Comment the following section. This is not needed.
# dtoverlay=spi0-hw-cs
  1. Save the config.txt file. Reboot the Raspberry Pi.

  2. Verify the SPI configuration. The CAN module should be initialized.

$ dmesg | grep -i spi

  The result will look like as shown below.

[    8.544607] mcp251x spi0.0 can0: MCP2515 successfully initialized.

  By the same command you can check the CAN module if it was started by default:

$ dmesg | grep -i can

  The result will look like as shown below.

[    9.793497] CAN device driver interface
[    9.819174] mcp251x spi0.0 can0: MCP2515 successfully initialized.
[  271.563711] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready
[  271.695497] can: controller area network core
[  271.711043] can: raw protocol

  If for any reason this is not the case, you can add the CAN module at system start:

$ sudo nano /etc/modules

  Add "can" in a new line, save the file and reboot.

Optional additional CAN utilities.

  1. Install Linux can utility for SocketCAN (https://github.com/linux-can/can-utils).
$ sudo apt-get install can-utils
  1. Set the clock speed.
$ sudo ip link set can0 up type can bitrate 500000

  If the device is busy as shown below:

$ RTNETLINK answers: Device or resource busy

  Shutdown the CAN interface as shown below:

$ sudo ifconfig can0 down

  And then restart it as shown below:

$ sudo ifconfig can0 up
  1. Listen for any data in the CAN bus.
$ candump any
  1. Send some data to the CAN bus.
$ cansend can0 111#FF
  1. Below are some examples.

  Wrong CAN-frame format! Try:

<can_id>#{R|data}          for CAN 2.0 frames
<can_id>##<flags>{data}    for CAN FD frames
<can_id> can have 3 (SFF) or 8 (EFF) hex chars
{data} has 0..8 (0..64 CAN FD) ASCII hex-values (optionally separated by '.')
<flags> a single ASCII Hex value (0 .. F) which defines canfd_frame.flags

e.g. 5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / 123##1 / 213##311
     1F334455#1122334455667788 / 123#R for remote transmission request.

can-utils https://github.com/linux-can/can-utils