Memcpy or alternative

Hello everyone;
I'm trying to read CAN information from a device, all data comes in at once without any problems. But I want to assign each data to a variable separately, but the memcpy command gives it in one go. I use mcp2515.h library

float k ;

if (canMsg1.can_id == 0x405)
 { uint8_t weight[4] = {(canMsg1.data[1]), (canMsg1.data[2]),(canMsg1.data[3]),(canMsg1.data[4])};
     memcpy (&k, weight, 4);
    Serial.println (k);
   }

serial screen output:
2.5
3
4.6
3.4

I moved your topic to an appropriate forum category @brave33.

In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.

This is an important part of responsible forum usage, as explained in the "How to get the best out of this forum" guide. The guide contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

1 Like

Post your complete code.

2 Likes

I am unsure of what you want. Aren't canMsg1.data[x] variables?

1 Like

Are you trying to reassembly a float from four bytes received in a CAN message, without using a separate 4-byte array as an intermediate step?

1 Like

Try this

float k ;

if (canMsg1.can_id == 0x405)
  {
    memcpy (&k, &canMsg1.data[1], sizeof(k));
    Serial.println (k);
  }

If you learn more about how data is stored in RAM you would know that you have no problem with buffered bytes when you can address them relative to the buffer they are in.

The name of every array compiles the address of the start of the array. Base + 0 is base[0], etc, but once you can point you don't need the brackets.
Any 4 bytes in RAM can be read as a float, when you point to the right 4 bytes you get the right value meaning that every float saved in that buffer can be read directly without copying elsewhere. Just point and there's the right 4 bytes.

This requires learning the first few things about pointers which is not a beginner subject but your code needs just the start, address and offset.

When you break through the veil of syntax and see the simple underside, code gets easier to understand.

Add: I just need to get past the C++ hall Monitor.

1 Like

It depends on whether there is actually a float object at that location. If not (even if the bit pattern present can be reinterpreted as a float), the strict aliasing rule is violated, which leads to undefined behaviour.

1 Like

Thank you all. I get the same output, if I need to write more clearly I found the memcpy command by accident, I'm a bit of a beginner. My exact goal is this:
Assigning the numbers appearing on the serial screen to a separate variable and using them in my code.
for example:
2.5 ......> a
3 .......> b
4.6 .......> c
3.4 .......> d

float a;
float b;
float c;
float d;

No, that's probably not a good idea, leading to unnecessarily long, repetitive code. An array might be better. Tell us more about how these values arrive and how you want to use them in your code.

These values come from a device as CAN data, there are 4 different weight data, and I want to assign these 4 different weight data to separate variables and use them, I hope it was explanatory.
Serial screen output comes as 4 separate values at the same time as seen,
I for example float the value 2.5 a; I want to assign it to a variable, so how can I do it as an array?

2.5 ......>float a;
3 .......> float b;
4.6 .......> float c;
3.4 .......> float d;

#include <mcp2515.h>
struct can_frame canMsg1;
MCP2515 mcp2515(53);

float k ;

void setup() {
  Serial.begin(38400);
  mcp2515.reset();
  mcp2515.setBitrate(CAN_250KBPS, MCP_8MHZ);
  mcp2515.setNormalMode();
}
void loop() {

  if (mcp2515.readMessage(&canMsg1) == MCP2515::ERROR_OK) 
  { 
   // if (canMsg1.can_id == 0x405)
   // { uint8_t weight[4] = {(canMsg1.data[1]), (canMsg1.data[2]), (canMsg1.data[3]), (canMsg1.data[4])};
   //   memcpy (&k, weight, 4);
   //   Serial.println (k);
   // }
  
  if (canMsg1.can_id == 0x405)
  {
    memcpy (&k, &canMsg1.data[1], sizeof(k));
    Serial.println (k);
  }
  }
}

I guess as you said, but I don't know how to use array.

Do all 4 come in the same message or in different messages?

No, it wasn't. You haven't said why you want to use separate variables or how you will use them. These details are important for figuring out the best way to deal with them.

Maybe like this

float k[4];
...
    memcpy (&k[0], &canMsg1.data[1], sizeof(k[0]));
    Serial.println (k[0]);
...

But for this to be preferable over using 4 separate variables depends on how you get all 4 values and what you do with them after.

All 4 come from the same message, just like I shared in the code. I am trying to develop my code, the reason why I want to use 4 different weight data separately is because I want to save them separately in the continuation of the code and perform mathematical operations with them. For example, plus the variables a-b-c-d, or minus the variable a from the variable d...

I tried, again 4 different values came at once.

Ok, thanks for sharing that. It was not clear from your previous explanations.

No, in the code you shared, the message contained only one value. Now you are saying it contains 4 values. Please share more details of how the other 3 values can be extracted from the message.

If you are talking about my 11th message, I only gave the first value 2.5 as an example, but as you can see at the top, there are 4 values underneath. Again, the lines with // in the code I shared in my 11th message are the lines I wrote before, but the other active lines are the lines you gave me. So I get the same output from both.

I tried the value of canMsg1.data[1] , [1] here as 2-3-4 and my outputs are always
0.0
0.0
0.0
0.0
it happened.
I guess it's just data from data[1], for example
2.5
3
4.6
3.4

I'm sorry, but your last post made no sense to me. Please try to be more precise. :slight_smile: Post the code you used in each test and describe the output you saw.

I guess it didn't happen because of the language translation, thank you very much for your patience. (: