7 years, 8 months 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 /media/uploads/jafarov/2-node-can2.jpg

/media/uploads/jafarov/14001879_636322893187586_650444201_o.jpg

This code works. ( My test code ) Transmitter cod.

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

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

/media/uploads/jafarov/13940205_636754139811128_1848931002_o.jpg

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

2 Answers

7 years, 8 months 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.

Accepted Answer
7 years, 8 months 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 nazım jafarov 10 Aug 2016

Hello 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;
    }
}
posted by Zoltan Hudak 10 Aug 2016

Zoltan Thank you very much.. This project is very important for me .. You helped me a lot.. :)

posted by nazım jafarov 11 Aug 2016

I live in İstanbul / turkey .. Call me if you come to turkey ( Whatsapp no : +90 539 383 43 63).

posted by nazım jafarov 11 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

Hello 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 Zoltan Hudak 14 Aug 2016