How can I loop through each header file?

So I'm currently working on a project with the Arduino Uno and a display. This is my code:

//cluster_fuck.ino
//
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "GetServerList.h"
//#include "GetServerList.h";
bool startupdone = false;

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
lcd.begin();
// Turn on the blacklight.
lcd.backlight();
//startup();
}

void startup() {
    if (startupdone == true) { 
     checkeach();
    }
  // Robojax code for LCD with I2C
  // initialize the LCD,
  digitalWrite(13, HIGH);
  delay(200);
  digitalWrite(13, LOW);
  lcd.setCursor(0, 0);
  lcd.print("8888888888888888");
  lcd.setCursor(0, 1);
  lcd.print("8888888888888888");
  delay(2000);
  lcd.clear();
  bootscreen();

}
void bootscreen() {
  //Title Screen
  lcd.setCursor(0, 0);
  lcd.print("Cluster Fuck 1.1");
  lcd.setCursor(0, 1);
  lcd.print("Cluster Control");
  delay(5000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("   Starting Up");
  lcd.setCursor(0, 1);
  lcd.print(" Please Wait...");
  delay(5000);
  checkeach();
}

void loop() {
startup();
}
void checkeach() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("S" + serverId + " " + serverName +  " C"+ clusterId); //Change This
  lcd.setCursor(0, 1);
  lcd.print("IP:" + serverIP); //Change This
  lcd.setCursor(0, 1);
  delay(5000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("S" + serverId + " " + serverName + " C" + clusterId); //Change This
  lcd.setCursor(0, 1);
  lcd.print(serverStatusCode + " - " + serverStatusName); //Change This
  delay(5000);
  checkeach();
}

The file below gets the server data files:

//getserverlist.h
//
#include "serverdata/1.h"
#include "serverdata/2.h"

Each of the serverdata header files contain the following data:

//1.h
//
  String serverId = "1";
  String clusterId = "1";
  String serverName = "Web Server";
  String serverIP = "192.168.1.234";
  String serverStatusCode = "E0";
  String serverStatusName = "No Err";

I'm trying to make it to where it'll loop through each header file in the serverdata directory.

However, the problem I'm having is:

note: 'String {name of string}' previously declared here

How can I make this happen?

What do you mean by this and what are you trying to accomplish by doing so?

Basically this is how I want it to go:

  1. It'll first read serverdata/1.h and output it to the LCD screen
  2. After it outputs it to the LCD screen, it'll go to the next header file (this instance, being 2.h and do the same thing

And it'll keep doing that until all the files have been read through and then loop back to the beginning.

What I'm doing is creating a microcontroller which will output statuses of each server in a cluster.

There will be a Raspberry Pi attached to the Arduino that will read the server data and output it to the arduino as needed (for instance, if there's an error with one of the servers, it'll be able to re-upload the header script with new data using a serial connection).

This is what it looks like with just one of the statuses. But I need it to show more than just one server

OK. That won't work. Aside from the expected errors that you're seeing, the main problem is that header files are read at compile time not run time.

It sounds like what you want to do would be better accomplished by reading server data from an SD card, or if you don't need that flexibility, hardcode the server data in the code as entries in an array or some other data structure. Then you can iterate through them as the program runs.

Alright I'll have to try that. My end goal was trying to keep the code clean and organized where I'm not having everything all pushed onto a single file.

You are wasting a lot of RAM by using String (capital S) variables; each String object uses 6 bytes excluding the actual text.

I did not look much at your code but I guess that your IDs can be integers which (on an 8-bit processor) is only 2 bytes.

That can be done, but in a different way. Below based on @Delta_G's suggestion to use array of structs.n It's 4 files.

macros.h

#ifndef _MACROS_H_
#define _MACROS_H_

// macro to calculate the number of elements in of any type of array
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))

#endif

The first part is called an include guard (you can look it up) so including the file multiple times (directly or indirectly) does not cause compiler problems.
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0])) is a convenient macro to calculate the size of any type of array (int, char, float, struct).

serverStuff.h

#ifndef _SERVERSTUFF_H_
#define _SERVERSTUFF_H_

/*
   Struct definition for server related stuff
*/
struct SERVERSTUFF
{
  uint16_t serverID;
  uint16_t clusterID;
  char serverName[32];
  char serverIP[16];
  char statusCode[3];
  char statusName[32];
};

/*
   Tell the file that includes this serverSTuff.h that there is a serverStuff array somewhere
*/
extern SERVERSTUFF serverStuff[];

/////////////////////
// function prototypes
/////////////////////
/*
   get number of defined servers
   Returns:
    Number of servers
*/uint16_t getNumServers();

/*
   Print server details
   In:
    index of server in serverStuff array
*/void printServerStuff(uint16_t cnt);

#endif
This file defines a struct that contains the server details. It also declares two function prototypes and an external variable.

You will need to adjust the sizes of the character arrays to your needs. I do not know what your longest server name will be so made it quite spacious.

**serverStuff.cpp**
```cpp
#include <Arduino.h>
#include "serverStuff.h"
#include "macros.h"

SERVERSTUFF serverStuff[] =
{
  {1, 1, "Web Server 1", "192.168.1.234", "E0", "No Err"},
  {2, 1, "Web Server 2", "192.168.1.235", "E0", "No Err"},
};


uint16_t getNumServers()
{
  return NUMELEMENTS(serverStuff);
}


void printServerStuff(uint16_t cnt)
{
  Serial.print(F("serverID: "));
  Serial.println(serverStuff[cnt].serverID);
  Serial.print(F("clusterID: "));
  Serial.println(serverStuff[cnt].clusterID);
  Serial.print(F("serverName: "));
  Serial.println(serverStuff[cnt].serverName);
  Serial.print(F("serverIP: "));
  Serial.println(serverStuff[cnt].serverIP);
  Serial.print(F("statusCode: "));
  Serial.println(serverStuff[cnt].statusCode);
  Serial.print(F("statusName: "));
  Serial.println(serverStuff[cnt].statusName);
  Serial.println("=====");
}

In this file you can add all your servers (currently 2). Further it contains the implementations of the two functions.

And lastly the main file to demonstrate the use

#include "serverStuff.h"


void setup()
{
  Serial.begin(115200);
  for (uint8_t cnt = 0; cnt < getNumServers(); cnt++)
  {
    printServerStuff(cnt);
  }
}

void loop()
{
}

This is just to give you the idea; if your serverStuff array is fixed, you can move it to PROGMEM to save RAM memory.

Sounds to me like the Arduino is not needed here. Connect the LCD directly to the Pi.

If the Arduino is needed, the Pi can send the data directly to the Arduino to display over the serial connection. Formatting them as .h files is completely unnecessary, that just makes it more difficult to write Arduino code to parse the data. It would be easier to have the Pi send the data as one string of 32 characters which the arduino can split into 2x16 to display.

But even easier would be to have the Pi send the data to the display directly. The Arduino is wasted doing this trivial task

1 Like

what about something like

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd (0x27, 16, 2); // 16x2 at addr 0x27 

struct Server {
    int         id;
    int         cluster;
    const char *name;
    const char *ipAddress;
    const char *status;
    const char *statusName;
};

Server servers [] = {
    { 1, 1, "Web Server", "192.168.1.234", "E0", "No Err" },
    { 2, 1, "Server2",    "192.168.1.100", "E0", "No Err" },
    { 3, 2, "Server3",    "192.168.1.102", "E0", "No Err" },
};
const int Nserver = sizeof(servers)/sizeof(Server);

char s [90];

// -----------------------------------------------------------------------------
void disp ()
{
    Server *p = servers;
    for (int n = 0; n < Nserver; n++, p++)  {
        sprintf (s, "S %d, C %d, statis %s %s, %s",
                p->id, p->cluster, p->status, p->statusName, p->name);
     // Serial.println (s);
        lcd.clear ();
        lcd.print (s);
        delay (1000);
    }
}

void loop() {
    disp ();
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    lcd.begin();
    lcd.backlight();
}

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