New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

m2m-can

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

m2m-can

A simple can-bus communication system based on socketCAN.

latest
npmnpm
Version
1.0.9
Version published
Maintainers
1
Created
Source

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.

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



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

  or

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

  • 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.

$ sudo apt-get install can-utils
  • 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
  • Listen for any data in the CAN bus.
$ candump any
  • Send some data to the CAN bus.
$ cansend can0 111#FF
  • 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.

Links

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

Keywords

bcm2835

FAQs

Package last updated on 22 Mar 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts