Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
8 years ago.
can bus arduino mega with lpc1768
Below are examples of canbus from arduino, sender and receiver. I need to write a code how to use lpc178 as receiver. I am using the mcp2515 module. Thanks friends...
CAn send
- include <mcp_can.h>
- include <SPI.h>
MCP_CAN CAN0(53); Set CS to pin 10
void setup() { Serial.begin(115200);
Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled. if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!"); else Serial.println("Error Initializing MCP2515...");
CAN0.setMode(MCP_NORMAL); Change to normal mode to allow messages to be transmitted }
byte data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
void loop() { send data: ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send byte sndStat = CAN0.sendMsgBuf(0x100, 0, 8, data); if(sndStat == CAN_OK){ Serial.println("Message Sent Successfully!"); } else { Serial.println("Error Sending Message..."); } delay(100); send data per 100ms }
CAN Receive Example
- include <mcp_can.h>
- include <SPI.h>
long unsigned int rxId; unsigned char len = 0; unsigned char rxBuf[8]; char msgString[128]; Array to store serial string
- define CAN0_INT 2 Set INT to pin 2 MCP_CAN CAN0(53); Set CS to pin 10
void setup() { Serial.begin(115200);
Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled. if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!"); else Serial.println("Error Initializing MCP2515...");
CAN0.setMode(MCP_NORMAL); Set operation mode to normal so the MCP2515 sends acks to received data.
pinMode(CAN0_INT, INPUT); Configuring pin for /INT input
Serial.println("MCP2515 Library Receive Example..."); }
void loop() { if(!digitalRead(CAN0_INT)) If CAN0_INT pin is low, read receive buffer { CAN0.readMsgBuf(&rxId, &len, rxBuf); Read data: len = data length, buf = data byte(s)
if((rxId & 0x80000000) == 0x80000000) Determine if ID is standard (11 bits) or extended (29 bits) sprintf(msgString, "Extended ID: 0x%.8lX DLC: %1d Data:", (rxId & 0x1FFFFFFF), len); else sprintf(msgString, "Standard ID: 0x%.3lX DLC: %1d Data:", rxId, len);
Serial.print(msgString);
if((rxId & 0x40000000) == 0x40000000){ Determine if message is a remote request frame. sprintf(msgString, " REMOTE REQUEST FRAME"); Serial.print(msgString); } else { for(byte i = 0; i<len; i++){ sprintf(msgString, " 0x%.2X", rxBuf[i]); Serial.print(msgString); } }
Serial.println(); } }
3 Answers
8 years ago.
Hello. Mbed tools do not care (for the most part) about the target board so experiment with yours and the following available CAN examples / libraries. Select the IMPORT CODE button and select your target board inside the Compiler Window (top right side - you can add your target board from the GUI):
https://developer.mbed.org/users/tecnosys/code/mcp2515/
https://developer.mbed.org/users/FalconOnishi/code/MCP2515/
https://developer.mbed.org/questions/68586/How-to-use-MCP2515-for-LPC1114FN28/
In the future, please post with the following tags - will format your code for easier viewing:
<<code>> ; at the start of your code
<</code>>
; at the end of your code
https://developer.mbed.org/users/WiredHome/notebook/can---getting-started/
8 years ago.
Hello Ekrem,
To make your code nicely formatted please use the Wiki Syntax as below (see also the link to Editing tips at the bottom of your editing box for more details). It becomes much easier to read.
<<code>> int max(int x, int y) { return (x > y) ? x : y; } <</code>>
Your Arduino CAN sender code formatted:
#include <mcp_can.h> #include <SPI.h> MCP_CAN CAN0(53); // Set CS to pin 10 void setup() { Serial.begin(115200); // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled. if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!"); else Serial.println("Error Initializing MCP2515..."); CAN0.setMode(MCP_NORMAL); // Change to normal mode to allow messages to be transmitted } } byte data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; void loop() { // send data: ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send byte sndStat = CAN0.sendMsgBuf(0x100, 0, 8, data); if(sndStat == CAN_OK) Serial.println("Message Sent Successfully!"); else Serial.println("Error Sending Message..."); delay(100); //send data per 100ms }
An example of receiver code for LPC1768 board (see also the mbed CAN-Handbook for more info):
#include "mbed.h" const uint16_t MSG_ID = 0x100; Serial pc(USBTX, USBRX); DigitalOut led1(LED1); CAN can(p30, p29); CANMessage msg; int main() { can.frequency(500000); while(1) { if(can.read(msg)) { pc.printf("CAN message received\r\n"); pc.printf(" ID = 0x%.3x\r\n", msg.id); pc.printf(" Type = %d\r\n", msg.type); pc.printf(" Format = %d\r\n", msg.format); pc.printf(" Length = %d\r\n", msg.len); pc.printf(" Data ="); for(int i = 0; i < msg.len; i++) pc.printf(" %.2x", msg.data[i]); pc.printf("\r\n"); if(msg.id == MSG_ID) { led1 = !led1; } } } }
Schematic (Zoom in)
NOTE: Since in the example above the receiver is sending data to the connected PC over a 'slow' serial connection I recommend to increase the Arduino's send delay from 100ms to 1000ms or more.
Zoltan
hi Zoltan Thank you so much for your suggestions . ı was tried that code ago. but ı will try again. ı made that send candata -receive can data by using arduino. ı send data by arduino on MCP2515 Module and ı try read data from canbus line by lpc1768 contoller and mcp2551Integrated .But ı cant read data on cabus line with using lpc1768.
ı using can frequency(125000) .and baudrate is 9600 to see data.
ı think ı have small wrong about data type convert but ı dont know what it is . ı send data type : data id = unsigned char and data =unsigned char . ı read data type is data id = const uint16_t . ı cant know how ı will use that function well :
CANMessage(int _id, const char *_data, char _len=8, CANType _type= CANData, CANFormat _format =CANStandart)
but ı will try use these codes again.
posted by 08 Dec 2016I see the picture you sent but I use the mcp2515 module, I do not use integrated 2515 and 2551. I only use 2551 for lpc1768. Because there are 2515 and 2551 for the MCP2515 CANBUS-SPI Communication Module.
posted by 08 Dec 2016Hello Ekrem,
The MCP2515 chip (the one connected to the Arduino) is just a stand-alone CAN controller with SPI interface. If you connect it directly to a CAN bus it will not work. An additional CAN transceiver (like for example the MCP2551) is needed for such connection. If you use an Arduino shield, for instance this https://www.sparkfun.com/products/13262 or this http://wiki.seeed.cc/CAN-BUS_Shield_V1.2/ then both chips (MCP2515 + MCP2551) are already installed. Otherwise, when you build a CAN interface for Arduino by yourself, you have to add both chips as indicated on the schematic above.
8 years ago.
hii Zoltan, we use the circuit so that. we use MCP2515 CANBUS Modul between arduino and canbus line. also there is in mcp2551 and mcp2515 inside canbus 2515 Module.
WikiPage http://www.google.com.tr/search?q=canbu+module&espv=2&biw=1366&bih=589&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjl3PfrxeXQAhVrBsAKHYgrDBUQ_AUIBygC#imgrc=NorJfTLa58Mr7M%3A
are you mean we cant can-bus communicate between using arduino and lpc1768 ? do we need buy things (canbus shield) what you shared links?
Hello,
The CAN module (shield) you use is equipped with a TJA1050 CAN transceiver which provides the same functionality as MCP2551. So you do not need to buy anything else. Your schematic (in the picture above) is correct and the CAN bus communication between arduino and LPC1768 shall work.
NOTE: Make sure that the arduino's GND is also connected to the same GND as the CAN modules, LPC1768 and MCP2551 (I could not see this connection in your schematic).
thank you. For a month we try the codes above and our connections are correct. But we can not read lpc1768 den message, I think we have a programmatic error. What else could be wrong?
posted by 10 Dec 2016I have tested the code above with LPC1768 and it works fine. For Arduino I use this CAN bus library. It shall work also with your CAN module. Once downloaded, unzip the arduinoCANBUS-library-v0_3.zip file. The library is implemented in the arduinoCAN.h and arduinoCAN.cpp files. There are also some good examples attached. For installation instructions have a look at this link. Before using it remember to configure the CAN_CS pin in the arduinoCAN.h file according to your schematic (#define CAN_CS 10). Interrupt (CAN_INT pin) is not used. Also make sure you set-up the same CAN bus frequency for both the Arduino module and the LPC1768. For example, if you would like to use 250kbps then:
Arduino
... void setup() { myCAN.begin(250); ... }
LPC1768
... int main() { myCAN.frequency(250000); ... }
NOTE: Although this Question does not relate to Arduino, it might be useful to have a look.
Hello, yes we managed to run it, but arduino is 500 kbps, lpc can.frequency (250000), but we read like this. What could be the reason for this?
posted by 11 Dec 2016arduinomega2560; #include <mcp_can.h> #include <SPI.h> //11 ok 12 error const int SPI_CS_PIN = 53; //Can‐Bus pin ayarı MCP_CAN CAN(SPI_CS_PIN); const int analogInPin =0; // Ldr Pin Ayarı int sensorValue = 0; char outputValue = 0; void setup() { Serial.begin(9600); pinMode(5,OUTPUT); pinMode(6,OUTPUT); START_INIT: if(CAN_OK == CAN.begin(CAN_500KBPS)) //Can‐Bus bağlantı hızı ve kontrolü { Serial.println("CAN BUS Shield init ok!"); digitalWrite(6,LOW); digitalWrite(5,HIGH); //Baglanti Kuruldu Ledi } else { Serial.println("CAN BUS Shield init fail"); Serial.println("Init CAN BUS Shield again"); digitalWrite(5,LOW); digitalWrite(6,HIGH); //Baglanti Kuruldu Ledi delay(1000); goto START_INIT; } } void loop() { sensorValue = analogRead(analogInPin); // sensör okuma outputValue = map(sensorValue, 0, 1023, 0, 255); analogWrite(3,outputValue); byte ldr[8] = {outputValue, 0, 0, 0, 0, 0, 0, 0}; // send data: id = 0x00, standrad frame, data len = 8, stmp: data buf CAN.sendMsgBuf(0x001,0, 8, ldr); //Can‐Bus hattına veri gönderme delay(1000); }
lpc1768 receiver; #include "mbed.h" const uint16_t MSG_ID = 0x001; Serial pc(USBTX, USBRX); DigitalOut led1(LED1); DigitalOut led2(LED2); CAN can(p30, p29); //CANMessage msg; CANMessage msg = CANMessage(); /*Variable de type CANMessage*/ //canmsg.id=0x001; /*L'identification du message*/ int main() { can.frequency(250000); pc.baud(9600); msg.len=8; /*Longeur de la trame en octet*/ msg.format=CANStandard; /*Format de la trame CANStandart 11 octet*/ msg.type=CANData; while(1) { if(can.read(msg)) { led2.write(1); pc.printf("CAN message received\r\n"); pc.printf(" ID = 0x%.3x\r\n", msg.id); pc.printf(" Type = %d\r\n", msg.type); pc.printf(" Format = %d\r\n", msg.format); pc.printf(" Length = %d\r\n", msg.len); pc.printf(" Data ="); for(int i = 0; i < msg.len; i++){ pc.printf(" %.2x", msg.data[i]); pc.printf("\r\n"); } if(msg.id == MSG_ID) { led1 = !led1; } } } }
Hello,
I had a closer look at the CAN bus module you are using and it seems (at least based on the picture on the AliExpress site ) that it's equipped with an 8MHz crystal (however, the Arduino library assumes 16MHz by default). That could explain why the CAN bus frequency is shifted two times.
Try to initialize the CAN bus with 8MHz crystal:
void setup() { ... if(CAN_OK == CAN.begin(MCP_ANY, CAN_250KBPS, MCP_8MHZ)) { ... }
Thank you. The library we use does not accept this encoding. It's not important, we're doing it. We are tired of you too, but sorry.. I am sending the following code to Arduino,
sensorValue = analogRead(A0); sensör okuma outputValue = map(sensorValue, 0, 1023, 0, 255); byte data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, outputValue};
but lpc1768 reads it with 16 bits of data. I want to read 0-1023 or 0-255. How can we do this?
posted by 12 Dec 2016You can send various data types over CAN bus for example as follows:
Arduino code
... const unsigned int ID_SENSOR_VALUE = 0x201; const unsigned int ID_OUTPUT_VALUE = 0x202; const unsigned int ID_SENSOR_VOLTAGE = 0x203; ... union CanDataType { byte data[8]; // 8 bytes (max length) unsigned int sensorValue; // 2 bytes char outputValue; // 1 byte float sensorVoltage; // 4 bytes }; ... CanDataType canData; unsigned int sensorValue; // 2 bytes byte outputValue; // 1 byte float sensorVoltage; // 4 bytes ... void loop() { ... sensorValue = analogRead(analogInPin); outputValue = map(sensorValue, 0, 1023, 0, 255); sensorVoltage = (sensorValue * 5) / 1023.0f; ... canData.sensorValue = sensorValue; CAN.sendMsgBuf(ID_SENSOR_VALUE , 0, sizeof(canData.sensorValue), &canData); delay(1000); canData.outputValue = outputValue; CAN.sendMsgBuf(ID_OUTPUT_VALUE, 0, sizeof(canData.outputValue), &canData); delay(1000); canData.sensorVoltage = sensorVoltage; CAN.sendMsgBuf(ID_SENSOR_VOLTAGE, 0, sizeof(canData.sensorVoltage), &canData); delay(1000); }
LPC1768 code
#include "mbed.h" const uint16_t ID_SENSOR_VALUE = 0x201; const uint16_t ID_OUTPUT_VALUE = 0x202; const uint16_t ID_SENSOR_VOLTAGE = 0x203; Serial pc(USBTX, USBRX); DigitalOut led1(LED1); DigitalOut led2(LED2); CAN can(p30, p29); CANMessage msg; uint16_t sensorValue; // 2 bytes uint8_t outputValue; // 1 byte float sensorVoltage; // 4 bytes int main() { pc.baud(9600); can.frequency(250000); while(1) { if(can.read(msg)) { led1 = !led1; pc.printf("CAN message received\r\n"); pc.printf(" ID = 0x%.3x\r\n", msg.id); pc.printf(" Type = %d\r\n", msg.type); pc.printf(" Format = %d\r\n", msg.format); pc.printf(" Length = %d\r\n", msg.len); pc.printf(" Data ="); for(int i = 0; i < msg.len; i++){ pc.printf(" 0x%.2x", msg.data[i]); } pc.printf("\r\n"); switch(msg.id) { case ID_SENSOR_VALUE: sensorValue = *((uint16_t*)msg.data); pc.printf("sensorValue = %d\r\n", sensorValue); break; case ID_OUTPUT_VALUE: outputValue = *((uint8_t*)msg.data); pc.printf("outputValue = %d\r\n", outputValue); break; case ID_SENSOR_VOLTAGE: sensorVoltage = *((float*)msg.data); pc.printf("sensorVoltage = %5.3fV\r\n", sensorVoltage); break; } } } }
Hello Zoltan, Thank you so so much for your help.we have learned our wrong and we have learned canbus communication because of you . he can do all canbus communication after someone looked that sharing. kind regards
posted by 14 Dec 2016Hello Zoltan ,ı have one question more. how can ı read negative value on canbus line. for example the sensor read -5 value of data and send that to canbus lıne . but ı read 250 on lpc1768. ı send data of sensor value by "char"
send canbus data
signed char ldr[8] = {val2, 0, 0, 0, 0, 0, 0, 0}; // send data to canbus line
Hello,
Computers encode signed integers as two's complement. If you receive a byte with bits coded such way and interpret it as unsigned char
(uint8_t) then you will get wrong results. When you send a signed char
then you also have to interpret the received data as signed char
(int8_t). So instead of declaring the variable as uint8_t
declare it as int8_t
and also remember to cast it to int8_t
as below:
LPC1768
... int8_t outputValue; // 1byte ... case ID_OUTPUT_VALUE: outputValue = *((int8_t*)msg.data); pc.printf("outputValue = %d\r\n", outputValue); break; ...