Menü für ESP32 in VSC erstellen

OP #7502791
Lesenswert?

Hallo zusammen,

ich bin zwar kein Anfänger in der Mikrocontroller Programmierung, doch die Projekte die ich bisher für mich privat realisiert habe, hatten einen geringeren Umfang als mein jetziges. Dementsprechend habe ich einige Fragen. Ich Arbeite mit VSCode und der der PlatformIO IDE und schrieb bisher kleinere Programme für den ESP32. Mein aktuellsten Projekt soll, grob gesagt, ein Menü haben wo man auswählen kann, welches "Sub-Programm" man nutzen möchte. Folgendes Beispiel möchte ich nicht umsetzen, verbildlicht aber mein anliegen: Ich habe eine Menü wo ich zwischen verschiedene Spielen aussuchen kann. Soweit so gut.

Ich frage mich grade nur wie ich das umsetze. Die einzelnen Programme sind mehr oder weniger fertig geschrieben und funktionieren auch, wenn man Sie als einzelnes Programm auf den Controller lädt. Dies ist aber nur die halbe miete.

Ich habe mir überlegt das Menü so zu schreiben, dass ich mit Switch Case die einzelnen Programm aufrufen kann. Die Überlegung dass man vom Menü Programm, in ein anderes Programm "springt" scheint mir nicht möglich zu sein. Macht man sowas am besten etwa mit Headerdatein? Ich weiß es nicht.

Daher die frage an euch. Wie setze ich sowas um. So das die einzelnen Programm wirklich getrennt von einander sind. Ist für die Übersicht, Fehlersuche und Erweiterbarkeit am sinnvollsten.

Viele Grüße

#7503988
Lesenswert?

In der Theorie kann man es so etwa machen:

Host Partition -> Startet nach Reset und hostet das Menu. -> Steuert ein Reset Safe Struct bei um die "Cluster"(Spiele Partitionen) zu verwalten ( wenn ein direkt Sprung von Spiel A nach Spiel B zB gewünscht ist). -> Schreibt in das Struct das gewünschte Spiel und springt direkt oder per Reset, falls nötig, an die Startadresse des gewählten Cluster.

Cluster Partitionen: -> Stellen ein Interface zur Verfügung, was zum Host oder mit einem Reset wieder zum Host springt.

Das ist jetzt nur ganz grundsätzlich ein Vorgehen, wie man die Spiele gleich lassen kann. Evtl kann man auch direkt die Startadresse vor dem Reset manipulieren, das weiß ich aber nicht). Mit dem Reset stellt man zB uninitialisierte Peripherie für das jeweilige Spiel sicher. Grundsätzlich ist das kein großes Hexenwerk, man wird nur einiges selber am Memory Layout rumbasteln müssen.

#7504017
Lesenswert?

Hercules schrieb:

Ich Arbeite mit VSCode und der der PlatformIO IDE

Arduino-Framework?

Schmeiß den Quellcode der einzelnen Spiele zusammen, lass alles gemeinsam kompilieren, aber benenn die "setup()" und "loop()" jeweils um. Dabei sind sicher viele gemeinsam benutzte Funktionen dabei, die dann auch nur einmal im Flash landen.

Und dann in etwa:

1
void setup() {
2
  aktives_programm=MENU;
3
  setup_menu();
4
}
5

6
void loop() {
7
  switch (aktives_programm) {
8
    case MENU: loop_menu(); break;
9
    case SPIEL1: loop_spiel1(); break;
10
    case SPIEL2: loop_spiel2(); break;
11
  }
12
}

usw.

Beim Wechsel des Aktiven Programms einmal das zugehörige "setup_spielX()" laufen lassen. Wenn darin Sachen initialisiert werden, die wieder aufgeräumt gehören, z.B. Interrupts, große Speicher-Allokationen: für jedes noch eine "cleanup_spielX()"-Funktion schreiben, die beim Programmwechsel vor dem setup des nächsten läuft.

1
void switch_task(task_enum_t new_task) {
2
  switch (aktives_programm) {
3
    case MENU: cleanup_menu(); break;
4
    case SPIEL1: cleanup_spiel1(); break;
5
    case SPIEL2: cleanup_spiel2(); break;
6
  }
7
  aktives_programm=new_task;
8
  switch (aktives_programm) {
9
    case MENU: setup_menu(); break;
10
    case SPIEL1: setup_spiel1(); break;
11
    case SPIEL2: setup_spiel2(); break;
12
  }
13
}

Und wenn dir die ganzen switch-case-Teile auf die Nerven gehen: bastel dir ein Array-von-Struct-mit-Funktionspointern. Oder, mehr OOP, Objekte.

Und wenn dir für die Fehlersuche das Starten des jeweils zu debuggenden Programms über das Menu zu aufwändig ist: änder setup(), so dass gleich das richtige loslegt.

#7504490
Lesenswert?

Hi,

1
Hi,
2
so könnte es prinzipiell aussehen.
3

4
Lösung 1 - einfach
5
-------------------
6
menu setup
7
menu loop
8
game1 setup
9
game1 loop
10
game2 setup
11
game2 loop
12
...
13
reset button in every game --> ESP.restart();
14

15

16

17
Lösung 2 - das letzte Game beim Einschalten wieder starten
18
-----------------------------------------------------------
19
// Read menuIndex on startup or reset
20
void preferencesRead(void)
21
{
22
  // read menu index, stored permanently
23
  // 0 or undefined = menu, 1 = game1, 2 = game2 ...
24
  preferences.begin("menuIndex", true);
25
  menuIndex= preferences.getInt("menuIndex", 0);
26
  preferences.end();
27
}
28

29
-
30
if menuIndex == 0   // perform menu
31
preferencesWrite()  // write menuIndex 1 for game1 / 2 for game2 ...
32
ESP.restart();
33
-
34

35
-
36
if menuIndex == 1   // perform game1 setup & loop
37
preferencesWrite()  // write menuIndex 0 for menu (Reset/Exit Button)
38
ESP.restart();
39
-
40

41
-
42
if menuIndex == 2
43
game2               // perform game2 setup & loop
44
preferencesWrite()  // write menuIndex 0 for menu (Reset/Exit Button)
45
ESP.restart();
46
-
47

48

49

50
// Write menuIndex selected
51
void preferencesWrite()
52
{
53
  // write menu index, stored permanently
54
  preferences.begin("menuIndex", false);
55
  preferences.clear();
56
  preferences.putInt("menuIndex", menuIndex);
57
  preferences.end();
58
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren