6 years ago.

Multiple CAN Messages using 1 mbed LPC1768 and two CAN channels

I'm trying to send a message from one channel, receive it on the other, adapt the data and send it back. I've been using my adapted code of the tutorial but it won't let me send and receive more than one message. Please can someone help!?

CAN_LED_New_Struct_v2

#include "mbed.h"

Ticker ticker1;
Ticker ticker2;
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
CAN can1(p9, p10);
CAN can2(p30, p29);
CANMessage msg;
int ChargerVoltage;

void DummyCharger(){
    int Votlage = 98;
    int Current = 16;
    int DecV = Votlage * 10;
    int DecC = Current * 10;
    int Top8V = DecV >> 8;
    int Top8C = DecC >> 8;
    int bot8var = 255;
    int Bot8V = bot8var & DecV;
    int Bot8C = bot8var & DecC;
    CANMessage msg;  
      
    msg.format = CANExtended;// or  CANExtended;  // standard or extended ID (can be skipped for standard)
    msg.id = 0x18FF50E5;
    msg.len = 4;//length in bytes (1 to 8);
    msg.data[0] = Top8V; // repeat for each byte.
    msg.data[1] = Bot8V;
    msg.data[2] = Top8C;
    msg.data[3] = Bot8C;
    msg.data[4] = 0;
    msg.data[5] = 0;
    msg.data[6] = 0;
    msg.data[7] = 0;
    
    printf("Top 8: %d\n", Top8V);
    printf("Bottom 8: %d\n", Bot8V);
    
    if (can2.write(msg)){
    printf("Charger_writesuccess\n");
    led1 = !led1;
    }
};

void Send2Charger(){
    printf("Charger Voltage: %d\n", ChargerVoltage);
    int SendVoltage = ChargerVoltage + 50;
    printf("Send Voltage: %d\n", SendVoltage);
    int DecV2 = SendVoltage;
    int DecC2 = 16 * 10;
    int Top8V2 = DecV2 >> 8;
    int Top8C2 = DecC2 >> 8;
    int bot8var = 255;
    int Bot8V2 = bot8var & DecV2;
    int Bot8C2 = bot8var & DecC2;  
    CANMessage msg;
    
    msg.format = CANExtended;// or  CANExtended;  // standard or extended ID (can be skipped for standard)
    msg.id = 0x1806E5F4;
    msg.len = 4;//length in bytes (1 to 8);
    msg.data[0] = Top8V2; // repeat for each byte.
    msg.data[1] = Bot8V2;
    msg.data[2] = Top8C2;
    msg.data[3] = Bot8C2;
    msg.data[4] = 0;
    msg.data[5] = 0;
    msg.data[6] = 0;
    msg.data[7] = 0;
    
    printf("Top 8: %d\n", Top8V2);
    printf("Bottom 8: %d\n", Bot8V2);
    
    if (can1.write(msg)){
        printf("Controller_writesuccess\n");
    led3 = !led3;}
};




int main() {
    printf("main()\n");
    ticker1.attach(&DummyCharger, 1);
    ticker2.attach(&Send2Charger, 1);
    CANMessage msg;
    while(1) {
        //printf("loop()\n");
        if (can1.read(msg)) {
            printf("Controller_readsuccess\n");
            if (msg.id == 0x18FF50E5){
                int HexVoltageTop = msg.data[0];
                int HexVoltageBot = msg.data[1];
                
                
                int TopVoltCharger = HexVoltageTop << 8;
                ChargerVoltage = 0 | TopVoltCharger;
                ChargerVoltage = ChargerVoltage | HexVoltageBot;
                
                if (msg.data[0] == 0x03){
                    led2 = !led2;
                }
            }
        }
        if (can2.read(msg)){
            if (can2.read(msg)) {
                printf("Charger_readsuccess\n");
                if (msg.id == 0x1806E5F4){              
                    if (msg.data[0] == 0x04){
                        led4 = !led4;
                    }
                }
            }
        }
    }
}

Yes that's possible. Please post your code so people can help you with it.

posted by Andy A 01 May 2018
  1. include "mbed.h"

Ticker ticker; DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); CAN can1(p9, p10); CAN can2(p30, p29); CANMessage msg; int ChargerVoltage;

void DummyCharger(){ int Votlage = 98; int Current = 16; int DecV = Votlage * 10; int DecC = Current * 10; int Top8V = DecV >> 8; int Top8C = DecC >> 8; int bot8var = 255; int Bot8V = bot8var & DecV; int Bot8C = bot8var & DecC; CANMessage msg;

msg.format = CANExtended; or CANExtended; standard or extended ID (can be skipped for standard) msg.id = 0x18FF50E5; msg.len = 3;length in bytes (1 to 8); msg.data[0] = Top8V; repeat for each byte. msg.data[1] = Bot8V; msg.data[2] = Top8C; msg.data[3] = Bot8C; msg.data[4] = 0; msg.data[5] = 0; msg.data[6] = 0; msg.data[7] = 0;

if (can2.write(msg)){ led1 = !led1; } };

void Send2Charger(){ int SendVoltage = ChargerVoltage + 5; int DecV2 = SendVoltage * 10; int DecC2 = 16 * 10; int Top8V2 = DecV2 >> 8; int Top8C2 = DecC2 >> 8; int bot8var = 255; int Bot8V2 = bot8var & DecV2; int Bot8C2 = bot8var & DecC2; CANMessage msg;

msg.format = CANExtended; or CANExtended; standard or extended ID (can be skipped for standard) msg.id = 0x1806E5F4; msg.len = 3;length in bytes (1 to 8); msg.data[0] = Top8V2; repeat for each byte. msg.data[1] = Bot8V2; msg.data[2] = Top8C2; msg.data[3] = Bot8C2; msg.data[4] = 0; msg.data[5] = 0; msg.data[6] = 0; msg.data[7] = 0;

if (can1.write(msg)){ led3 = !led3;} };

int main() { printf("main()\n"); ticker.attach(&DummyCharger, 1); ticker.attach(&Send2Charger, 1); CANMessage msg; while(1) { printf("loop()\n"); if (can1.read(msg)) { if (msg.id == 0x18FF50E5){ int HexVoltageTop = msg.data[0]; int HexVoltageBot = msg.data[1];

int TopVoltCharger = HexVoltageTop << 8; ChargerVoltage = 0 | TopVoltCharger; ChargerVoltage = ChargerVoltage | HexVoltageBot;

if (msg.data[0] == 0x03){ led2 = !led2; } } } if (can2.read(msg)){ if (can2.read(msg)) { if (msg.id == 0x1806E5F4){ if (msg.data[0] == 0x03){ led4 = !led4; } } } } } }

posted by Joe Capper 01 May 2018

1 Answer

6 years ago.

Hello Joe,

  • Attaching a second function to a Ticker object detaches the first one. Consequently, only the second one is getting called. So rather than

Ticker ticker;
...
    ticker.attach(&DummyCharger, 1);
    ticker.attach(&Send2Charger, 1);
...

try to use two Ticker objects.

Ticker ticker1;
Ticker ticker2;
...
    ticker1.attach(&DummyCharger, 1);
    ticker2.attach(&Send2Charger, 1);
...
  • The printf function is a "behemoth" so it takes quite a long time to execute it. Since you are polling the CAN bus for received messages in an endless loop I would recommend to remove it from there (in order not to miss some of them while printing a debug message).

...
    while(1) {
        //printf("loop()\n");
        ...
  • I think that in the code snippet below the message length should be set to 4 rather than to 3:

    ...
    msg.format = CANExtended;// or  CANExtended;  // standard or extended ID (can be skipped for standard)
    msg.id = 0x1806E5F4;
    msg.len = 3;//length in bytes (1 to 8);
    msg.data[0] = Top8V2; // repeat for each byte.
    msg.data[1] = Bot8V2;
    msg.data[2] = Top8C2;
    msg.data[3] = Bot8C2;
    msg.data[4] = 0;
    msg.data[5] = 0;
    msg.data[6] = 0;
    msg.data[7] = 0;
    ...

NOTE: To avoid messy and error prone type conversions when adding data to and extracting data from a CAN message you can give the CANMsg library a try.

Accepted Answer

Thank you, it now all works apart from the final read. I still can't seem to get the final read to work, do you know what might be happening? I've updated the code above with my new code as it is too long to post in a comment.

Thanks , Joe

posted by Joe Capper 02 May 2018

Don't worry I've fixed it, thank you for your help!

For anyone reading this thread in the future, I had an if statement inside and if statement for the same thing, deleting the embedded if statement makes it work!

posted by Joe Capper 02 May 2018