Use struct for settings

Hello,

Lets say i have a Struct:

struct Settings
{
int time;
int interval;
String date:
}

I know that i can created different objects for this struct.

My question. In my program i can select diffrent probes to measure my water. My plan is now, that i can select (via my nextion display) my prefered probe and that, depending of the selected probe, the intern settings will change and set.

Lets say i define 2 probe objects for the struct:

Settings probe1;
Settings probe2;

What would be the best way to switch between this to pointers? I am struggling how to initiate the correct pointer. Lets say i create a menu on my display where i can select "probe1" or "probe2".

I hope you can understand what i mean.

thank you

Note that the String class is a special case. It uses indirect data access and cannot be stored in a structure in the usual way. I would recommend that you use some other data type, such as fixed length strings. If this is a calendar date, then you don’t need strings at all; you can use, for example, integers for the day, month and year.

How about an array of structs ?

Something like this

struct Settings
{
    int time;
    int interval;
    char date[12];
};

Settings probes[] = {
    { millis(), 1000, "" },
    { millis(), 2000, "" }
};

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

void loop()
{
}

You can then refer to the problesas probles[0] and probles[1] and their values as sensors[0] interval and sensors[1].time etc

1 Like

Why not have then in an array?

something like

   switch( selected_probe_number )
   {
      case 1:  selected_settings_ptr = &probe1; break;
      case 2:  selected_settings_ptr = &probe2; break;
      default: /* ?? */ break
   }

But an array would save all that repetition ...

Thank you for the answers.

i tried to create a small example to gain more understanding:


#include <Arduino.h>
#include "EasyNextionLibrary.h"  // Include EasyNextionLibrary


EasyNex myNex(Serial2); // Create an object of EasyNex class with the name < myNex > 
                       // Set as parameter the Hardware Serial you are going to use

int selectedProbe;

struct Settings{

  char devinename;
  int day;
  int month;
  int year;
  int hour;
  int minute;
  int second;
  int interval;
  int brightness;

};

Settings probe1;
Settings probe2;
Settings *selected_settings_ptr;

void setup() {


  Serial.begin(9600);  //Bauderate for Serial monitor
  myNex.begin(9600); //Bauderate for Nextion

  switch( selectedProbe )
  {
    case 1:  selected_settings_ptr = &probe1; break;
    case 2:  selected_settings_ptr = &probe2; break;

  }

}

void loop(){


  myNex.NextionListen();    //This function must be called repeatedly to response touch events

                         
}

//*******************************************************
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******************************************************



void trigger1(){
  
}

I dont know if thats correct what i did. How i understand it:
I createtd 2 objects of my struct. probe1 and probe2. I also created a pointer of type of my struct. So wht happens: deppening on selectedProbe (which i will choose on my Nextion), my pointer will point to the adress of the selected probe.

Whats unclear (if i am right): Lets say i selected "2" of my selectedProbe:

selected_settings_ptr.devicename is not the same as selected_settings_ptr.devicename, when i am picking selectedProbe=1?

thank you

Because it's a pointer, the correct syntax is:

selected_settings_ptr->devicename

That will be pointing to either probe1.devicename or to probe2.devicename

The two probe structures - and all their elements - remain entirely distinct; accessing one has no effect on the other.

This would be another advantage of the array approach:

struct Settings
{
    int time;
    int interval;
    char date[12];
};

Settings probes[2];

You would then refer directly to probes[0] or probes[1] - and not have to make sure that the pointer is pointing to the right one ...

In general, to get the time for the currently-selected probe:

probes[ selected_probe_number  ].time

I too think that the array approach is simpler, which is why I suggested it

1 Like

thank you again.
This is what i have so far: I think it works. At least i can store into diffrent elemtns depening on
the global seletedProbe:

#include <Arduino.h>
#include "EasyNextionLibrary.h"  // Include EasyNextionLibrary
#include <Preferences.h>
#include <functions.h>
#include <globals.h>


EasyNex myNex(Serial2); // Create an object of EasyNex class with the name < myNex > 
                       // Set as parameter the Hardware Serial you are going to use

int selectedProbe = 2;

struct Settings{

  char devinename[15];
  int day;
  int month;
  int year;
  int hour;
  int minute;
  int second;
  int interval;
  int brightness;

};

Settings probes[7];

//------------
Preferences preferences;

void setup() {


  Serial.begin(9600);  //Bauderate for Serial monitor
  myNex.begin(9600); //Bauderate for Nextion
  delay(1000);

/*
  preferences.begin("Settings");  //namespace
  preferences.getBytes("Settings",&probes[selectedProbe],sizeof(probes[selectedProbe]));

  Serial.print("****: ");
  Serial.println(probes[selectedProbe].devinename);*/


}

void loop(){


  myNex.NextionListen();    //This function must be called repeatedly to response touch events

                         
}

//*******************************************************
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
//*******************************************************



void trigger1(){

  String deviceName = myNex.readStr("t0.txt");

  strcpy(probes[selectedProbe].devinename,deviceName.c_str());

/*

  preferences.begin("Settings");  //namespace
  preferences.putBytes("Settings", &probes[selectedProbe], sizeof(probes[selectedProbe]));

  preferences.end(); //close namespace*/

}

As u can see, i expermiented a bit with prefrences. Since i wanna store the data of the different settings of each probe to use it later again, whats the best approach to save them here.

Is it possible to save each struct of probe into preferences. My research concluded that putBytes should be the way to go. but to fullfill my goal i have to set the name of the namespace form the prefrences also to be a variable. Are my thoughts right?

When i use it like above i would aways overwrite my settings, since i always use the namespace "Settings"

thank you

Could you not just save the whole of the probes array in a single namespace ?

1 Like

I would now do this:


  preferences.begin("Settings");  //namespace
  preferences.putBytes("Settings", &probes[selectedProbe], sizeof(probes[selectedProbe]));
  preferences.end(); //close namespace

Lets say i selected selectedProbe = 1. From my understanding i would now store the whole struct of my selected probe into the namespace "Settings"

when i now select selectedProbe = 2 and would now save again, i would overwrite the settings of "probe 1". Or am i missing something?

how do i save the whole array in a single namespace?

thank you

Preferences is something that I have only briefly looked at so I may well be wrong

That seems likely to me too

If

preferences.putBytes("Settings", &probes[selectedProbe], sizeof(probes[selectedProbe]));

then what would

preferences.putBytes("Settings", &probes, sizeof(probes));

save ?

To get back the values of a single probe you would load the whole array then extract the required probe data from it using its array index

Another thought. It occurs to me that you could make the code more readable by using an enum to give the array levels in the probes array meaningful names. This would mean that you could have lines of code like this

if (probes[top].brightness > 123)
{
  probes[top].interval = 1000;
}

Thank you. In that way it worked

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.