Sending data from an attiny85 + NRF24L01 using NRFLite (sketch Sensor_TX_ATtiny85_2Pin.ino)
Receiving this data on a Nano 33 IOT + NRF24L01 using RF24 (sketch assembled from RF24 examples and the compatibility info from NRFLite Github)
At this point I rule out hardware issues as all standard examples that come with the libraries work flawlessly in all sorts of configurations and the setup above also works like a charm when I replace the Nano IOT with a Nano.
The issue is that the Nano 33 IOT shows strange values. I've boiled it down to the difference in size of data types on various architectures. So I solved the case at hand by rearranging the order of the members in the struct that is being sent, so that:
offset in the structure is a multiple of member size
structure size is a multiple of the largest type in the structure
I can see why this works, but without any experience in C++, I'm not sure how to proceed, in the sense that I would like to keep the TX and RX side ignorant of each other's intestines.
General question: what topics / techniques should I delve into to achieve this goal? Here I'm sort of asking the question what questions to ask.
More specific, less urgent: I noticed that the size of the actual struct members is the same on the Nano and the Nano IOT, but there is a difference in the size of the struct itself. Any chance there is some quick fix for either the Nano IOT (RX) or the ATTiny85 (TX) code to align struct size so that I can create structs without any worries?
I don't know the details of of what you're using but almost all data-communication (and data storage) is byte-by-byte. RS-232 and Ethernet transmit/receive bytes. Your hard drive stores bytes.
Of course you can transmit/receive 16 or 32-bit words, or read/write them from your hard drive but you can also get the bytes one at a time.
You can open a file with a hex editor and see the bytes in hexadecimal and if you don't don't know the context you don't know if they represent individual byes or "bigger numbers" or if they represent ASCII text or audio samples, or part of a pixel, or a computer instruction, etc... The application has to know how to interpret the data and often how to "re-assemble" it from bytes.
There is no point in sending floating point values for sensor measurements. Multiply by a suitable scale factor (e.g. 10 or 100), convert to integer and send the integer.
The raw sensor data are integer to begin with, so if you have access to those, send them instead.
Thank you. Adding this on the Nano IOT (RX) side eliminates the need to order the struct. I guess, when really making things generic, adding this on both sides would meet all needs.
Not sure about forum rules about follow-up questions, but would this generalize to the statement that when using various boards to send a set of variables through NRF24l01 transceivers, the best way to organise your payload is to create a struct applying attribute((packed)) to the struct?
Just to get it ultrasharp.
Thanks again, it totally makes sense. I had a brief encounter with Endianness misery when figuring out the addresses of the radio's, that turned out to be quite easy but I've been wary ever since Cheers!
Actually, it does. Float representations can vary from computer to computer, just as endianness and default integer size do, which is one of several reasons to avoid transmitting them.
Thank you. So float, integer and endianness vary from computer to computer so we have to avoid transmitting them. That's a bummer. What data type(s) should I use in my scenario?
Okay. But I want to send multiple values in one transmission, so I use a struct. Dropping the floats doesn't fix the issue of different struct sizes on the Nano and the Nano IOT. So if I send this from a Nano (where it has size 8):
Why do the structs have different sizes? Did you forget to use the packed attribute, or doesn't it work as expected?
If you get tired of all this, pack and unpack byte arrays with custom code (trivial with memcpy()), or use a line of comma separated ASCII text (CSV format). The latter has the great advantage of being readable by humans.
Aha. I assumed you suggested using integers of defined size in order to overcome the issue with differences in size as it was your initial reply. That is completely solved by using the packed attribute, indeed.
At the moment I don't really see a huge problem in the current approach: sending a bunch of values in a struct with the packed attribute.
You still gave some valuable pointers I think, reason being that I'm planning to fill the available space on the ATTiny85 with as much code as possible. My intuition is that your suggestions may come in handy for cutting things down to the bare minimum.
Does this makes sense?
Anyhow, thanks, your feedback is much appreciated. Unless it becomes clear I'm totally on the wrong track I think I'll leave it at this so I can become more familiar with the matter first.