Arduino - Convert 4 X Uint8 To 1 X Uint32 - EEVblog

EEVblog Electronics Community Forum A Free & Open Forum For Electronics Enthusiasts & Professionals Welcome, Guest. Please login or register.Did you miss your activation email? 1 Hour 1 Day 1 Week 1 Month Forever Login with username, password and session length This topic This board Entire forum Google Bing
  • EEVblog Electronics Community Forum »
  • Electronics »
  • Microcontrollers »
  • Arduino - Convert 4 x uint8 to 1 x uint32
« previous next »
  • Print
  • Search
Pages: [1] 2 Next All Go Down

Author Topic: Arduino - Convert 4 x uint8 to 1 x uint32 (Read 9059 times)

0 Members and 1 Guest are viewing this topic.

Offline kolbepTopic starter

  • Frequent Contributor
  • **
  • Posts: 601
  • Country: za
    • ShoutingElectronics.com
Arduino - Convert 4 x uint8 to 1 x uint32
« on: January 28, 2020, 07:13:35 pm » Hi All.So I am Interfacing a PZEM16 Modbus Power Meter Module to an Arduino nano, and so far I have got it working ok. I am just having problems converting the 8 Bit Register Returns into 32 Bit Integers.It works fine at low current, but as soon as the current increases over a few amps, I start getting a display of 40000 + Amps.Here is the Relevant Section of code where it receives all the registers from the moduleCode: [Select] while (mySerial.available()) { int countr = countr + 1; buffer[countr] = mySerial.read(); containsdata = 1; };And here is when I try to convert it to 32 Bit Integers, to make it easier for Display on the Serial, LCD, and logging to file :Code: [Select] if (containsdata) { uint16_t rvoltage = (buffer[4] << 8) | buffer[5]; uint32_t rcurrent = (buffer[6] << 8) | buffer[7] | (buffer[8] << 24) | (buffer[9] << 16); uint32_t rcurrent = (buffer[6] << 8) | buffer[7]; uint32_t rpower = (buffer[10] << 8) | buffer[11] | (buffer[12] << 24) | (buffer[13] << 16); uint32_t renergy = (buffer[14] << 8) | buffer[15] | (buffer[16] << 24) | (buffer[17] << 16); uint32_t rfreq = (buffer[18] << 8) | buffer[19]; uint32_t rpf = (buffer[20] << 8) | buffer[21]; float pvoltage = float(rvoltage) / 10; float pcurrent = float(rcurrent) / 1000; float ppower = float(rpower) / 10; float penergy = float(renergy); float pfreq = float(rfreq) / 10; float ppf = float(rpf) / 100; Serial.print("-----------------------------------"); Serial.println(rcurrent); Serial.print(pvoltage, 1); Serial.print(F("V ")); Serial.print(pcurrent, 3); Serial.print(F("A ")); Serial.print(ppower, 1); Serial.print(F("W ")); Serial.print(penergy, 1); Serial.print(F("E ")); Serial.print(pfreq, 1); Serial.print(F("hz ")); Serial.print(ppf, 2); Serial.print (F("pf ")); Serial.println();From what I understand (From the Attached Register Listing), Element 1 2 and 3 in the Array are irrelevant, they are just the Slave Address, etc. {They are not shown in this table, but from the rest of the Datasheet it makes sense}that Element 5 is the Low Byte for Voltage, Element 4 is the High Byte for Voltage. And for current, Element 7 Is Low Byte, Element 6 is the High Byte, Element 9 is the High Bytes Low, and Element 8 is the High Bytes High.Even as I am typing this out, I am confused.Please can somebody check this code, and the Image of Register Listings, and help me out.Thanks « Last Edit: January 28, 2020, 07:15:41 pm by kolbep » Logged ====================================www.ShoutingElectronics.com Don't just talk about Electronics, SHOUT ABOUT IT! Electronics Blog Site and Youtube Channel

Offline RoGeorge

  • Super Contributor
  • ***
  • Posts: 7995
  • Country: ro
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #1 on: January 28, 2020, 07:23:05 pm » - identify the indian-ness type for your uint32 representation- use "union" to easily read the same memory location(s) either as uint8 or as uint32- never start talking with "so", "so" is for conclusion, not for explaining a situation Logged https://hackaday.io/RoGeorgehttps://rogeorge.wordpress.com

Offline kolbepTopic starter

  • Frequent Contributor
  • **
  • Posts: 601
  • Country: za
    • ShoutingElectronics.com
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #2 on: January 28, 2020, 08:21:09 pm » I think I have just made some headway.In my Global Variable Declaration I had Code: [Select]byte buffer[25];changed it to Code: [Select]unsigned int buffer[25];and now it seems to be better, more accurately tracking the load Logged ====================================www.ShoutingElectronics.com Don't just talk about Electronics, SHOUT ABOUT IT! Electronics Blog Site and Youtube Channel

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 10026
  • Country: us
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #3 on: January 28, 2020, 11:13:54 pm » I sure wonder aboutCode: [Select]while (mySerial.available()) { int countr = countr + 1; buffer[countr] = mySerial.read(); containsdata = 1; };countr is not initialized to zero nor is it static. countr will be allocated on the stack and the stack contains random values. I'm not sure how it would work out.Since you have it working, maybe this doesn't matter. Logged

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1803
  • Country: us
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #4 on: January 29, 2020, 01:56:52 am » Quote from: kolbep on January 28, 2020, 08:21:09 pm
I think I have just made some headway.In my Global Variable Declaration I had Code: [Select]byte buffer[25];changed it to Code: [Select]unsigned int buffer[25];and now it seems to be better, more accurately tracking the load
Good.In general, you want to post a complete reproduction case when asking for help, rather than eliding the code and only posting the "relevant" portion (which in this case was a necessary but not sufficient subset). Logged

Offline Renate

  • Super Contributor
  • ***
  • Posts: 1460
  • Country: us
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #5 on: January 29, 2020, 03:36:27 pm » Quote from: RoGeorge on January 28, 2020, 07:23:05 pm
Never start talking with "so", "so" is for conclusion, not for explaining a situation.
So what. :PGenerally I'd take Modbus in on a uint8_t buffer.If you're using "switch" or "coil" there could be an odd number of bytes.OTOH, if in a specific case it's all registers then uint16_t could be easier.(I still wouldn't do it.)As you've shown already, Modbus is high byte, low byte order.It seems that usage of multiple words by implementers tends to be low word (16bit), high word.I think that I'll pick up one of these.I guess that you can only set address by putting it on a standalone wire and writing the address register there? Logged

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1968
  • Country: us
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #6 on: January 29, 2020, 05:57:29 pm » Quote from: RoGeorge on January 28, 2020, 07:23:05 pm
use "union" to easily read the same memory location(s) either as uint8 or as uint32
Be very careful with this technique. It relies on having an absolute understanding of how your compiler of choice handles structures/unions, and in particular how it handles packing. That can vary from compiler to compiler, and even revision to revision of the same compiler. Don't ask what it cost me to learn that.For some background on the topic, you can start with: http://www.catb.org/esr/structure-packingTo the OP: I strongly suggest taking the time to better understand your data, and then manually write safe routines to rearrange it as desired. You assume your compiler does, and later will continue to, handle such conversions at your peril. Logged

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17254
  • Country: fr
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #7 on: January 29, 2020, 06:13:52 pm » A note - knowing the endianness of your target, and provided that it's the same as your data, you can safely "read" from or "write" to a buffer of uint8_t as a uint32_t... as long as there is no alignment problem! Many small MCUs don't support unaligned accesses, so you can only do this if the data is properly aligned. So, that's a first potential trap. The second one is of course if the endianness is not the same, then obviously you can't do that, or you'd have to reverse the bytes, which you might as well do directly.If you're using structs to "map" data, you need to be careful about alignment as well. As said above, first make sure the various fields are "packed" (meaning not padded), compilers usually have attributes for that. An older, but usually supported by most compilers, way of enforcing this is to use "#pragma pack(...)" directives. But exactly as with the above, you could still encounter unaligned access problems.Consider this struct for instance (GCC attributes):Code: [Select]struct __attribute__((__packed__, aligned(4))){ int32_t A; int16_t B; int32_t C;};If the target is 32-bit and doesn't support unaligned accesses, you'll have a problem. Accessing A will be OK. Accessing B will be OK. Accessing C will not. « Last Edit: January 29, 2020, 06:15:29 pm by SiliconWizard » Logged

Offline RoGeorge

  • Super Contributor
  • ***
  • Posts: 7995
  • Country: ro
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #8 on: January 29, 2020, 08:04:55 pm » Quote from: IDEngineer on January 29, 2020, 05:57:29 pm
Quote from: RoGeorge on January 28, 2020, 07:23:05 pm
use "union" to easily read the same memory location(s) either as uint8 or as uint32
Be very careful with this technique. It relies on having an absolute understanding of how your compiler of choice handles structures/unions, and in particular how it handles packing. That can vary from compiler to compiler, and even revision to revision of the same compiler. Don't ask what it cost me to learn that.For some background on the topic, you can start with: http://www.catb.org/esr/structure-packing
Not sure where to look. That is a link to more than 5 thousand words about structures, nothing about unions. In fact, the unions are mentioned as much safer, yet not discussed there.I was thinking about a conversion like in the following example. The advantage is that there are no additional operations, and can be used for either ui32 to ui8[4] or ui8[4] to ui32.Code: [Select]...union ui32or4xui8 { uint32_t as32bitsTogether; uint8_t[4] as8bitsByte;};...int main() {... union ui32or4xui8 myNumber;... /* write ui32, read each ui8 */ myNumber.as32bitsTogether = 0xDEADBEEF; printf("%x", myNumber.as8bitsByte[0]); printf("%x", myNumber.as8bitsByte[1]); printf("%x", myNumber.as8bitsByte[2]); printf("%x", myNumber.as8bitsByte[3]);... /* write each ui8, read as ui32 */ myNumber.as8bitsByte[0] = 0xB0; myNumber.as8bitsByte[1] = 0xB1; myNumber.as8bitsByte[2] = 0xB2; myNumber.as8bitsByte[3] = 0xB3; printf("%x", myNumber.as32bitsTogether);...}AFAIK, all union members are guaranteed to start at the same address, and an uint8 vector is never padded between the elements.Can you please give an example of architecture/compiler/settings where the above union is not safe (assuming we know the endianness)? Logged https://hackaday.io/RoGeorgehttps://rogeorge.wordpress.com

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17254
  • Country: fr
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #9 on: January 29, 2020, 08:26:17 pm » Quote from: RoGeorge on January 29, 2020, 08:04:55 pm
AFAIK, all union members are guaranteed to start at the same address, and an uint8 vector is never padded between the elements.
Although that is a reasonable assumption, the real problem is not so much with the start address. There still isn't any formal guarantee that writing to an union member will be reflected as is if reading another union member afterwards.Standard C99 says:Quote
" With one exception, if the value of a member of a union object is used when the mostrecent store to the object was to a different member, the behavior isimplementation-defined.One special guarantee is made in order to simplify the use ofunions: If a union contains several structures that share a common initial sequence (seebelow), and if the union object currently contains one of these structures, it is permitted toinspect the common initial part of any of them anywhere that a declaration of thecompleted type of the union is visible."
In your example, the union contains two members that are themselves not structures. So the behavior is actually implementation-defined as per the standard.Whereas it will do as you expect with many C compilers for many different targets, there is just no guarantee. It's implementation-defined, meaning that by nature it's not portable code.Now for programming specific MCU targets with a specific compiler, you may rely on the implementation doing that correctly as long as you checked it did. Just be aware that it's not, by definition, portable.(And yes, we may argue that any implementation that would not guarantee this would be pretty twisted, but the standard still considers this possible.) « Last Edit: January 29, 2020, 08:32:11 pm by SiliconWizard » Logged The following users thanked this post: RoGeorge

Offline RoGeorge

  • Super Contributor
  • ***
  • Posts: 7995
  • Country: ro
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #10 on: January 29, 2020, 09:34:58 pm » I thought that type conversion through a union is a trick, but it even has a name "union type punning". :)https://stackoverflow.com/questions/25664848/unions-and-type-punningSome are saying it's working fine. Some don't like it.Seems like the software world is still arguing about union type punning, but coming from the hardware world, I see no reason why it shouldn't work for a simple 32 <-> 4x8 bits (again, apart from reasons like endianness, compiler optimisations that can be fixed by using volatile, or obvious causes like "manually" writing consecutive uint8 values in an array will not be atomic operations from the viewpoint of a 32 bits read, etc).I know the "I see no reason" is not a proof for "there is no reason", but still feels like an urban legend.Does anybody have an example where union type punning of uint32 and uint8[4] behave different than expected? Logged https://hackaday.io/RoGeorgehttps://rogeorge.wordpress.com

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1883
  • Country: se
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #11 on: January 29, 2020, 10:50:52 pm » Quote from: RoGeorge on January 29, 2020, 09:34:58 pm
Some are saying it's working fine. Some don't like it.Does anybody have an example where union type punning of uint32 and uint8[4] behave different than expected?
Under a quite relaxed set of constraints, that specific example of type punning is perfectly fine.The only condition to verify is that sizeof(uint32_t) == 4.Just to make sure, let's see how I derive this conclusion, from the C99 standard:First of all, we are guaranteed that there are no padding bits or bytes:Both uint8_t and uint32_t are exact-width integer types.As a typedef, uint8_t it cannot be smaller than the smaller integer type, char, and is unsigned so there's no alternative for it to be anything else that unsigned char (7.18.1.1), with size 1 by definition.Chapter 6.2.6.1 (Representation of types - General) states in §4:Quote
Values stored in non-bit-field objects of any other object type consist of n × CHAR_BITbits, where n is the size of an object of that type, in bytes. The value may be copied intoan object of type unsigned char [n] (e.g., by memcpy); the resulting set of bytes iscalled the object representation of the value.
This is a guarantee that any object value can be represented in a sequence of unsigned chars. It does not guarantee, in general, that any value of the sequence corresponds to a valid object (trap representations), but in our case:- There is no padding- All the bit combination in an uint32_t (sized 4) are then a valid value, as a consequence of 6.2.6.2 Integer types, §4So no trap representation is possible.Similar consideration can be made in other cases, as an example, if instead of uint32_t we consider int32_t, we must add another constraint:The implementation must use two's complement integer representation.If this is not verified (one's complement or sign magnitude) the bit pattern for negative 0 might be a trap representation.As both the representation and the trap status of negative 0 are implementation-defined, they must be documented by the compiler.Now, endianness is a different matter...but still must be documented, as is part of the implementation-defined behaviour (J.3.13 Architecture).EtA: It must be said that if type punning is done to "optimize" the code, it is mostly a wasted effort.Much better use explicit shifts: if they match endiannes, they are optimized away, if they do not, type punning would introduce a bug. « Last Edit: January 29, 2020, 11:10:44 pm by newbrain » Logged Nandemo wa shiranai wa yo, shitteru koto dake. The following users thanked this post: RoGeorge

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1968
  • Country: us
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #12 on: January 29, 2020, 11:28:52 pm » Quote from: newbrain on January 29, 2020, 10:50:52 pm
First of all, we are guaranteed that there are no padding bits or bytes:Both uint8_t and uint32_t are exact-width integer types.
The latter statement is true. The former statement may NOT be true, which is why you must be careful. 32 bit values may be required by the processor architecture to be aligned on a word or dword boundary. If you lead with a char, there could be padding to align an immediately following word or dword.Note you can always read or write multibyte entities as bytes. It's going the other way that may be a problem (reading multiple individual bytes as a word, dword, etc.). If your base address is not aligned for the size of read/write you're requesting you can get anything from no effect, to additional cycles as the CPU silently accommodates the misalignment, to a fault as noted in that article I cited. When I used to write Assembly language for the x86 family we had to pay careful attention to data alignment to maximize performance for exactly this reason.Quote
Now, endianness is a different matter...but still must be documented, as is part of the implementation-defined behaviour (J.3.13 Architecture).
So far I've seen people only mention endianness at the byte level. However, be careful with some sensors which can (optionally, if you're lucky!) reverse the BIT order within their output bytes. The most recent time I saw this was in an accelerometer+gyro MEMS chip; the data could be reordered in almost any way, with reversal within each byte as well as reordering of the bytes themselves in the 16-bit values. I suspect this was done to assist with implementing FFT's since those can involve bit-level reversal, and that's not an operation commonly found in non-DSP cores so offering it in the hardware could yield a performance boost on general purpose CPU's.My bottom line for stuff like this: Write the code and step through it with the debugger, line by line, examining all of the data at each step to make positively certain you know what the compiler AND the CPU are doing. Then heavily document it in the source so you, or someone else, know where the potential trouble spots are and how they are (presently) handled for which compiler and which underlying hardware. The language specs are delightful but there's no guarantee that a given version of a given compiler for a given hardware target actually implemented something strictly to the specs. I trust no one and verify everything. YMMV! Logged

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1883
  • Country: se
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #13 on: January 30, 2020, 12:19:45 am » Quote from: IDEngineer on January 29, 2020, 11:28:52 pm
Quote from: newbrain on January 29, 2020, 10:50:52 pm
First of all, we are guaranteed that there are no padding bits or bytes:Both uint8_t and uint32_t are exact-width integer types.
The latter statement is true. The former statement may NOT be true, which is why you must be careful. 32 bit values may be required by the processor architecture to be aligned on a word or dword boundary. If you lead with a char, there could be padding to align an immediately following word or dword.
I respectfully disagree:0. Our uint32_t has size 4 - note that I explicitly put this as a precondition.1. Char hasn't got any padding bits, per 6.2.6.2.2. uint8_t cannot be anything else than unsigned char: cannot be smaller, as it is both exact-width and a typedef, and cannot be larger as the minimum range for unsigned char is 0-255.3. An union must be correctly aligned for both its member types - we are not considering a generic uint8_t[4] - and there can't be padding at the beginning, per 6.7.2.1 Structure and union specifiers, §13.4. All the representations in an exact-width 32 bit unsigned int of size 4 must be valid (I don't think I have to show why).All of the the above yields:- No padding is possible in an uint32_t when its size is 4.- There are no trap representations possible.- Alignment is guaranteed.- I can read the uint32_t as a sequence of 4 uint8_t (always guaranteed, no need for an union).- I can read the sequence of 4 uint8_t as an uint32_t, without fear of misalignments or trap representations Logged Nandemo wa shiranai wa yo, shitteru koto dake.

Offline GeorgeOfTheJungle

  • Super Contributor
  • ***
  • !
  • Posts: 2699
  • Country: tr
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #14 on: January 30, 2020, 12:21:53 am » Quote from: RoGeorge on January 28, 2020, 07:23:05 pm
- use "union" to easily read the same memory location(s) either as uint8 or as uint32
Why not use a ptr to the uint32_t, that you can always cast as needed?Code: [Select]#include <stdio.h>#include <stdint.h>int main (void) { uint32_t a= 0x03020100; uint8_t* b= (uint8_t*) &a; printf("%d %d %d %d\n", b[0], b[1], b[2], b[3]);}-> 0 1 2 3Code: [Select]#include <stdio.h>#include <stdint.h>int main (void) { uint32_t a= 0x03020100; #define aptr ((uint8_t*) &a) printf("%d %d %d %d\n", aptr[0], aptr[1], aptr[2], aptr[3]);}-> 0 1 2 3 « Last Edit: January 30, 2020, 11:24:25 am by GeorgeOfTheJungle » Logged The further a society drifts from truth, the more it will hate those who speak it.

Offline GeorgeOfTheJungle

  • Super Contributor
  • ***
  • !
  • Posts: 2699
  • Country: tr
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #15 on: January 30, 2020, 12:33:03 am » Quote from: kolbep on January 28, 2020, 07:13:35 pm
It works fine at low current, but as soon as the current increases over a few amps, I start getting a display of 40000 + Amps.
"A few amps" is less than 10?I'd printf the bytes of that uint32_t (see the msg above) and compare what you get with these values in mA: 1A= 0x000003e8 2A= 0x000007d0 3A= 0x00000bb8 4A= 0x00000fa0 5A= 0x00001388 6A= 0x00001770 7A= 0x00001b58 8A= 0x00001f40 9A= 0x0000232840e3A= 0x02625a00 Logged The further a society drifts from truth, the more it will hate those who speak it.

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1968
  • Country: us
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #16 on: January 30, 2020, 01:06:58 am » Quote from: newbrain on January 30, 2020, 12:19:45 am
Alignment is guaranteed.
Consider this case, one of many easy examples (addresses are offsets from the base of the struct/union, which is itself presumed to be aligned). We have a char followed by a dword in a struct/union:Offset 0x00: charOffset 0x01: LSB of dwordOffset 0x02: next byte of dwordOffset 0x03: next byte of dwordOffset 0x04: MSB of dwordAccessing the char is guaranteed to be aligned, yes. It's a single byte. Accessing the dword as a 32 bit entity... not so much. It's on an odd address. The char caused it to be offset from the base of the (overall aligned) struct/union.Options to permit aligned access for BOTH members include:1) Insert a pad byte at 0x01 (works for architectures where a 32 bit access need only be aligned on an even address, e.g. address LSb = 0)2) Insert three pad bytes at 0x01 (works for architecture where a 32 bit access is required to be on a modulo-4 address, e.g. two address LSb's = 0)3) Author rearranges the order of the struct/union to place the dword at offset 0x00 (compiler dares not do this on its own since other code may presume the source's explicit ordering)Note that options 1 and 2 may end up being repeated if the struct/union has more members which also end up misaligned due to ordering. It is possible to write a compiler that could automatically optimize ordering, but that had better be an explicit opt-in or else the cast-based accessing being discussed in this thread would fail horribly - AND the compiler may not even be able to warn about it depending upon how the cast-based accessing was expressed in the source. « Last Edit: January 30, 2020, 01:08:30 am by IDEngineer » Logged

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1803
  • Country: us
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #17 on: January 30, 2020, 01:17:48 am » Quote from: newbrain on January 29, 2020, 10:50:52 pm
Under a quite relaxed set of constraints, that specific example of type punning is perfectly fine.The only condition to verify is that sizeof(uint32_t) == 4.
I think you also need to verify that CHAR_BITS is 8 (which is required by POSIX and as a practical matter, it's been decades since a platform had a CHAR_BITS of 9, but that would still allow for sizeof(uint32_t) == 4 and yet almost assuredly guarantee that a uint8_t[4] would not be the same bits as a uint32_t) The spec only guarantees that CHAR_BITS is >= 8. Logged

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1883
  • Country: se
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #18 on: January 30, 2020, 06:59:49 am » Quote from: sokoloff on January 30, 2020, 01:17:48 am
Quote from: newbrain on January 29, 2020, 10:50:52 pm
Under a quite relaxed set of constraints, that specific example of type punning is perfectly fine.The only condition to verify is that sizeof(uint32_t) == 4.
I think you also need to verify that CHAR_BITS is 8 (which is required by POSIX and as a practical matter, it's been decades since a platform had a CHAR_BITS of 9, but that would still allow for sizeof(uint32_t) == 4 and yet almost asesuredly guarantee that a uint8_t[4] would not be the same bits as a uint32_t) The spec only guarantees that CHAR_BITS is >= 8.
Remember, we have in this case an uint8_t.According to standard, this is a typedef so it does not change the characteristics of the underlying type.It is also an exact-width integer type.It cannot be smaller than unsigned char as (unsigned) char is the smallest integer. It cannot be larger than unsigned char as 8 bits is the minimum size for unsigned char.The two statements above are guaranteed by "5.2.4.2.1 Sizes of integer types <limits.h>", §1:Quote
— number of bits for smallest object that is not a bit-field (byte) CHAR_BIT 8
There are no objects smaller than CHAR_BIT (bit-fields are off-topic in this discussion)So, if we have uint8_t at all, CHAR_BIT==8.Having sizeof(uint32_t)==4 is only the last of a series of preconditions, but using exact-width integers automatically verifies them: they are optional types, if they are there they must behave as stated. If we had used generic (unsigned) ints and chars they would not hold.@IDE_engineer: no. Again: it's a union and there's no padding at the beginning. The members of an union begin at the same address. If one is typacasting odd structures into other objects all bets are of course off."cast-based"?This is not cast based. Ths is type punning and uses a union. No cast operators in sight.EtA: Standard chapter for minimum object size, it's CHAR_BIT not BITS. « Last Edit: January 30, 2020, 08:04:31 am by newbrain » Logged Nandemo wa shiranai wa yo, shitteru koto dake.

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1883
  • Country: se
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #19 on: January 30, 2020, 09:43:49 am » Quote from: IDEngineer on January 30, 2020, 01:06:58 am
It is possible to write a compiler that could automatically optimize ordering
Of course, but not in a standard compliant mode.See "6.5.8 Relational operators", §5:Quote
...If the objects pointed to are members of the same aggregate object, pointers to structure members declared later compare greater than pointers to members declared earlier in the structure...
Logged Nandemo wa shiranai wa yo, shitteru koto dake.

Offline donotdespisethesnake

  • Super Contributor
  • ***
  • Posts: 1093
  • Country: gb
  • Embedded stuff
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #20 on: January 30, 2020, 10:05:48 am » Always funny to see people justifying why writing bad code is a good idea. :-DDIn this case, it's not like there is only one way to do it. The alternative method is always guaranteed to be correct with any compiler on any platform, and usually compiles to something with similar performance. It borders on insanity not to use it.My job is basically is fixing other people's bad code, so I have seen a lot of it. « Last Edit: January 30, 2020, 10:07:29 am by donotdespisethesnake » Logged Bob"All you said is just a bunch of opinions."

Offline GeorgeOfTheJungle

  • Super Contributor
  • ***
  • !
  • Posts: 2699
  • Country: tr
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #21 on: January 30, 2020, 11:28:05 am » Quote from: donotdespisethesnake on January 30, 2020, 10:05:48 am
In this case, it's not like there is only one way to do it. The alternative method is always guaranteed to be correct
Which way is that? Logged The further a society drifts from truth, the more it will hate those who speak it.

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1883
  • Country: se
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #22 on: January 30, 2020, 11:35:21 am » Quote from: donotdespisethesnake on January 30, 2020, 10:05:48 am
Always funny to see people justifying why writing bad code is a good idea. :-DD
If you are referring to my explanation, I might have made my purpose and stance clearer.I already stated that this us of type punning is wasted time, and I would never advocate (or use) it.My elucubrations were just the answer to RoGeorge doubt, to show that, yes, in this very specific case the standard is backing you (IMO, but I haven't seen a valid rebuttal, yet).But let the phase of the moon change, and undefined behaviour will rear its ugly head (in some, more benign, cases just implementation defined behaviour).Do I find this code "bad"? Yes.Do I think it's standard compliant? Yes. In C99 at least, C11 and later change some fine points in the wording.Quote from: donotdespisethesnake on January 30, 2020, 10:05:48 am
The alternative method is always guaranteed to be correct with any compiler on any platform, and usually compiles to something with similar performance. It borders on insanity not to use it.
Could not agree more. As I also demonstrated.I am quite sure I've never written this kind of code. I make use of unions very sparingly in any case.Quote from: donotdespisethesnake on January 30, 2020, 10:05:48 am
My job is basically is fixing other people's bad code, so I have seen a lot of it.
Eh...having been in the same position I'm glad Italian has wonderfully rich vocabulary for swearing.Quote from: GeorgeOfTheJungle on January 30, 2020, 11:28:05 am
Which way is that?
Use shifts. Logged Nandemo wa shiranai wa yo, shitteru koto dake.

Offline GeorgeOfTheJungle

  • Super Contributor
  • ***
  • !
  • Posts: 2699
  • Country: tr
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #23 on: January 30, 2020, 12:21:23 pm » Quote from: newbrain on January 30, 2020, 11:35:21 am
Use shifts: https://gcc.godbolt.org/z/DSxgPJ
gcc.godbolt.org :-+ !! Logged The further a society drifts from truth, the more it will hate those who speak it.

Offline grizewald

  • Frequent Contributor
  • **
  • Posts: 612
  • Country: ua
Re: Arduino - Convert 4 x uint8 to 1 x uint32
« Reply #24 on: January 30, 2020, 12:56:10 pm » Quote from: rstofer on January 28, 2020, 11:13:54 pm
I sure wonder aboutCode: [Select]while (mySerial.available()) { int countr = countr + 1; buffer[countr] = mySerial.read(); containsdata = 1; };countr is not initialized to zero nor is it static. countr will be allocated on the stack and the stack contains random values. I'm not sure how it would work out.Since you have it working, maybe this doesn't matter.
Maybe it doesn't, but declaring 'countr' inside the while loop is just wrong. Logged Lord of Sealand
  • Print
  • Search
Pages: [1] 2 Next All Go Up « previous next »

Share me

Digg Facebook SlashDot Delicious Technorati Twitter Google Yahoo Smf
  • EEVblog Electronics Community Forum »
  • Electronics »
  • Microcontrollers »
  • Arduino - Convert 4 x uint8 to 1 x uint32
There was an error while thanking Thanking...
EEVblog Main Site EEVblog on Youtube EEVblog on Twitter EEVblog on Facebook EEVblog on Odysee
  • SMF 2.0.19 | SMF © 2021, Simple MachinesSimple Audio Video EmbedderSMFAds for Free Forums | Powered by SMFPacks Advanced Attachments Uploader Mod
  • XHTML
  • RSS
  • Mobile
  • Mobile
  • WAP2

Tag » Arduino Uint32_t To Byte Array