In a sketch I will be entering a large amount of sample data pairs consisting of an unsigned long value and a byte value (a checksum of sorts). Of course I could make them both longs, or I could enter all the longs in one array and all the bytes in another. But the data would be easier to enter, and edit, and it would save space if C++ would let me have the array entries consist of a long followed by a byte. Is that a thing?
why not use a Structure
Examples: Array of Structures in C | GeeksforGeeks
On other than an 8 bit processor an array of structures would be equivalent in size to an array of 2 longs due to structure alignment.
Unless you use __attribute__((packed)) on the struct. In which case see
But in your case it may be worth the code bloat and performance hit for simpler code. If you have the code space and the processor is fast enough that the time is not an issue ignore my rant and move on. ![]()
so to answer the question clearly, NO you can't. All the items in an array share the same type (which can be a compound type like a struct or class and so you could pack different data).
Thanks very much for the responses. I'm afraid my C++ knowledge is pretty limited. I never quite got to structs. No time like the present, I guess.
But I did once place an array into flash using PROGMEM. Can I do that with a two-dimensional array of longs, and then read one part back into ram as a byte array, or I guess even access it as longs from flash? The problem is ram filling up.
Which Arduino are you targeting?
I'd like it to work on a basic Uno or Nano (328P).
So the issue is finding a way to enter data in a reasonable manner - in pairs - without ram being a limit on how many samples I can use. If the PROGMEN method will let me do a two-dimensional long array in flash, then I can begin the program transferring everything into two separate ram arrays, one of longs and the other of bytes.
Example of using an array of structs:
struct {
int number;
char character;
} myArray[5] = { {1, 'A'}, {2, 'B'}, {3, 'C'}, {4, 'D'}, {5, 'E'}};
void setup() {
Serial.begin(115200);
for (int i = 0; i < 5; i++) {
Serial.print(myArray[i].number);
Serial.print(" translates to ");
Serial.println(myArray[i].character);
}
}
void loop() {}
void loop() {}
If you want to write to the array while the program is running, PROGMEM is not useful, as the array contents are fixed at compile time.
You might take a look at the Adafruit Feather boards. They are really nice and most have quite a bit more RAM and program memory that the venerable AVR line.
I will take a look at the struct option. But I did try an example of defining the array in PROGMEN, and then reading it back into ram, but with the second long field brought in as bytes.
const unsigned long Key[][2] PROGMEM = {
{14256, 95},
{8395, 19},
{88493, 4},
{9586, 42},
{33333, 24}
};
int i;
const int Samples = sizeof(Key) / sizeof(Key[0]);
unsigned long ramsam[Samples] = {};
byte ramcheck[Samples] = {};
void setup() {
Serial.begin(9600);
for (i = 0; i < Samples; i++) {
ramsam[i] = pgm_read_dword_near(&Key[i][0]);
ramcheck[i] = pgm_read_dword_near(&Key[i][1]);
}
for (i = 0; i < Samples; i++) {
Serial.print(ramsam[i]);
Serial.print(" ");
Serial.println(ramcheck[i]);
}
}
void loop() {
}
Output:
14256 95
8395 19
88493 4
9586 42
33333 24
Put whatever data you want in a linear array. Write a translator to decide what the data is and write "dimensional" math to extract the correct element from the correct dimension.
Here is how I made fake 10-dimension arrays... using a single dimension array... and why I can not think in terms of struct or arrays of arrays... in PROGMEM.
This is an implicit cast from long to byte. Potentially losing info (for numbers larger than 255). The compiler should warn you for this.
Add an explicit cast.
ramcheck[i] = byte(pgm_read_dword_near(&Key[i][1]));
Problem remains, but now it is clear you ment it to be like that....
For large arrays, this needs 4 times as much progmem space to store your byte....
Can you clarify if you know the array upfront at compile time and it won’t change or if the data in the array is acquired at runtime?
On a small Arduino like a UNO you can’t simply store data in flash at runtime. You can use eeprom but its size is not huge (1024 bytes).
There are easy to use I2C or SPI FRAM module that you can attach to your gig and that would provide more non volatile storage (maintains the data if you cut the power) - check Adafruit I2C Non-Volatile FRAM Breakout - 256Kbit / 32KByte : ID 1895 : Adafruit Industries, Unique & fun DIY electronics and kits for example - and you can use that at run time. Those modules also have a much better lifetime than the eeprom (write wear out) .
you'll need to read the element(s) back into RAM as needed, but if you're only reading back one element, does size matter at that point
This is about brute-force reverse engineering of an IR transmission "checksum". It's related to another thread here, now approaching 500 posts, where everything has been figured out except the 5-bit checksum. I thought it must be a CRC, but I wrote code to test every possible 5-bit polynomial, seed, and final XOR, as well as MSB/LSB, and got no solution. Then I ran across this thread:
https://softwareengineering.stackexchange.com/questions/369182/reverse-engineering-a-checksum-or-crc
in which the answer details another method that was used in Microsoft keyboards back in the day. Each bit of the checksum is the exclusive-or of certain bits in the main transmission. The Microsoft algorithm doesn't work on our data, so I'm writing code to test every possible permutation of bits to see if any one works for all samples. This really should be a PC task, but it's easier for me to use Arduino. The problem with this method is that you get a lot of false positives until you've included enough samples to get down to one answer. The more samples you test, the fewer solutions you get, and if the last one really is the answer, it will continue to work for all future samples.
So the data is all available at complile time, and won't change. But there will be a lot of data crunching, and I thought trying to do all that in the flash data would really slow things down. But I understand that it really isn't all that bad. So I'll probably just leave everything in flash, which would eliminate any concern about the number of samples, although I might have to go make coffee while it runs.
You may get mileage out of an online C/C++ compiler. This
and this
work very well. And are faster than the Aduino even without the upload cycling.
a7
Processing.org is the parent of Arduino IDE, is a forgiving language, can crunch at the power of your computer, can map your data, and and can export a stand-alone executable app.