I'm making a robot that should have simple two way communication for a large variety of values to a desktop via UART (serial communication, modem port). It's also desirable for it to be easy to add new values.
The board on the robot is an Olimexino, a rather powerful Arduino clone with an arm processor. For the sake of simplicity, I believe it could be affordable to store all relevant global values as floats.
My idea is to store all values in a matrix, like below. On the robot I for instance would like multiple controllers, which here can be viewed just as a heap of values grouped. These should be easy to modify and send.
enum rows
{
controller_a,
controller_b,
controller_c,
rows
}
enum controllers
{
controller_value1,
controller_value2,
columns
}
float values[rows][columns]
This should make it quite easy to for instance add a controller. It would also be rather easy to send and insert values, as I could target any vale by just sending the coordinates as [row, column].
The question is though, are there other better ways?
Should I perhaps define the controllers in structs instead
struct controller
{
float controller_value1;
etc
}controllers[columns];
If I make sure that all controllervalues are floats, maybe I could use pointers to the structs for easy read/write? I dont't know how to do that pointer aritmethics though. I guess it would require a specific routine for handling each different struct, meaning that the code wouldnt be that easy to modify?
First, it is a very very bad idea to use floats if you are going to be sending the data between devices, particularly if they are going to be of different architectures, it would be far more sound to use 64 bit integers and implement a fixed point by hand where necessary. Floats are not of a predictable format in memory and thus trying to serialise them is highly difficult.
Second, I think you have some sound ideas as far as storing the data goes, using a 2D array of a fixed type to store the data will work well and hopefully be well optimised. The enums are also a nice way of avoiding confusion. However what you are missing is a way to send them easily. As you are using a micro a nice simple protocol would do, may I suggest something along the lines of the following. This assumes you are keeping the table synced between your computer and the arduino like:
uint64_t ValueTable[CONTROLLER_MAX][VALUE_MAX];
uint32_t UartFD; // This gets set somewhere during init
// It should be a non blocking fd so we dont block if there are
// no value changes
void SetValue(uint32_t ControllerNum, uint32_t ValueIndex, uint64_t Value)
{
ValueTable[ControllerNum][ValueIndex] = Value;
write(UartFD, &ControllerNum, sizeof(uint32_t));
write(UartFD, &ValueIndex, sizeof(uint32_t));
write(UartFD, &Value, sizeof(uint64_t));
}
void GetValue(void)]
{
uint32_t ContNum;
uint32_t ValIndx;
uint64_t Value;
if(!read(UartFD, &ContNum, sizeof(uint32_t)))
{
// No data waiting
return;
}
// Wait for the rest
while(!read(UartFD, &ValIndx, sizeof(uint32_t)));
while(!read(UartFD, &Value, sizeof(uint64_t)));
ValueTable[ContNum][ValIndx] = Value;
}
Obviously this is the version for the PC, the arduino needs read and write replaced with Serial.read and Serial.write and does not need the first argument, otherwise the two are the same.Obviously you need to call those wherever you write to a value in the table.
Effectively for what you are doing your idea is great, just make sure to keep the implementation fast and simple so it runs well on the robot's embedded system. Yuo need not worry too much about extensibility, as you are likely to update both at once, particularly if you can keep a fair amount of common code between the PC and robot.