Pass data structure name to function.

This might be something incredibly simple but I haven't been able to find the answer.

Basically I have a couple of data structures that I am storing some user config settings in, I am using struts so I can can also use EEPROM.get() and .put().

struct AnalogCHConfig {
  int LowerCali;
  int NeturalCali;
  int HighCali;
};

AnalogCHConfig CH1Config, CH2Config;

What I want to be able to do is just pass its name to a function so one function can reference any of them.

Something like.

AnalogChannelRead(CH1_PIN, CH1Config);

void AnalogChannelRead(int PIN, struct Test) {
   Test.lowerCali = 100;
}

What would be the correct way of doing this?

The above code is just an example as I am only just starting to write out the actual code.

Thanks

void AnalogChannelRead(int PIN, AnalogCHConfig &Test)
{
Test.lowerCali = 100;
}

larryd:
void AnalogChannelRead(int PIN, AnalogCHConfig &Test)
{
Test.lowerCali = 100;
}

Perfect, thank you.

I just wrote a quick program to test it which worked perfectly but I've just tried to incorporate that into my actual project and I have a problem.

It's my largest project to data so to help me write and debug it I am using the Arduino IDE tabs function that lets me split up my code.

The data structure setup is in the first tab and my function is currently in the last one.

When I try to compile it I get the following error.

'AnalogCHConfig' has not been declared

The exact same code put into one tab works fine.

What is causing this error?

Have not done as you (have always kept things in one tab) but might be do to the need for a ‘prototype’ or ‘extern’ declaration.

Did you do a #include “xxxxx.h” on the .h file ?

I haven't sent any extensions so all my tabs are just .ino files the the IDE combines into a single .ino file before compiling it.

One approach is to have a header file, perhaps named mySketch.h that contains:

#ifndef BEENHERE           // Have we been here before?
   #define BEENHERE        // Nope, so define the symbolic constant

   struct AnalogCHConfig {
     int LowerCali;
     int NeturalCali;
     int HighCali;
   };

   extern AnalogCHConfig CH1Config, CH2Config;

   // more #defines and externs (?)

#endif

Then in your other source files, the top of each one has:

#ifndef BEENHERE
#include "mySketch.h"
#endif 

// the actual code for the file follows...

This is a data declaration for the two variables. Then in your myScketch.ino file you have:

AnalogCHConfig CH1Config, CH2Config;

The extern keyword in the header file is essentially saying to all of the cpp files: "CHiConfig is defined in another file, but I'll declare it here so you can use it as an AnalogCHConfig data item." The data declaration using extern simply constructs an attribute list for the variable(s) that allows you to use it across all files, but no memory is allocated for it with the extern statement. In the ino file, you actually define the variables, which means they now have an attribute list and are allocated memory. (It's the linker's job to fix the addresses in the other source files.)

Also, by making all "tabbed" files cpp files and having only one ino file (the file that contains setup() and loop()), it allows the IDE's GCC compiler to perform incremental compiles. That is, it only compiles those files that have changed since the last compile. The time savings can be significant. For example, I had one project with 19 source file (i.e., 18 *.cpp files) and the first compile in the morning would take almost 45 seconds on a pretty fast machine. Subsequent compiles where I was changing only a single file during debugging the compile time dropped to around 10 seconds. If you do 30 compiles a day, that saves you 15 minutes of thumb-twiddling each day. Do that for a half a year and you end up with a pretty large chunk of time!

This seems to work okay:

//Put in your .ino tab

#include "struct.h"

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  AnalogChannelRead(CH1Config);
  
  AnalogChannelRead(CH2Config);

  Serial.println(CH1Config.LowerCali);

  Serial.println(CH2Config.HighCali);

  delay(1000);
}

void AnalogChannelRead(AnalogCHConfig &Test)
{
  Test.LowerCali = 100;
  Test.HighCali  = 500;  
}
//Put in your struct.h tab

struct AnalogCHConfig {
  int LowerCali;
  int NeturalCali;
  int HighCali;
};

AnalogCHConfig CH1Config, CH2Config;

I managed to resolve it.

The problem was caused by some weird behavior of Tabs in the IDE

Because there was no functions in my first tab all the auto generated function declarations were added to the start of the code meaning my function deceleration came before the struct was declared.

Manually adding the deceleration of this function after the struct stops the IDE from trying to declare it too early.

Thanks for your help.

For a better way to use multiple tabs (aka files), see Reply #3 Here.