Variablen Zugriff in anderen Dateien

Hi
Ich beschäftige mich grade mit Tasmota und versuche mir eine Individuelle Seite zu machen.
Ich habe in der xdrv_01_9_webserver.ino eine kleine testseite angelegt:

void HandleAchimPage(void) {
  Webserver->send(200, "text/html", "<html><body><h3>Achim Mini</h3><p>Nur ein direkter Test.</p></body></html>");
}

Bis dahin alles ok, Ich kann die aufrufen und sehe den Test-Text.
Jetzt möchte ich aber von anderen Tasmota Dateien Daten auf meiner Seite anzeigen und da ein bisschen zu Übungszwecken mit html rumspielen.

Allerdings stehe ich vor dem Problem das Ich nicht schaffe die Daten von den anderen Seiten abzugreifen zb:

void HandleAchimPage(void) {
  Webserver->send(200, "text/html", "<html><body><h3>Achim Seite</h3>");
  for (uint8_t i = 0; i < sml_globs.maxvars; i++) {
    if (i >= sml_globs.meters_used) break;  // Optional: Abbruchbedingung
    double val = sml_globs.meter_vars[i];
    char buf[64];
    snprintf(buf, sizeof(buf), "<p>Var %d: %f</p>", i, val);
    Webserver->sendContent(buf);
  }
  Webserver->sendContent("</body></html>");
}

sml_globs ist ein struct in der Tasmota Datei xsns_53_sml.ino

Bei kompillieren mit Platform IO bekomme Ich so Fehler:
error: 'sml_globs' was not declared in this scope

Ich erkläre mir das so das er sml globs nicht findet, weil der Kompiler nicht weis das der in einer anderen Datei ist. Ich habe heute schon den ganzen vormittag versucht mit define oder include dem kompiller zu erklären das das struct woanders ist.
Aber Ich komme auf keinen grünen Zweig.

Meine letzte Lösung wäre das ich vllt in der User config globale Variablen anlege und in der xsns_53_sml.ino die Werte in die globalen Variablen schreibe. Das würde wahrscheinlich klappen.
Aber es müsste doch auch irgendwie gehen direkt auf das struct zuzugreifen.

Hat eventuell jemand eine Idde?

lg
Achim

Aehm, die gehört doch ins Projekt.

HI,
Danke für deine Antwort.
Wie genau meinst du das?
xsns_53_sml.ino wird aufjeden Fall mit kompilliert und läuft auch

lg
Achim

Ok, wenn die mitkompiliert wird, dann gibt es dafür keinen Prototypen, der bei Abarbeitung des Compilers von HandleAchimPage zur Verfügung steht.

Das lässt sich bestimmt auflösen.

Grad mal geschaut. Das ist auch so wie es aussieht nicht dafür gedacht, dass Du da die Inhalte aus dem Struct nutzen sollst...

Was Du machen könntest:
In der xsns eine Funktion rein schreiben, die Dir die Werte zurück gibt.

Ich bin bei PlatformIO raus....

@achim86
Wenn Du also unbedingt auf die Struktur direkt zugreifen willst hilft vielleicht eine zusätzliche Zeile vor dem setup():

// struct SML_GLOBS;   // vielleicht auch noch dieses, damit der Strukturtyp bekannt wird
extern struct SML_GLOBS sml_globs;

@my_xy_projekt
PlatformIO ist nicht so schlimm (verwende ich inzwischen ganz gern); es erfordert u.a. aber die Deklarationen, bei denen die Arduino IDE durch Aktivitäten Hintergrund manches gerade zieht bzw. verzeiht.

Die hab ich gesucht :+1: war mir mit dem Aufruf nicht sicher :man_shrugging: dann lieber lassen :slight_smile:

Die struct ist hoffentlich in einem Header definiert und braucht nur ein Include.

Ansonsten ist die Forward declaration die Lösung.

Leider nicht. Das Ding steht so in xsns_53_sml.ino:

struct SML_GLOBS {
...
} sml_globs;

Da wir keinen compilier- und testbaren Minimalcode haben, war ich zu faul, um das auszuprobieren. Deshalb ist #5 "ohne Gewähr" - wie die Lottozahlen :slight_smile:

Nein. Sie steckt in

und hat eigentlich auch nur dort ihren Gültigkeitsbereich. Wie ich schon schrub, der Inhalt ist nicht dafür gedacht an anderer Stelle wieder-/weiterverwendet zu werden.
Darum bin ich etwas zwiegespalten, was den Direktzugriff auf den Inhalt angeht.

HI,
Danke für die vielen Antworten.
Wenn die struct nicht für den Zugriff von aussen gedacht ist, brauche Ich eine andere Lösung.
Ich würde dann wohl doch versuchen eine Funktion in der xsns zu schreiben die mir die Werte zurück gibt. Das wäre wahrscheinlich der richtige Weg.

lg
Achim

Du könntest Dir eine getFunktion() dort bauen und einfach für die gesuchten Werte einen neuen Struct bauen und den insgesamt zurück geben.

Dann brauchst Du zwar auch das Prototyping für die Funktion, kannst dann aber die Werte nicht versehentlich verändern...

Die struct-Definition selbst muss öffentlich werden.
Man kann die get Funktion so definieren, dass sie zwar eine
const Referenz auf die struct liefert, damit man diese aber dennoch nicht ändern darf.

struct DATA {
    DATA(int a, float b): a(a),b(b){} 
    int a; float b;
};
// const DATA& get() ; // Deklaration nicht erforderlich in Arduino IDE


void setup() {
  Serial.begin(115200);
  Serial.println(get().b);
  // Serial.println(d.b);  // error: 'd' was not declared in this scope
  // get().a++; // error: increment of member 'DATA::a' in read-only object
  Serial.println(get().a);
}
void loop() { }
// erst später definiert ...
DATA d (10,0.1);
const DATA & get() {return d;}

Dann würde es ja Sinn machen, ein Konstrukt aus beidem zu machen, um nicht in das Tasmota einzugreifen.
Also zum einen den Prototypen für das struct wie von @wno158 vorgeschlagen und dann einen eigenen Funktionsblock der sich den Inhalt des struct schreibgeschützt holt.