I was able to get the data from Schneider PM5560 power meter via modbus RS485. but having difficulty in interpreting that data.
i wanted to read register 3035 which has a Data type of float 32. this is the code i am using
Now if we combine hex values 437A and DD60 we get 437ADD60 and converting it to floating point we get 250.860, which is required as meter is giving this value on its screen.
Thanks @bobcousins, i used seoftwareserial and designate other pins to Rx, Tx, and it started working fine. @gcjr
I want to read multiple registers but as soon as I try reading other register all the register values comes out to be 0. (Note: only at the start after 10,15 values of 0 actual values do comes up once only).
i wish you could have noted this issue but tried answering the question
i may find my answer here, but i think it's attempting to be efficient by copying words and needs to deal with the stray bytes at the ends of the copy regions
I can’t speak to the platform-specific implementations of memcpy(). The point of my Post #7 was that casting a ‘float *’ to ‘uint16_t *’ and then dereferencing the latter is not legal C++ code. As pointed out in the post I linked, the rules of reinterpret_cast on pointers are complex, especially if the result of the cast is dereferenced.
There are a few cases where it’s legal and of those the only ones I use are:
Cast a pointer to a ‘void *’ and then back to the original pointer type. You may then dereference it once it’s cast back. This might be necessary when using ‘C-type’ interfaces such as the API calls in ESP32’s FreeRTOS. Also, some platforms and libraries support defining a ‘void *’ parameter that’s passed to an ISR or Callback Function. It can be cast back to a pointer to the original type in the ISR / Callback and then deferenced. Obviously, the ISR / Callback must know what that original type was.
Cast a pointer to a ‘uint8_t *’ (aka a Byte pointer). You may then deference that to access the byte representation of the original object (both examine and modify). This is why memcpy() is legal. Note that I don’t think it’s legal to go the other way … you can’t cast a byte array to a ‘float *’ and then dereference it as a float.
if you don't mind, i'd like to understand this better. i'm not trying to pick a fight
especially after looking at torvald's code, it looks like the issue is alignment, that if not careful, a pointer might be improperly aligned for some specific variable type. for example, a pointer to a float is set to a pointer to a char where the char pointer is not word (4 byte) aligned. is this correct?
and if doing things like this is illegal, why does the compiler accept without warning the use of casts such as
char c;
float *f = (float*) &c;
does it really come down to some knowledgeable review saying "you shouldn't do that"?
I would think the result of doing that is platform-specific. It might range for inefficient access of the float variable all the way to the hardware throwing and exception.
I know there are dozens of compiler flags that can be set / unset. Perhaps there's on (or a combination of ones) that will kick out a warning for that. Try a web search for the warning "dereferencing type-punned pointer will break strict-aliasing rules"
It's not illegal, but undefined behaviour. There are many undefined behaviours. I think a conforming C++ compiler is not required to generate warnings for undefined behaviour.
There are many 3rd party C++ analysis tools which do a much better job flagging potentially risky code, but even those may not cover everything.
In a recent project high integrity project I worked on, you can imagine how much fun it was checking every line of code for undefined and implementation defined behaviour, analysing the results, modifying the code or writing a justification of why the code was acceptable.
Why not? A 32-bit processor accesses memory 4 bytes at a time on 32-bit address boundaries. So, accessing a misaligned float will require two memory accesses instead of one ---> less efficient.
Also, don’t you think that at 32-bit (or 64-bit) processor with a hardware Floating Point peripheral could possibly get upset (even to to the point of throwing an exception) accessing a misaligned float?
Did you try it? It works as expected for me using memcpy():
yes, absolutely. but isn't that an alignment problem not a hardware/platform problem?
yes of course
but you're copying the data to a float, not (misusing) an unaligned pointer to a float as a demonstration of the problem i believe is why doing something like this is "illegal" or "undefined"