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.
Canbus . data sending and reading problems
Hi, I want to send string data LPC1768 from other LPC1768. I use can bus communication protocol. (pin30, p29)
my circuit I
This code works. ( My test code ) Transmitter cod.
- include "mbed.h"
Ticker ticker; DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); CAN can1(p30, p29); char counter = 0;
void send() { if(can1.write(CANMessage(1337, &counter, 1))) { led2 = !led2; } led1 = !led1; } int main() { CANMessage msg;
can1.frequency(250000);
while(1) { ticker.attach(&send, 1); wait(0.2); } } RECEIVER
- include "mbed.h" Ticker ticker; DigitalOut led4(LED4); CAN can1(p30, p29);
int main() { CANMessage msg; can1.frequency(250000);
while(1) { if(can1.read(msg)) { led4 = !led4; } wait(0.2); } } My Problem. I want to send data int or string format. I want to turn on the lights, depending on the condition. I want the code to do this operation for example. Transmitter int a=5; can1.write(CANMessage(a);
RECEIVER if(can1.read(msg)) { led4 = !led4; } İf (msg==5) { led2= !led2}
you write this code. Please
2 Answers
8 years ago.
Please use the <<code>> and <</code>>
tags on separate lines around your posted code to keep it readable.
Example code for sending and inspecting the content of a CAN message is here.
8 years ago.
Hello Nazim,
See below an example:
Transmitter
#include "mbed.h" DigitalOut led1(LED1); CAN can1(p30, p29); int a = 0; int main() { can1.frequency(250000); while(1) { can1.write(CANMessage(1337, reinterpret_cast<char*>(&a), sizeof(a))); led1 = !led1; a++; wait(0.2); } }
Receiver
#include "mbed.h" DigitalOut led2(LED2); DigitalOut led4(LED4); CAN can1(p30, p29); CANMessage msg; int a; int main() { can1.frequency(250000); while(1) { if(can1.read(msg)) { if(msg.id == 1337) { led4 = !led4; a = *reinterpret_cast<int*>(msg.data); if(a % 5 == 0) led2 = !led2; } } } }
hello Zoltan :) it works :) Thank you so much. You saved me. I do not know anything about mbed and LPC1768.I have one more question. Can you help.. He added new photos. look up.. I have 3 LPC one master 2 slave https://developer.mbed.org/media/uploads/jafarov/x13940205_636754139811128_1848931002_o.jpg.pagespeed.ic.X6ZapsqRr5.webp
Transmitter I want int a=0 ; Send from slave1. (LPC1768) and I want int a=0 ; Send from SLAVE2.
Receiver ( master ) Read the master. if if sent slaves1 0. I want to turn on the lights ( led1 ). if if sent slaves2 0. I want to turn on the lights ( led2 ). you write this code. Please
posted by 10 Aug 2016Hello Nazim,
Normally there is no master (or host) in a CAN network. It is a message based protocol. Please read CAN - Getting Started for more info (also regarding the termination of a CAN bus at the ends by resistors). All CAN nodes are equal (peers). However, in your case for the sake of simplicity, we can call the nodes Master, Slave1 and Slave2 if you like so. Each node will receive all messages transmitted by the others. In your case, the 'Mater' is specially interested in two kind of messages. One shall control LED1 and the other LED2. The CANMessage class already includes a member designed to distinguish individual 'kind' of messages. It's called "id". So after receiving a message the 'Master' shall check the 'id' of the message received and then take the action defined by the data received.
Master
include "mbed.h" const uint16_t CONTROL_LED1 = 0x200; // Messages to control LED1 const uint16_t CONTROL_LED2 = 0x201; // Messages to control LED2 DigitalOut led1(LED1); DigitalOut led2(LED2); CAN can(p30, p29); CANMessage msg; int main() { can.frequency(250000); while(1) { if(can.read(msg)) { switch(msg.id) { case CONTROL_LED1: led1 = *reinterpret_cast<int*>(msg.data); break; case CONTROL_LED2: led2 = *reinterpret_cast<int*>(msg.data); break; } } } }
Slave1 will send messages to control LED1:
Slave1
#include "mbed.h" const uint16_t CONTROL_LED1 = 0x200; // Messages to control LED1 CAN can(p30, p29); DigitalOut led1(LED1); int ledStatus; int main() { can.frequency(250000); while(1) { ledStatus = led1; can.write(CANMessage(CONTROL_LED1, reinterpret_cast<char*>(&ledStatus), sizeof(ledStatus))); wait(2.0); led1 = !led1; } }
Slave2 will send messages to control LED2:
Slave2
#include "mbed.h" const uint16_t CONTROL_LED2 = 0x201; // Messages to control LED2 CAN can(p30, p29); DigitalOut led1(LED1); int ledStatus; int main() { can.frequency(250000); while(1) { ledStatus = led1; can.write(CANMessage(CONTROL_LED2, reinterpret_cast<char*>(&ledStatus), sizeof(ledStatus))); wait(3.0); led1 = !led1; } }
Zoltan Thank you very much.. This project is very important for me .. You helped me a lot.. :)
posted by 11 Aug 2016I live in İstanbul / turkey .. Call me if you come to turkey ( Whatsapp no : +90 539 383 43 63).
posted by 11 Aug 2016Zoltan. I'm uncomfortable. sorry. can.write(CANMessage(sinyalg_g, reinterpret_cast<char*>(&signal), sizeof(signal))); This code write only char. I want to write the float. for example: float signal = 0;
posted by 14 Aug 2016Hello Nazim,
Declare a message ID for CAN messages you plan to send and declare and initialize a signal
variable as float
. (Similar to the int ledStatus
in the example above.)
const uint16_t SIGNAL_ID = 0x202; float signal = 257.31;
Then sizeof(signal)
returns the size of a float
, which is four bytes. So the data length of a CAN message you create will be four bytes. If you are in doubt you can use 4 instead of sizeof(signal)
in the CANMessage constructor.
Because the CANMessage
constructor's second argument shall always be a pointer to char (char*
) and &signal
is a pointer to float, the expression reinterpret_cast<char*>(&signal)
will cast it from a pointer to float to a pointer to char.
So when you call the constructor
CANMessage(SIGNAL_ID, reinterpret_cast<char*>(&signal), sizeof(signal))
or
CANMessage(SIGNAL_ID, reinterpret_cast<char*>(&signal), 4)
it will create a can message with data starting at the address of the signal
variable and it's going to be four bytes long.
Then calling
can.write(CANMessage(SIGNAL_ID, reinterpret_cast<char*>(&signal), sizeof(signal)))
or
can.write(CANMessage(SIGNAL_ID, reinterpret_cast<char*>(&signal), 4))
will send a CAN message with data length of four bytes.
Transmitter
#include "mbed.h" const uint16_t SIGNAL_ID = 0x202; CAN can(p30, p29); DigitalOut led1(LED1); float signal = 257.31; int main() { can.frequency(250000); while(1) { can.write(CANMessage(SIGNAL_ID, reinterpret_cast<char*>(&signal), sizeof(signal))); wait(2.0); led1 = !led1; } }
When you receive a CAN message you can get more details about it as follows:
Receiver
#include "mbed.h" const uint16_t SIGNAL_ID = 0x202; Serial pc(USBTX, USBRX); DigitalOut led1(LED1); CAN can(p30, p29); CANMessage msg; float signal; int main() { can.frequency(250000); 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 == SIGNAL_ID) { led1 = !led1; signal = *reinterpret_cast<float*>(msg.data); pc.printf(" signal = %5.2f\r\n", signal); } } } }
Zoltan
posted by 14 Aug 2016
Zoltan. I'm uncomfortable. sorry. can.write(CANMessage(sinyalg_g, reinterpret_cast<char*>(&signal), sizeof(signal))); This code write only char. I want to write the float. for example: float signal = 0;
posted by nazım jafarov 14 Aug 2016