Forum: Mikrocontroller und Digitale Elektronik Menü für ESP32 in VSC erstellen


von Hercules (hercules)


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

: Verschoben durch Moderator
von Uwe B. (boerge) Benutzerseite


Lesenswert?

Hercules schrieb:
> Daher die frage an euch. Wie setze ich sowas um. So das die einzelnen
> Programm wirklich getrennt von einander sind.

...mit einem Betriebssystem auf dem ESP! Der zweite Absatz des dt. 
Wikipedia-Artikels fasst es schön zusammen:
https://de.wikipedia.org/wiki/Betriebssystem

von Joh S. (joh93)


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.

: Bearbeitet durch User
von Εrnst B. (ernst)


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.

: Bearbeitet durch User
von ElC (elc)


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
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.