This package is capable of controlling CAN BUS modules with SPI interface.
I used the MCP2515 CAN BUS module, but might be useful for other CAN modules.
This package is created according to this arduino library: https://github.com/Seeed-Studio/CAN_BUS_Shield
Firstly, you need to install Node.js. I am using node v12.16.1 and npm 6.14.3.
Follow this tutorial for installation:
How to Install Node.js and npm on Raspberry Pi
Secondly, you need to create an npm project.
After that, you can install PI-CAN node module.
Use:
npm i pi-can
Finally, you need to enable SPI communication on the Pi.
Use sudo raspi-config and navigate to 5 Interfacing Options > SPI > Yes (enable)
Reboot your Pi and you can start to programming your CAN network.
const PiCan = require('pi-can');
const can = new PiCan('/dev/spidev0.0');
can.begin(PiCan.defs.CAN_500KBPS)
.then(() => {
console.log('INIT SUCCESS');
// You can now use readMsg, sendMsg and others
})
.catch(() => {
console.log('INIT FAILED');
})setInterval(async () => {
let stat = await can.checkReceive();
if (stat === PiCan.defs.CAN_MSGAVAIL) {
can.readMsg()
.then(data => console.log('Recv:', data))
.catch(error => {
console.log('error', error);
})
}
if (stat === PiCan.defs.CAN_NOMSG) { }
}, 10);// ID, Extended, RTR, Length, Data
can.sendMsg(123, false, false, 3, [1, 2, 3])
.then(() => {
console.log('SENT');
})
.catch(() => {
console.log('Failed to send');
})can.begin(PiCan.defs.CAN_500KBPS)
.then(() => can.setMask(0, false, 0x7ff))
.then(() => can.setMask(1, false, 0x7ff))
// You should set both masks. More detailes at API > setMask
.then(() => can.setFilter(0, false, 0xfa))
//.then(() => can.setFilter(0..5, Extended, Accepted_id))can.begin(PiCan.defs.CAN_500KBPS)
// You can set pinmodes like this:
.then(() => can.pinMode(PiCan.rxPin(0), PiCan.defs.MCP_PIN_OUT))
.then(() => can.pinMode(PiCan.rxPin(1), PiCan.defs.MCP_PIN_OUT))
.then(() => can.pinMode(PiCan.txPin(0), PiCan.defs.MCP_PIN_IN))
.then(() => can.pinMode(PiCan.txPin(1), PiCan.defs.MCP_PIN_IN))
.then(() => can.pinMode(PiCan.txPin(2), PiCan.defs.MCP_PIN_IN))
// Write to output
can.digitalWrite(PiCan.rxPin(0), true);
can.digitalWrite(PiCan.rxPin(1), false);
// Read from input
can.digitalRead(PiCan.txPin(0)).then(value=>console.log(value));
can.digitalRead(PiCan.txPin(1)).then(value=>console.log(value));
can.digitalRead(PiCan.txPin(2)).then(value=>console.log(value));
// You can also read written output value. Use rxPin with digitalRead.IMPORTANT: TX is the input, RX is the output
Creates a new instance of this module.
spi:
SPI device
Usually it is'/dev/spidev0.0'or'/dev/spidev0.1'.debug:
trueoffalse
If set to true, you will get logs in the console about the current state of the program.
Initializes the module, than set speed and clock.
speedset:
Any of these values:
PiCan.defs.CAN_5KBPS PiCan.defs.CAN_10KBPS PiCan.defs.CAN_20KBPS PiCan.defs.CAN_25KBPS PiCan.defs.CAN_31K25BPS PiCan.defs.CAN_33KBPS PiCan.defs.CAN_40KBPS PiCan.defs.CAN_50KBPS PiCan.defs.CAN_80KBPS PiCan.defs.CAN_83K3BPS PiCan.defs.CAN_95KBPS PiCan.defs.CAN_100KBPS PiCan.defs.CAN_125KBPS PiCan.defs.CAN_200KBPS PiCan.defs.CAN_250KBPS PiCan.defs.CAN_500KBPS PiCan.defs.CAN_666KBPS PiCan.defs.CAN_1000KBPSThis speed needs to be consistent between the CAN nodes.
You need to set this, there is no default value.clockset:
MCP_16MHz (default) or
MCP_8MHzRETURN
Promise
Returns the status of the receive buffers.
RETURN
Promise
If fulfilled the return value can bePiCan.defs.CAN_MSGAVAILorPiCan.defs.CAN_NOMSG
Returns a message from the receive buffers.
RETURN
Promise
If fulfilled the return value is an object like this:{ id: number, // The ID of the message ext: boolean, // Extended frame rtr: boolean, // Remote transmission request size: number, // Message length data: number[], // Message data } // Message data is an empty array if RTR received
Sends a message to the CAN network.
id
The ID of the message.
Accepts number value.ext
True if you want to send an extended frame.
Accepts boolean value.rtrBit
True if you want to send a remote request.
Accepts boolean value.len
The length of the message
Accepts number value from 0 to 8.buf
The content of the message
Accepts an array of numbers. Needs to contain between 0 and 8 numbers.
If rtrBit === true, this shuld be an empty array.RETURN
Promise
If rejected the return value can bePiCan.defs.CAN_GETTXBFTIMEOUT
Tries to send a message through a specified transfer buffer.
iTxBuf
The transfer buffer's number.
Accepts0,1or2See other parameters above, at the sendMsg description.
Takes the module into sleep mode.
RETURN
Promise
Wakes up the module
RETURN
Promise
Sets a filter to the recived messages.
You can use up to 6 filters (from 0 to 5)
num
The number of the filter.
Number between0and5ext
Extended ID,
booleanulData
The accepted ID,
numberRETURN
Promise
Gets a filter value.
num
The number of the filter
RETURN
An object like this:
{ id: number, // Filter ID ext: number // Is ID extended }
Sets a mask to the filters.
There are two different masks. They are for the two different receive buffers.
You should set the same mask for each receive buffer.
The message will be received, if this logic returns true:
(RECEIVED_ID & MASK) == (FILTER & MASK)
// & means bitwise and.
So, you can turn off masks and filters, if both masks are set to 0.
num
The number of the mask.
Number0or1ext
Extended ID,
booleanulData
The applied mask on the filter,
numberRETURN
Promise
Gets a mask value.
Parameters: Same as setFilter.
Sets pin mode on GPIO
pin
Any of these values:
PiCan.rxPin(0) PiCan.rxPin(1) PiCan.txPin(0) PiCan.txPin(1) PiCan.txPin(2)mode
Any of these values:
PiCan.defs.MCP_PIN_HIZ PiCan.defs.MCP_PIN_INT PiCan.defs.MCP_PIN_OUT PiCan.defs.MCP_PIN_IN
MCP_PIN_INcannot be applied to RX pins.
MCP_PIN_HIZandMCP_PIN_INcannot be applied to TX pins.RETURN
Promise
Writes data to a GPIO output (to RX pin)
pin
PiCan.rxPin(0)orPiCan.rxPin(1)mode
trueorfalseRETURN
Promise
Reads data from a GPIO input (from TX pin)
pin
Any of these values
PiCan.rxPin(0) PiCan.rxPin(1) PiCan.txPin(0) PiCan.txPin(1) PiCan.txPin(2)RETURN
Promise
If fulfilled the return can betrueorfalse
Gets RX GPIO pin.
pin
0or1RETURN
PiCan.defs.MCP_RX0BForPiCan.defs.MCP_RX1BF
Gets TX GPIO pin.
pin
0,1or2RETURN
PiCan.defs.MCP_TX0RTS,PiCan.defs.MCP_TX1RTSorPiCan.defs.MCP_TX2RTS
PiCan.defs contains all definitions for this module.
If this project was useful for you, you can give me a cup of coffee :)
Thank You!
