11 years, 3 months ago.

Why do I lose data when i write in can bus?

Hello, I send some data with different ID, but if I don't put a wait() between the different can.write()I'll lose some data and some of them are written more times instead of one. Can someone explain me that? Here's my code:

while(1){
if(can1.write(CANMessage(20, mypos.bytes, 4))) {
        }
        wait(WAIT_TIME);
        if(can1.write(CANMessage(21, mypos_vel.bytes, 4))) {
        }
        wait(WAIT_TIME);
        if(can1.write(CANMessage(22, mypos_acc.bytes, 4))) {
        }
        wait(WAIT_TIME);
        if(can1.write(CANMessage(23, mypos_count.bytes, 4))) {
        }
        wait(WAIT_TIME);
        if(can1.write(CANMessage(24, myrot.bytes, 4))) {
        }
        wait(WAIT_TIME);
        if(can1.write(CANMessage(25, myrot_vel.bytes, 4))) {
        }
        wait(WAIT_TIME);
        if(can1.write(CANMessage(26, myrot_acc.bytes, 4))) {
        }
        wait(WAIT_TIME);
        if(can1.write(CANMessage(27, myrot_count.bytes, 4))) {
        }
        wait(WAIT_TIME);

        if(can1.write(CANMessage(29, mytime.bytes, 4))) {
        }
        wait(WAIT_TIME);
    }
}

1 Answer

11 years, 3 months ago.

You are probably losing data due to your CAN transmit buffers being full when you try to write a CAN message to them. The can.write command passes data to the transmit buffer, the CPU then moves on to it's next command and lets the CAN peripheral do the work of controlling the hardware. This takes a certain amount of time based on the speed of the bus and amount of traffic.

This means that multiple messages can be written to the transmit buffer before the previous message has been sent. The CAN peripheral does have a queue implemented, but this only gives space for three messages (I'm, guessing the first three messages are always transmitted).

If you are wanting to wait until the last message has been sent you can wait() or you can set up a while loop that checks the status of the CAN Global Status Register (CAN1GSR) or the Central Transmit Status Register (CANTxSR) as these contain bits for transmission status for each CAN controller.

Also you if statements aren't doing anything, just adding to the delay, if the compiler isn't optimizing them out.

Accepted Answer