Return mit variablen Datentyp deklarieren

Hallo,
ich lese ein Messgerät aus, welches mir die Messwerte über die serielle Schnittstelle als HEX zur Verfügung stellt. Diese werden dann in einem char array gespeichert. Anschließend wird die Checksumme überprüft, Nibble neu zugeordnet und eigentlich soll dann der HEX zur weiteren Verarbeitung als Dezimalwert angezeigt werden.

Für die Umwandlung von HEX zu Dezimal habe ich eine Funktion geschrieben. Das Messgerät gibt die Rückgabewerte in unterschiedlicher Länge und Genauigkeit aus, von 8 bis 32 bit. Die Rückgabevariable meiner Funktion sollte also 32 bit entsprechen. Nun habe ich aber auch festgestellt, dass sowohl unsigned als auch signed 32 bit Werte vom Messgerät ausgegeben werden, wodurch sich ja der Wertebereich ändert.

Ich nehme an, dass ich vorher wissen und evtl. auch hinterlegen muss, welchen Dateitypen der vom Messgerät empfangene Wert entspricht? Und um zwei getrennte Funktionen für jeweils signed und unsigned komme ich auch nicht drumherum?

Irgendwie muss Dir das Messgerät erst mal mitteilen, was es Dir senden will. Zumindest signed/unsigned und evtl. die Länge.
Ansonsten kannst Du auch gleich einen Zufallsgenerator nehmen.

Gruß Tommy

Return mit variablen Datentyp deklarieren
...
Und um zwei getrennte Funktionen für jeweils signed und unsigned komme ich auch nicht drumherum?

Der Rückgabe Datentype einer Funktion ist nicht ganz so einfach "flexibel" zu bekommen!

template<typename MeinDatenType> MeinDatenType funktion()
{
  return 42;
}

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

  Serial.println(funktion<float>());
  Serial.println(funktion<byte>());
  Serial.println(funktion<char>());
}

void loop() {}

Du solltest dir 12 mal überlegen, ob du das wirklich willst.

Leider verstehe ich dein Problem überhaupt nicht.
Von daher vermute ich einen Fehler in deinen Annahmen

Hallo Tommy,
leider teilt mir es nicht das Messgerät mit, ich habe ein HEX-Protokoll erhalten. Dort steht beschrieben, zur welchen abgefragten Information der jeweilige Dateityp zurückgegeben wird. Bisher hatte ich mit meiner Programmierung auch noch nie Probleme und möglicherweise wird es die auch gar nicht geben.. Bei genauerer Prüfung des Protokolls konnte ich eben entnehmen, dass ich vermutlich nie einen Overflow bei irgendwelchen Abfragen erhalte. So viele Rückgabewerte mit uint32_t gibt es auch gar nicht. Die Abfrage der Laufzeit des Messgerätes wäre z.B. ein solcher. Diese wird in Sekunden ausgegeben..

Wenn ich den Rückgabewert meiner Funktion als int32_t deklariere, würde ich wohl erst nach 2147483647 Sekunden (etwa 68 Jahren) fehlerhafte Werte bekommen. Ich glaube darüber muss ich mir dann keine Gedanken mehr machen. Das Messgerät läuft zwar im Dauerbetrieb, auch mehrere Jahre am Stück.. aber nun gut.

Werde das Protokoll morgen doch nochmal genauer prüfen, vermutlich mache ich mir zu viele Gedanken um nichts. Prinzipiell muss ich den Dateityp des Rückgabewertes aber kennen um damit richtig umgehen zu können. Dieser wird wie gesagt nicht mit dem HEX übermittelt und ich müsste ihn selbst für die jeweilige Abfrage in einer Bibliothek hinterlegen.

Dort steht beschrieben, zur welchen abgefragten Information der jeweilige Dateityp zurückgegeben wird.

Je nach Abfrage bekommst Du eine Antwort. Verwende für jede Antwort die richtige Funktion. Du brauchst mehrere Funktionen.
Grüße Uwe

seackone:
... vermutlich mache ich mir zu viele Gedanken um nichts.

Das vermute ich auch, aber dennoch kann man ja mal was probieren.

Über die Zeichenkette hast Du nicht gesagt, also denke ich mir ein 'U' oder 'L' hinter der Zahl aus.

Klein Fritzchen sagt: "Zweiunddreißig Bits sind zweiunddreißig Bits, egal, was sie bedeuten. Also übergebe ich zweiunddreißig Bits an eine Funktion, die mir diese mit Einsen und Nullen füllt. Als Rückgabe die Information, ob ein 'L' für signed gefunden wurde. Ist das der Fall, konvertiere ich unsigned in signed. Getestet mit UNO:

void setup() {
  Serial.begin(9600);
  Serial.println("\nStart");
  char t1[] = "4037677363U";
  char t2[] = "4037677363L";
  uint32_t uwert = 0;
  int32_t wert = 0;
  if (wandlung(t1, uwert)) {
    wert = int32_t(uwert);
    Serial.println(wert);
  } else {
    Serial.println(uwert);
  }
  if (wandlung(t2, uwert)) {
    wert = int32_t(uwert);
    Serial.println(wert);
  } else {
    Serial.println(uwert);
  }
}

bool wandlung(char *text, uint32_t &w) {
  Serial.println(text);
  char * vz;
  w = strtoul (text, &vz, 10);
  Serial.println(w);
  return (vz[0] == 'L');
}

void loop() {
  // put your main code here, to run repeatedly:
}

Ob es wohl funktioniert?

Hallo,
vielen Dank für eure Antworten. Ich habe mich heute noch ein wenig mit dem HEX Protokoll beschäftigen können und tatsächlich scheint es viel Rauch um nichts zu sein. Lediglich bei der Produkt-ID des Messgerätes (Rückgabe ebenfalls als int32_t) gab es dann tatsächlich einen komischen Wert, ansonsten sollte die Reduzierung des Wertebereichs für int32_t keine Rolle spielen. Ich werde dort nie an irgendwelche Grenzen stoßen. Solche Sachen wie Produkt-ID sind mir auch nicht wichtig, habe ich zuvor noch nie abgefragt.

@combie: Vielen Dank für dein Input. Mir war nicht bewusst, dass es wirklich möglich ist, Funktionen mit variablen Rückgabetypen zu definieren. Habe ich wieder etwas gelernt. Benötigt habe ich es zuvor noch nie, aber falls ich es aus irgendeinem Grund doch mal wirklich brauche, weis ich ja jetzt wo es steht.

Der Knackpunkt ist bei mir einfach, dass mein Programm nicht weis, welcher Variablentyp vom Messgerät zurückgegeben wird. Wenn ich es wirklich ordentlich machen will, muss ich meine Library dahingehend ergänzen.

@agmue: Ich finde deinen Vorschlag auch sehr interessant, habe ihn mal ausprobiert und nachvollzogen. Allerdings muss ich ja auch wissen, ob die Typen einen Vorzeichen besitzen oder nicht. Dennoch hat mich deine Idee zu einem neuen Ansatz angeregt, bei dem ich dein Beispiel in ähnlicher Form verwenden werde. Vielen Dank!

Vielen Dank nochmal. Ich habe die erwarteten Dateitypen in meiner Bibliothek hinterlegt und mache dann eine ähnliche Abfrage/Konvertierung von uint32_t zu int32_t wie es agmue in seinem Beispiel hatte. Dadurch brauche ich keine zusätzliche Funktion und mache die Konvertierung außerhalb. Eigentlich ziemlich einfach.. hm. :confused:

seackone:
Eigentlich ziemlich einfach.. hm. :confused:

So soll es sein :smiley:

@combie: Vielen Dank für dein Input. Mir war nicht bewusst, dass es wirklich möglich ist, Funktionen mit variablen Rückgabetypen zu definieren. Habe ich wieder etwas gelernt. Benötigt habe ich es zuvor noch nie, aber falls ich es aus irgendeinem Grund doch mal wirklich brauche, weis ich ja jetzt wo es steht.

Ja, ist schon eine spannende Ecke....

Eigentlich sind es ja 3 Funktionen, welche da nach Bedarf erzeugt werden.
So ganz variabel ist der Type also nicht, er muss zur Kompilezeit festgelegt werden, bzw. bekannt sein..

Das Thema gehört im allgemeinen Sinne zur "Generativen Programmierung".
C++ ist hier mein Generator.

Treffend ist auch das Thema "Generische Programmierung"

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