Introduction to Arduino Struct

Arduino Struct syntax lets you to organize related data into a single variable, so you can easily organise information in a group without having lots of variables all over the place. Programs are therefore easier to understand and maintain.

As your programs become more complex you will find that keeping track of related data becomes a problem. If you create a struct variable you can group that data in a logical way allowing you to more easily manage complex programs.

This introduction for using structs with any Arduino microcontroller, demonstrates how to declare struct variables, and use them in your own examples.

You will find out how structs make your code more organized and readable for handling interconnected information.

What is a Struct?

A struct (short for "structure") type in C/C++ is a user-defined datatype that allows grouping of multiple variables of different data types together under a single name.

A  struct can can contain many variables of any of the of fundamental data types like integers, floats, characters. You can even use other types like arrays, pointers etc.

For example, if you want to store information about a person like their name, their age, and their salary etc. instead of declaring separate variables, you can create a struct called person and define the member variables inside it.

In this case you would use variables of type char array i.e. a string, integer, and float respectively. All this information will be contained in one struct element making the code more organized and readable as all the related data for a person is contained in one variable.

Declaring an Arduino Struct

To use a struct in Arduino code, you first need to declare the struct type by specifying the member variables it contains. The general syntax for declaring a struct is:

struct struct_name {
   member1_data_type member1;
   member2_data_type member2;
   member3_data_type member3;
   ...
};

For example, to store sensor readings from three sensors, we can declare:

struct sensor_readings {
  int sensor1;
  int sensor2;
  int sensor3;
};

This declares a new Arduino struct type called sensor_readings with 3 integer members - sensor1, sensor2, sensor3 to hold the readings from each sensor.

Defining Struct Variables

After declaring the struct type, you need to define variables of that struct type to use it. Struct variables are declared similar to basic variable types.

For example, to define a variable called readings of type sensor_readings:

struct sensor_readings readings;

You can also define multiple struct variables at once:

struct sensor_readings readings1, readings2, readings3;

This defines 3 variables - readings1, readings2, readings3 of type sensor_readings to store separate sets of sensor readings.

Accessing Struct Members

To access individual members of a struct variable, use the dot (.) operator followed by the member name.

For example, to store readings in the first variable:

readings.sensor1 = 100;
readings.sensor2 = 150;  
readings.sensor3 = 200;

And print the second reading:

Serial.print("Reading 2: ");
Serial.println(readings.sensor2);

Passing Structs to Functions

You can pass Arduino struct type variables to a function in the same way that you use any other variable argument. The struct variable is passed by value, meaning a copy of it is passed instead of the original variable. It means you can pass a lot of data into a function using a single "struct" variable.

For example, to average the sensor readings:

struct sensor_readings averageReadings(struct sensor_readings readings) {

  int total = readings.sensor1 + readings.sensor2 + readings.sensor3;
  struct sensor_readings avg;

  avg.sensor1 = total/3;
  avg.sensor2 = total/3;
  avg.sensor3 = total/3;

  return avg;
}

And call it:

struct sensor_readings avg = averageReadings(readings);

Benefits of struct variables

Here are some additional benefits that structs provide for organizing and working with data in Arduino code:

Encapsulation: Structs allow grouping of related data and functions into one block, hiding unnecessary details from the outside. This makes code more organized and maintainable.

Type safety: Defining a struct creates a new customized type. This prevents incorrect assignments like storing an integer in a string member, adding clarity.

Memory efficiency: Structs allow allocation of multiple variables of different types in contiguous memory blocks, reducing memory overhead compared to individual variables.

Scalability: It's easy to add/remove members from a struct as needs change. This makes the code flexible and future-proof compared to separate variables approach.

Readability: Grouping logically related data into a named datatype (e.g. SensorReadings) makes the code more self-documenting and readable compared to individual variables.

Reusability: Structs containing common data can be defined once and reused across programs and libraries, reducing duplication.

Portability: Structs allow sending blocks of related data over communications with well-defined interfaces, easier than sending individual variables.

Example Sketch

The following sketch shows a simple database example that defines a Person struct with three elements:

  • Name
  • Age
  • Salary

So information that is related to a person is stored in a single variable.

The sketch simply prints out details for each person. It then calculates and shows the average age and salary for all of them.

One disadvantage of using a character array is that it is not dynamic (it is fixed length). If you had a person's name longer than 50 characters, you would need to re-program the application! You could remove this problem by using dynamic strings but these come with their own problems (see the link).


struct Person {
  char name[50];  // Character array to store the name
  int age;       // Integer to store the age
  float salary;  // Float to store the salary
};

void printPersonInfo(const char* personName, const Person& person) {
  Serial.print(personName);
  Serial.println(":");
  Serial.print("Name: ");
  Serial.println(person.name);
  Serial.print("Age: ");
  Serial.println(person.age);
  Serial.print("Salary: $");
  Serial.println(person.salary);
  Serial.println();
}

void setup() {
  // Start the serial communication at a baud rate of 115200
  Serial.begin(115200);

  // Create three Person instances and populate their data
  Person person1, person2, person3;

  strcpy(person1.name, "John");
  person1.age = 30;
  person1.salary = 45000.0;

  strcpy(person2.name, "Alice");
  person2.age = 25;
  person2.salary = 63500.0;

  strcpy(person3.name, "Bob");
  person3.age = 33;
  person3.salary = 55000.0;

  // Calculate the average age and salary
  int totalAge = person1.age + person2.age + person3.age;
  float totalSalary = person1.salary + person2.salary + person3.salary;
  int numPeople = 3;
  float averageAge = totalAge / numPeople;
  float averageSalary = totalSalary / numPeople;

  // Print out the data for each person using the printPersonInfo function
  printPersonInfo("Person 1", person1);
  printPersonInfo("Person 2", person2);
  printPersonInfo("Person 3", person3);

  // Print the average age and salary
  Serial.print("Average Age: ");
  Serial.println(averageAge);
  Serial.print("Average Salary: $");
  Serial.println(averageSalary);
}

void loop() {
  // Empty loop for demonstration purposes
}

Conclusion

This tutorial showed you how to use Arduino struct variables to organize related data in Arduino code. Structs provide a clean way to manage multiple pieces of related information as a single unit.

They make code more readable and maintainable by grouping logically connected variables.They provide organization, type safety, efficiency, flexibility, readability and reusability benefits - all of which aid in managing complex interconnected data sets in your Arduino programs.



Written by John Main who has a degree in Electronic Engineering.

Note: Parts of this page were written using poe & chatgpt as a research assistant. 



Comments

Have your say about what you just read! Leave me a comment in the box below.

Don’t see the comments box? Log in to your Facebook account, give Facebook consent, then return to this page and refresh it.



Privacy Policy | Contact | About Me

Site Map | Terms of Use