Auswahlmöglichkeit im Sketch

Hallo zusammen

Ich habe mir überlegt, einen Sketch für eine Motortreiber Ansteuerung zu schreiben für ein kleines ferngesteuertes Auto. Nun ist aber die Idee, dass man je nach dem welchen Motortreiber man auswählt, andere Programmteile verwendet werden sollten.
Mal ganz einfach gezeigt:

Motortreiber 1 muss die Steuerbefehle so erhalten:

Steuerbefehl und Prüfsumme1

Wenn man aber den Motortreiber 2 verwendet, dann muss er die Steuerbefehle mit einer andern Prüfsumme erhalten:

Steuerbefehl und Prüfsumme2

Wie kann man das am Beginn des Sketches definieren, dass wenn man Motortreiber 1 verwendet, Prüfsumme1 generiert wird und wenn Motortreiber 2 verwendet wird, Prüfsumme2 generiert wird?

Kann hier jemand ein ganz einfaches Beispiel zeigen?

Grüsse

Stef

du könntest mit Precompiler define arbeiten.


#define DRIVER A          // festlegen ob A oder B

#if DRIVER == A
//code für Driver A
void functionDo()
//..
void calcCRC()
//..
#else
// code für Driver B
void functionDo()
// ...
void calcCRC()
//..

#endif

Der Kompiler compiliert dann je nach der Definition für DRIVER den einen oder anderen Code.

Das sieht genau nach dem aus was ich gesucht habe! Vielen herzlichen Dank für den Tipp. Daran habe ich nicht gedacht. Einfach und man spart sich noch Speicherplatz auf dem Arduino, weil nicht alles hochgeladen wird was man nicht braucht, perfekt :slight_smile:

Musst du halt für den andern Treiber eine Zeile im Sketch anpassen und neu (übersetzen und) hochladen.

Andererseits: Könnte ein "universeller Sketch" überhaupt erkennen, welcher Treiber gerade aktiv ist?
Z.B. an den Steuerbefehlen selbst?

Eigentlich wäre es eine Aufgabe des Arduinos, im setup() den Motortreiber zu erkennen, und dann die Fernsteuerbefehle jeweils passend umzusetzen ...

Man kann auch einen Pin nehmen der je nach Treiber mit GND oder +Vcc verbunden wird und so dem Sketch anzeigt welcher Treiber angeschlossen ist.
In diesem Falle Muß der Sketch die Ansteuerung für beide Treiber enthalten aber nur der Teil für den gewählten Treiber ist aktiv.

Vorteil: Wenn man die Pinumschaltung mittels einer steckbaren Brücke (Jumper auf Pins) oder eines Schalters realisiert kann die Umschaltung und Austausch des Treibers jederzeit erfolgen.
Nachteil: es braucht mehr Speicher (FLASH) weil der Stektch teilweise doppelt vorhanden ist und nur ein Teil davon verwendet weid.

Bedingte Kompilierung wie in #2
Vorteil: Kleinerer Sketch im Speicher des Arduino. Der Quelcode ist größer aber nicht der gesamte QUellkode wird übersetzt.
Nachteil: Bei einem Wechsel des Treibers muß der Sketch neu kompiliert und hochgeladen werden.

Mein Vorschlag:
Ist der Sketch klein genug um beide Treiberversionen im sketch haben zu können ist die Auswahl durch ein Pin vorzuziehen.
Ist der Speicher knapp so kann eine bedingte Compilierung Speicher sparen und so das projekt erst ermöglichen.

Grüße Uwe

Vielen Dank für all die Ideen und Tipps! Ich werde mal die Variante von #2 nehmen, da normalerweise nur am Anfang definiert werden muss was genommen wird. Auch ist das mit dem Speicherplatz sparen eine gute Sache und ermöglicht jederzeit eine Erweiterung des Sketches ohne zusätzlichen Platzprobleme zu lösen.
Aber ich merke mir das mit den Pins. Das ist sehr interessant wenn wirklich ohne Programmierungsanpassung der Treiber getauscht würde. Eine sehr gute Idee so zu lösen, danke für die gute Idee/Hinweis!

Hallo,

ich hätte noch andere Varianten. Alles was konstant und nie wahr werden kann wird vom Compiler entsorgt.

Ganz simpel wäre:

constexpr bool DRIVERA {true};
constexpr bool DRIVERB {false};

void setup (void)
{
}

void loop (void)
{
  if (DRIVERA)
  {
    // mach hier sinnvolle Dinge
  }

  if (DRIVERB)
  {
    // mach hier sinnvolle Dinge
  }
}

oder verschärft

constexpr bool DRIVERA {true};
constexpr bool DRIVERB {false};

void setup (void)
{
}

void loop (void)
{
  if constexpr (DRIVERA)
  {
    // mach hier sinnvolle Dinge
  }

  if constexpr (DRIVERB)
  {
    // mach hier sinnvolle Dinge
  }
}

oder mit switch case

enum Driver {A, B}; 
constexpr Driver driver {A};

void setup (void)
{
}

void loop (void)
{
  switch (driver)
  {
    case A:  
            // mach hier sinnvolle Dinge
            break;
            
    case B: 
            // mach hier sinnvolle Dinge
            break; 
            
   default: break;        
  }
}

und verschärft

enum class Driver : byte {A, B}; 
constexpr Driver driver {Driver::A};

void setup (void)
{
}

void loop (void)
{

  switch (driver)
  {
    case Driver::A:  
                      // mach hier sinnvolle Dinge
                      break;
    case Driver::B: 
                      // mach hier sinnvolle Dinge
                      break;         
  }
}

Ich weiß jetzt nicht, ob "verschärft" ein optimierteres Compilerverhalten ermöglicht/erzwingt, und gebe zu bedenken, dass in der Aufgabenstellung vermutlich einiges unabhängig von den Driver-Varianten gleich bleiben wird. Das spricht dann meiner Meinung nach eher für gelegentliche if statt switch.
Man kann übrigens auch ausnutzen, dass Funktionen, die gar nicht verwendet werden, beim Linken unter den Tisch fallen.

Aber die eigentliche Frage bleibt: Neukompilieren je nach Driver oder nicht?
(Für nicht genutzten Speicherplatz gibt's kein Geld zurück, kostet sogar die gleiche Strommenge)

Hallo,

mit "verschärft" ist gemeint das "if constexpr" die Steigerungsform von nur "if" ist. Das wird auf jeden Fall zur compile time geprüft. Das einfache "if" mit konstanten Ausdruck hat jedoch den gleichen Effekt. So schlau sind die Compiler schon. Das hatten wir schon einmal für Fall als "Debugschalter" für bedingte serielle Ausgaben.
Beim enum vs. enum class ist der Zugriffsschutz strenger.
Das sind alles Feinheiten im Umgang mit C++.
In dem Fall hier ist das Endergebnis jeweils immer gleich, solange die entscheidende Auswahlvariable konstant ist. Wie du schon sagst, alles was deshalb nie wahr werden kann fällt unter den Tisch. Ich wollte zusätzlich unterschiedliche Ansätze zeigen, wollte niemanden verwirren. :wink: Für if constexpr muss man meines Wissens auch auf C++14 oder höher umstellen, fällt mir soeben ein.

Eins noch. Wegen dem Satz. "Für nicht genutzten Speicherplatz gibt's kein Geld zurück, kostet sogar die gleiche Strommenge". Der Satz ist ja komplett richtig und sehe ich auch so wie du. Mit vielleicht einem Unterschied. Wenn der Compiler diversen ungültigen Code rauswerfen kann, dann wird meistens einhergehend auch die Laufzeit optimiert, sprich kürzer.
Wenn ich abschweifen darf. Genau das ist der Lohn einer aufwendigen Template Programmierung. Viel Aufwand für maximale Freiheiten in den konstanten Parametern und am Ende wird alles zur compile time auf ein Minimum zusammengeschrumpft. Das heißt minimaler Programmcode der sehr schnell durchlaufen werden kann. Anstatt zur Laufzeit immer wieder die gleichen langatmigen Entscheidungsbäume durchzuhangeln. Die Entscheidung ist nur, braucht man das, will man das, macht das einem Spass. Man kann da durchaus Lunte riechen.

Weitermachen. :wink:

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