I'm trying to create a CAN bus message which is a 64 bit binary frame held in a uint64_t variable.
I have 8 variables which I want to send, one per byte
In this case I have:
SideLights = 1 or 0
MainLights = 1 or 0
HighLights = 1 or 0
HazLights = 1 or 0
IndLLights = 1 or 0
IndRLights = 1 or 0
RFogLights = 1 or 0
FFogLights = 1 or 0
If they were all set to 1, then the message I'd want to send is: 00010001000100010001000100010001
How do I make this conversion? There will be other frames I need to send where the variable may be a number rather than a 1 or a 0 so I need something that works fairly universally. The number of variables per frame will always be 8 however (1 per byte).
Didn't we cover this basic concept to death in another of your threads? It's a matter of setting bits in a variable, which is a mundane and ages old non-problem.
May I ask (actually anybody would ask) why you can't just place the bits consecutively, like
......000000000000000000011111111
Because CAN device at the other end assigns a variable to each byte in the frame. So it will read the whole 64 bit frame then split it into 8 bytes before reading the value of each as a decimal variable.
My thought was to use bitshifting, so I have built this:
Oh yes you are right! My mistake, thanks John. The CAN_SEND routine that I am using accepts a 64-bit number as I call it a few different times. In order to not modify this routine it would be helpful to pre-process the data packet into the format you show above. If I were doing this, would bitshifting be the right way to do it as I've attempted to do?
Hmmm. I can't recall if you participated in the same discussion in the other thread. In that one, and others, unions have been identified as producing undefined behavior when used this way, and non-portable due to undefined implementation details.
But the whole horse was beaten to a pulp already over there.
It's all a matter of use case. If you want to just make something work today on today's Arduino, why not? I did that a few times. I wouldn't use it for anything that I would publish or push forward into other projects...
I'm pretty sure that bit shifting is optimized by the compiler. Especially, a shift by 8 bits. That would translate into a fairly efficient series of byte moves for the case that is presented here.
Again, horse so dead, the flies are buzzing. Should have left it alone...
memcpy was discussed there, so it's worth a look. The question is not, does it work, it's can you depend on it to always work. That includes, can you implement it safely in all circumstances, including those you can't anticipate?
The mechanism of a raw memory move, vs. a raw conversion by pointer or union, only differs in method. Neither offers the assurance of data alignment that is offered by bit shifting. That is because it's (for better or worse) the only thing that is guaranteed by the language specification.