craspberry-pi3can-bussocketcan

Problems with sending EFF 29-bit ID message over SocketCAN


I am trying to send 29-bit EFF (Extended Frame Format) CAN messages over SocketCAN, but for some reason, it sends them with the 11-bit identifier, cutting off five bytes from the ID. Using loopback mode, through candump, I can see that messages are received as 11 bit.

I don't get any errors, nothing. That’s why I am confused.

I am using Raspberry Pi 3B+ if that makes any difference. And the Can-utils library.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <linux/can.h>
#include <linux/can/raw.h>

#include </home/pi/can-utils/lib.h>

int main(int argc, char **argv)
{
    int s, loop = 1;
    int nbytes;
    struct sockaddr_can addr;
    struct can_frame frame;
    struct ifreq ifr;

    // CAN interface

    if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
        perror("socket");
        return 1;
    }

    strcpy(ifr.ifr_name, "can0");
    if(ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
        perror("SIOCGIFINDEX");
        return 1;
    }

    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("bind");
        return 1;
    }

    // Data send loop

    while(loop) {
        int g;

        for (int e = 0; e < 1020; e++) {
            if(e < 10) {
                g = 0;
            }
            else if (e%100 == 0) {
                g = 1;
            }
            else if (e%50 == 0) {
                g = 2;
            }
            else if (e%20 == 0) {
                g = 3;
            }

            if (g == 0) {
                switch(e) {

                    case 1: // Total fuel used 5-8
                        frame.can_id = 0x0000FEE9;
                        printf("value %X", frame.can_id);
                        frame.can_dlc = 8;
                        frame.data[0] = 0x00;
                        frame.data[1] = 0x00;
                        frame.data[2] = 0x00;
                        frame.data[3] = 0x00;
                        frame.data[4] = 0xF5; // 0.5 l/bit
                        frame.data[5] = 0x06; // 0.5 l/bit
                        frame.data[6] = 0x07; // 0.5 l/bit
                        frame.data[7] = 0x08; // 0.5 l/bit
                        break;

                    case 2: // Fuel level 2
                        frame.can_id = 0x0000FEFC;
                        frame.can_dlc = 8;
                        frame.data[0] = 0x00;
                        frame.data[1] = 0x88; // 0.4%/bit
                        frame.data[2] = 0x00;
                        frame.data[3] = 0x00;
                        frame.data[4] = 0x00;
                        frame.data[5] = 0x00;
                        frame.data[6] = 0x00;
                        frame.data[7] = 0x00;
                        break;

                    case 3: // Total engine hours 1-4
                        frame.can_id = 0x0000FEE5;
                        frame.can_dlc = 8;
                        frame.data[0] = 0x11; // 0.05 h/bit
                        frame.data[1] = 0x22; // 0.05 h/bit
                        frame.data[2] = 0x33; // 0.05 h/bit
                        frame.data[3] = 0x44; // 0.05 h/bit
                        frame.data[4] = 0x00;
                        frame.data[5] = 0x00;
                        frame.data[6] = 0x00;
                        frame.data[7] = 0x00;
                        break;

                    case 4: // Milleage 1-4
                        frame.can_id = 0x0000FEC1;
                        frame.can_dlc = 8;
                        frame.data[0] = 0x44; // 5 miles/bit
                        frame.data[1] = 0x33; // 5 miles/bit
                        frame.data[2] = 0x22; // 5 miles/bit
                        frame.data[3] = 0x11; // 5 miles/bit
                        frame.data[4] = 0x00;
                        frame.data[5] = 0x00;
                        frame.data[6] = 0x00;
                        frame.data[7] = 0x00;
                        break;

                    case 5:
                        frame.can_id = 0x0000FEEE; // Engine temperature 1
                        frame.can_dlc = 8;
                        frame.data[0] = 0xCC; // 1 C/bit -40 C offset
                        frame.data[1] = 0x00;
                        frame.data[2] = 0x00;
                        frame.data[3] = 0x00;
                        frame.data[4] = 0x00;
                        frame.data[5] = 0x00;
                        frame.data[6] = 0x00;
                        frame.data[7] = 0x00;
                        break;

                    case 6: // Ambient temperature 4-5
                        frame.can_id = 0x0000FEF5;
                        frame.can_dlc = 8;
                        frame.data[0] = 0x00;
                        frame.data[1] = 0x00;
                        frame.data[2] = 0x00;
                        frame.data[3] = 0xE4; // 0.03125 C/bit -273 C offset
                        frame.data[4] = 0xF2; // 0.03125 C/bit -273 C offset
                        frame.data[5] = 0x00;
                        frame.data[6] = 0x00;
                        frame.data[7] = 0x00;
                        break;

                    case 7: // High res fuel 5-8
                        frame.can_id = 0x0000FD09;
                        frame.can_dlc = 8;
                        frame.data[0] = 0x00;
                        frame.data[1] = 0x00;
                        frame.data[2] = 0x00;
                        frame.data[3] = 0x00;
                        frame.data[4] = 0x01; // 0.001 l/bit
                        frame.data[5] = 0x02; // 0.001 l/bit
                        frame.data[6] = 0x03; // 0.001 l/bit
                        frame.data[7] = 0x04; // 0.001 l/bit
                        break;

                    case 8: // Vehicle weight 2-3
                        frame.can_id = 0x0000FEEA;
                        frame.can_dlc = 8;
                        frame.data[0] = 0x00;
                        frame.data[1] = 0x05; // 0.5 kg/bit
                        frame.data[2] = 0xFF; // 0.5 kg/bit
                        frame.data[3] = 0x00;
                        frame.data[4] = 0x00;
                        frame.data[5] = 0x00;
                        frame.data[6] = 0x00;
                        frame.data[7] = 0x00;
                        break;

                    case 9: // Distance before service 2-3
                        frame.can_id = 0x0000FEC0;
                        frame.can_dlc = 8;
                        frame.data[0] = 0x00;
                        frame.data[1] = 0xEF; // 5 km/bit -160 635 km offset
                        frame.data[2] = 0xCD; // 5 km/bit -160 635 km offset
                        frame.data[3] = 0x00;
                        frame.data[4] = 0x00;
                        frame.data[5] = 0x00;
                        frame.data[6] = 0x00;
                        frame.data[7] = 0x00;
                        break;

                    default:
                        break;
                }

                for(int i = 0; i <1; i++) {
                    if ((nbytes = write(s, &frame, sizeof(struct can_frame))) != sizeof(frame)) {
                    }
                }
            }

            if (g == 1) {
                for(int l = 1; l < 5; l++) {
                    switch(l) {

                        case 1: // EEC 3-5
                            frame.can_id = 0x000CF004;
                            frame.can_dlc = 8;
                            frame.data[0] = 0x00;
                            frame.data[1] = 0x00;
                            frame.data[2] = 0xEE; // Torque 1%/bit -125% offset
                            frame.data[3] = 0xEF; // RPM 0.125/bit
                            frame.data[4] = 0x12; // RPM 0.125/bit
                            frame.data[5] = 0x00;
                            frame.data[6] = 0x00;
                            frame.data[7] = 0x00;
                            break;

                        case 2: // Fuel economy 1-4
                            frame.can_id = 0x0000FEF2;
                            frame.can_dlc = 8;
                            frame.data[0] = 0xEC; // Fuel rate (0.05l/h)/bit
                            frame.data[1] = 0xFF; // Fuel rate (0.05l/h)/bit
                            frame.data[2] = 0x15; // Current fuel (1/512km/l)/bit
                            frame.data[3] = 0xE5; // Current fuel (1/512km/l)/bit
                            frame.data[4] = 0x00;
                            frame.data[5] = 0x00;
                            frame.data[6] = 0x00;
                            frame.data[7] = 0x00;
                            break;

                        case 3:  // Wheel speed 2-3
                            frame.can_id = 0x0000FEF1;
                            frame.can_dlc = 8;
                            frame.data[0] = 0x00;
                            frame.data[1] = 0x01; // (1/256 km/h)/bit
                            frame.data[2] = 0x99; // (1/256 km/h)/bit
                            frame.data[3] = 0x00;
                            frame.data[4] = 0x00;
                            frame.data[5] = 0x00;
                            frame.data[6] = 0x00;
                            frame.data[7] = 0x00;
                            break;

                        case 4: // EEC2 2-3
                            frame.can_id = 0x0000F003;
                            frame.can_dlc = 8;
                            frame.data[0] = 0x00;
                            frame.data[1] = 0x03; // 0.4%/bit accelerator position
                            frame.data[2] = 0x55; // 1%/bit engine load
                            frame.data[3] = 0x00;
                            frame.data[4] = 0x00;
                            frame.data[5] = 0x00;
                            frame.data[6] = 0x00;
                            frame.data[7] = 0x00;
                            break;
                    }

                    for(int i = 0; i <1; i++) {
                        if ((nbytes = write(s, &frame, sizeof(struct can_frame))) != sizeof(frame)) {
                        }
                    }

                    if(l < 5)
                        usleep(1000);
                }
            }
            else if (g == 2) {

                frame.can_id = 0x0000F003;
                frame.can_dlc = 8;
                frame.data[0] = 0x00;
                frame.data[1] = 0x03; // 0.4%/bit accelerator position
                frame.data[2] = 0x55; // 1%/bit engine load
                frame.data[3] = 0x00;
                frame.data[4] = 0x00;
                frame.data[5] = 0x00;
                frame.data[6] = 0x00;
                frame.data[7] = 0x00;

                for(int i = 0; i <1; i++) {
                    if ((nbytes = write(s, &frame, sizeof(struct can_frame))) != sizeof(frame)) {
                    }
                }
            }
            else if (g == 3) {

                frame.can_id = 0x0000F004;
                frame.can_dlc = 8;
                frame.data[0] = 0x00;
                frame.data[1] = 0x00;
                frame.data[2] = 0xEE; // Torque 1%/bit -125% offset
                frame.data[3] = 0xEF; // RPM 0.125/bit
                frame.data[4] = 0x12; // RPM 0.125/bit
                frame.data[5] = 0x00;
                frame.data[6] = 0x00;
                frame.data[7] = 0x00;

                for(int i = 0; i <1; i++) {
                    if ((nbytes = write(s, &frame, sizeof(struct can_frame))) != sizeof(frame)) {
                    }
                }
            }

            usleep(10000);
            g = 5;
            if(e == 900)
                e = 0;
        }
    }

    close(s);
    return 0;
}

Solution

  • You need to add the correct flag after setting can_id:

    frame.can_id |= CAN_EFF_FLAG;
    

    Or for example: Instead of

    frame.can_id = 0x0000FEE9
    

    use

    frame.can_id = 0x0000FEE9U | CAN_EFF_FLAG;
    

    Here U signifies that your integer literal is unsigned. Also see can.h.