// demo: CAN-BUS Shield, receive data with interrupt mode
// when in interrupt mode, the data coming can't be too fast, must >20ms, or else you can use check mode
// loovee, 2014-6-13
#include <SPI.h>
#include "mcp_can.h"
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
unsigned char flagRecv = 0;
unsigned char len = 0;
unsigned char buf[8];
char str[20];
void buffer_append_int16(uint8_t* buffer, int16_t number, int32_t *index) {
buffer[(*index)++] = number >> 8;
buffer[(*index)++] = number;
}
void buffer_append_uint16(uint8_t* buffer, uint16_t number, int32_t *index) {
buffer[(*index)++] = number >> 8;
buffer[(*index)++] = number;
}
void buffer_append_int32(uint8_t* buffer, int32_t number, int32_t *index) {
buffer[(*index)++] = number >> 24;
buffer[(*index)++] = number >> 16;
buffer[(*index)++] = number >> 8;
buffer[(*index)++] = number;
}
void buffer_append_uint32(uint8_t* buffer, uint32_t number, int32_t *index) {
buffer[(*index)++] = number >> 24;
buffer[(*index)++] = number >> 16;
buffer[(*index)++] = number >> 8;
buffer[(*index)++] = number;
}
// CAN commands
typedef enum {
CAN_PACKET_SET_DUTY = 0,
CAN_PACKET_SET_CURRENT,
CAN_PACKET_SET_CURRENT_BRAKE,
CAN_PACKET_SET_RPM,
CAN_PACKET_SET_POS,
CAN_PACKET_FILL_RX_BUFFER,
CAN_PACKET_FILL_RX_BUFFER_LONG,
CAN_PACKET_PROCESS_RX_BUFFER,
CAN_PACKET_PROCESS_SHORT_BUFFER,
CAN_PACKET_STATUS
} CAN_PACKET_ID;
void comm_can_set_rpm(uint8_t controller_id, float rpm) {
int32_t send_index = 0;
uint8_t buffer[4];
buffer_append_int32(buffer, (int32_t)rpm, &send_index);
CAN.sendMsgBuf(controller_id | ((uint32_t)CAN_PACKET_SET_RPM << 8), 1, send_index, buffer);
// comm_can_transmit(controller_id | ((uint32_t)CAN_PACKET_SET_RPM << 8), buffer, send_index);
}
void setup()
{
Serial.begin(115200);
START_INIT:
if(CAN_OK == CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
{
Serial.println("CAN BUS Shield init ok!");
}
else
{
Serial.println("CAN BUS Shield init fail");
Serial.println("Init CAN BUS Shield again");
delay(100);
goto START_INIT;
}
attachInterrupt(0, MCP2515_ISR, FALLING); // start interrupt
comm_can_set_rpm(1,4000);
comm_can_set_rpm(5,4000);
delay(100);
comm_can_set_rpm(1,0000);
comm_can_set_rpm(5,0000);
delay(1000);
comm_can_set_rpm(1,-4000);
comm_can_set_rpm(5,-4000);
delay(100);
comm_can_set_rpm(1,0000);
comm_can_set_rpm(5,0000);
}
void MCP2515_ISR()
{
flagRecv = 1;
}
void loop()
{
if(flagRecv)
{ // check if get data
flagRecv = 0; // clear flag
// iterate over all pending messages
// If either the bus is saturated or the MCU is busy,
// both RX buffers may be in use and reading a single
// message does not clear the IRQ conditon.
while (CAN_MSGAVAIL == CAN.checkReceive())
{
// read data, len: data length, buf: data buf
CAN.readMsgBuf(&len, buf);
Serial.print("Get Data From id: ");
Serial.println(CAN.getCanId());
if (CAN.isExtendedFrame())
{
Serial.println("IsExtendedFrame");
} else
{
Serial.println("Is NOT ExtendedFrame");
}
// print the data
for(int i = 0; i<len; i++)
{
Serial.print(buf[i]);Serial.print("\t");
}
Serial.println();
}
}
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/