Wie speichere ich Ausgaben effizient ab?
-
Ich möchte gerne verschiedene Werte bei einem Mikrocontroller über eine Serielle Schnittstelle ausgeben. Wie das nun mal so mit Mikrocontrollern ist, habe ich wenig Rechenleistung (2 MHz, 16 Bit) weniger Festspeicher (Flash) noch weniger RAM (gerade mal 2kB) und überhaupt kein Betriebssystem zur Verfügung.
Da ich jedoch einige zeitkritische Dinge zu erledigen habe, kann ich mich nicht lange mit Ausgaben beschäftigen. Deshalb ist es wichtig, das ich einen kleinen Teil Ausgebe, und dann wieder was anderes erledige. Dazu habe ich mir nun folgendes überlegt:
Alle Werte die ich ausgeben möchte liegen als globale Variablen vor. Um nun an den Wert zu kommen benutze ich einen Zeiger. Um die Werte auch vernünftig formatieren zu können würde ich gerne die sprintf()-Funktion benutzen. Das Ganze sieht nun dann so aus:Ich definiere eine struct:
typedef struct { char *text; void *wert; } SIO_TEXT;
*text ist dann ein Zeiger auf den Steuerstring, der an sprintf() übergeben wird, *wert ist ein Zeiger auf die jeweilige globale Variable.
Mit dieser struct kann ich im Flash nun effizient vorgefertigte Ausgaben ablegen. Beispielsweise:const SIO_TEXT Ausgabe[] = { {"Batteriespannung: %f V ", &Batteriespannung}, {"Batteriestrom: %f A ", &Batteriestrom}, {"Anzahl der Batterien: %i Stück", &ZahlBatterien} {NULL; NULL} };
Ich habe mir nun überlegt, das ich mit jedem Programmdurchlauf (das gesamte Programm ist eine einzige große Schleife) nur eine Zeile ausgebe. Das würde Rechenzeit und RAM sparen. Ich übergebe also in jedem Programmdurchlauf an sprintf() als erstes Argument den Steuerstring, und als zweites Argument den Variableninhalt des Zeigers. Und hier steckt mein Problem:
Verschiedene Variable haben verschiedene Variablentypen. Um auf verschiedene Variablentypen mit einem einheitlichen Zeiger zeigen zu können muss ich den Zeiger vom Typ void definieren. Damit geht natürlich auch die Information verloren, um was für einen Variablentyp es sich handelt. Um jedoch die Variable an sprintf übergeben zu können, muss ich den Variablentyp kennen.
Wie komme ich aus diesem Dilemma heraus?
Wäre es möglich den Datentyp irgendwie mit abzuspeichern?
-
im prinzip hast du den variablentyp ja schon im formatstring abgespeichert.
Kurt
-
wenn du dies knappen randbedingungen hast kannst du probleme mit dem sprintf bekommen. Bei den meisten µControllern ist in der standardlibrary nur ein sprintf ohne float formate verwirklicht. Meistens musß man eine spezielle Library hinzubinden um auch die floatformate bearbeiten zu können. Diese ist dann deutlich größer und braucht auch erheblich mehr Rechenzeit zur formatierung.
Das kann nicht funktionieren, denn es wird der Wert auf den Stack gepackt und nicht der pointer uaf den Wert
Wie wäre es den mit folgender Lösung
int run=0; switch(run) { case 0: printf{"Batteriespannung: %f V \n", Batteriespannung}; run=1; break; case 1: printf{"Batteriestrom: %f A ", Batteriestrom}; run=2; break; case 2: printf{"Anzahl der Batterien: %i Stück", &ZahlBatterien}; run=0; break; default: ; //Absicht }
Wenn alle Variablen also auch die Anzahl der Batterien als float geschrieben ließe sich etwas in der Art deines Verfahrens
verwirklichen.Vielleicht kommst du auch für alle Werte mit integern aus. Wie ich Vermute liest du einen AD-Wandler aus. die Anzeige die du brauchst, kommt mit 2 Stellen nach dem Komma aus. Su könntest alles in Integer bei passender Skalierung Rechnen wenn die Werte mit 100 multiplizierst und sie als 2 Integer ausgibst der Wert vor dem Komma ist Messwert dividiert durch 100 der nach dem Komma Messwert modulo 100; Im Beispiel ist Batteriestrom als Integer angenommen.
printf{"Batteriestrom: %i.%i A ", Batteriestrom/100,Batteriestrom % 100};
Der Vorteil wäre du brauchst keinerlei floating point Zahlen, somit würde das Programm auch schneller laufen.