I work in another programming language where you can define an array, then define an variable name to elements of the array. They call it aliasing. It avoids having to execute an equal statement each pass through the code.
The alias for array[3] is Supply_Temp
The alias for array[4] is Return_Temp
This allows the program to utilize the descriptive names rather than the array index and you don't have to manage a while bunch of equal statements. And the aliasing does not take any additional memory. I assume they have a way that defines the alias tag to the same memory location as the array location.
Is there a way to do this in C? I have never tried or had to conceive of it, but it would be a big help in working with Modbus and the register array.
@CodingBadly, I need to digest your solution more.
Alarm is registers[5] bit 0? It has been a long time since I have seen the "uint16_t variable:1;" definition.
@DKWatson, I understand the struct, but not sure how to relate (?) it to the element of the array. Would bits *flag1 = &array[99 ] work? (where array[x ] is of type unit16_t)
The bits example is to get to the bit level. The balance is merely to suggest that #define is the pre-compiler directive to deal with all your aliases.
Use #define alias_name convoluted_variable_name
anywhere you want, as long as you use it before you use it if that makes sense. It weighs nothing, costs nothing. When the pre-compiler assigns memory and an address to convoluted_variable_name, it replaces alias_name with that same reference everywhere it has been used after it was defined.
You will have to test. A given compiler can order either way but it will order them consistently. For example, I recall that Microsoft's C++ Intel compiler orders the opposite of AVR-GCC. Alarm with one of the compilers would be bit 15 and bit 0 with the other.
The test is trivial. Set Alarm to 1 then print register5.
I work in another programming language where you can define an array, then define an variable name to elements of the array. They call it aliasing. It avoids having to execute an equal statement each pass through the code.
The alias for array[3] is Supply_Temp
Why are the elements in an array in the first place? It sort-of sounds like a poor-man's alternative to structures, and C/C++ has 'real' structures... For a modbus-like thing:
typedef struct {
uint8_t fan0:1;
uint8_t coil1:1;
uint8_t coil2:1;
uint8_t coil3:1;
uint8_t coil4:1;
uint8_t coil5:1;
uint8_t coil6:1;
uint8_t coil7:1;
uint8_t Supply_Temp;
uint8_t Return_Temp;
uint8_t Internal_Temp;
} ac_unit_t;
:
if (modbusPak->data[0] == AC_UNIT_VAL) {
ac_unit_t *ac = &modbusPak->data[1]; // point to the ac unit data
if (ac->Return_Temp > 60 && ac->fan0 == 0) {
// temp getting high an fan off; do something to turn it on!
:
}
}
Other than that, #defines are probably the way to go:
westfw:
Why are the elements in an array in the first place? It sort-of sounds like a poor-man's alternative to structures, and C/C++ has 'real' structures...
The modbus communications are a good example. Modbus can read either a single register (supply_temp) or a group of (contiguous) registers (array[x]). Obviously it is more efficient to read four registers by reading a group which means you need an array. But using the array (and the array indices) throughout the program has two drawbacks. First, the variable is never very descriptive and you are always consulting the magic decoder ring to determine what array[3] is. Second, if you change the array indices (eg., insert Outside Temp between indices 2 and 3) then you must change all the indices throughout the whole program.
Pointers are one way to go. I'm liking CodingBadly's method as it has the layout (order of readable variables) in order, except for the bit thing. I will have to make sure that isn't a problem (or define all 16 bits, ugg.)
DKWatson:
The bits example is to get to the bit level. The balance is merely to suggest that #define is the pre-compiler directive to deal with all your aliases.
Use #define alias_name convoluted_variable_name
anywhere you want, as long as you use it before you use it if that makes sense. It weighs nothing, costs nothing. When the pre-compiler assigns memory and an address to convoluted_variable_name, it replaces alias_name with that same reference everywhere it has been used after it was defined.
That's only the second half of the question. What you have is a great way to break an int up and provide the bits readable variable names. But the variable flag1 needs to represent array[99] (ie., be the same memory location). so I can access the bits of array[99] using readable variable names.
adwsystems:
I work in another programming language where you can define an array, then define an variable name to elements of the array. They call it aliasing. It avoids having to execute an equal statement each pass through the code.
The alias for array[3] is Supply_Temp
The alias for array[4] is Return_Temp
It seems to me this Thread has drifted away from the question. What's wrong with a simple solution such as
int myAnimalCount[4]; // create an array of 4 elements
#define numberOfDogs 0
#define numberOfCats 1
#define numberOfGerbils 2
#define numberOfParrots 3
myAnimalCount[numberOfDogs] = 23;
I say still on target, just describing different ways to slice the bread.
Nothing wrong with your solution. In light of my response to westfw, I see where your line of thinking was. I was scoped locked on the method available at my day job and posed the question in those terms. CodingBadly, Blue Eyes, et al. provided solutions based on the requirements. Add in my response to the question posed by westfw, your option is to just name the indices will also meet the original requirement.
How about the enhanced question of making readable variable names for the bits of one of the array ints?
adwsystems:
Pointers are one way to go. I'm liking CodingBadly's method as it has the layout (order of readable variables) in order, except for the bit thing. I will have to make sure that isn't a problem (or define all 16 bits, ugg.)
or a simple reference as an alias (instead of a pointer and having to use all that dereferencing):
int array[10];
int& value3 = array[3]; // value3 is a reference to the [3] element of array
void setup() {
Serial.begin(9600);
for (auto& a :array) {
a = 10;
}
Serial.println(value3);
}
void loop() {
}