c++ / arduino: string zu variable parsen

Seite 1 von 1 - Forum: Coding Stuff auf overclockers.at

URL: https://www.overclockers.at/coding-stuff/c-arduino-string-zu-variable-parsen_245089/page_1 - zur Vollversion wechseln!


wergor schrieb am 02.01.2016 um 15:42

in meinem arduino projekt habe ich 1000+ zeilen zum parsen von kommandos, variablen etc, die über die serielle schnittstelle hereinkommen:

Code: CPP
bool EEPROMHandler::stringToVariable(uint16_t device, char* string, uint16_t& variable)
{
	if (device == EEPROMHandler::device_type_::GENERAL)
	{
		if (strcmp_P(string, PSTR("DISPLAY_AVAILABLE")) == 0)
		{
			variable = general_variable_:: DISPLAY_AVAILABLE;
			return true;
		}

		if (strcmp_P(string, PSTR("DISPLAY_TYPE")) == 0)
		{
			variable = general_variable_:: DISPLAY_TYPE;
			return true;
		}

		if (strcmp_P(string, PSTR("DISPLAY_RES_X")) == 0)
		{
			variable = general_variable_:: DISPLAY_RES_X;
			return true;
		}

		if (strcmp_P(string, PSTR("DISPLAY_RES_Y")) == 0)
		{
			variable = general_variable_:: DISPLAY_RES_Y;
			return true;
		}

		if (strcmp_P(string, PSTR("DISPLAY_UPDATE_INTERVAL")) == 0)
		{
			variable = general_variable_:: DISPLAY_UPDATE_INTERVAL;
			return true;
		}

		if (strcmp_P(string, PSTR("DISPLAY_BRIGHTNESS")) == 0)
		{
			variable = general_variable_:: DISPLAY_BRIGHTNESS;
			return true;
		}

		if (strcmp_P(string, PSTR("DISPLAY_CONTRAST")) == 0)
		{
			variable = general_variable_:: DISPLAY_CONTRAST;
			return true;
		}
...
hat jemand eine idee wie man das noch optimieren kann? ich würde gerne bei einem human readable protokoll bleiben.


Obermotz schrieb am 02.01.2016 um 15:52

Ich wuerde die ganzen Konstanten sauber in ein Array schreiben und dann via foreach drueber iterieren.

// Ah i see, da wirds ein Problem geben - in C++ laesst sich ein String nicht als Variablenname verwenden.. vielleicht faellt mir noch was ein.


11Fire01 schrieb am 07.01.2016 um 19:39

json file falls das für c++ gibt :p


wergor schrieb am 18.01.2016 um 23:18

danke für den tipp mit json, es gibt eine library für arduino dafür, die werde ich mir mal anschauen: https://github.com/bblanchon/ArduinoJson
ich bin aber trotzdem für weitere vorschläge offen :)


mat schrieb am 19.01.2016 um 00:55

Wie ist general_variable_:: DISPLAY_AVAILABLE definiert?


wergor schrieb am 19.01.2016 um 08:04

Code: CPP
struct general_variable_
{
	enum GeneralVariable_t_ : uint16_t
	{
		//...

		DISPLAY_TYPE = 30,			//(1 byte) display type.
		DISPLAY_RES_X = 32, 			//(2 byte) display resolution (x axis).
		DISPLAY_RES_Y = 34,			//(2 byte) display resolution (y axis).
		DISPLAY_UPDATE_INTERVAL = 36,		//(4 byte) display update interval in milliseconds.
		DISPLAY_CONTRAST = 40,			//(1 byte) display contrast setting
		DISPLAY_BRIGHTNESS = 41,		//(1 byte) display brightness setting

		//...
	}
}
die werte sind offsets von einer EEPROM- startadresse. die variable DISPLAY_AVAILABLE hab ich mittlerweile gelöscht.


Obermotz schrieb am 19.01.2016 um 09:38

Asoo. Dann bleib ich bei meiner Variante. String-Array sauber aufstellen (ob jetzt ausm JSON, einem Textfile oder im Code, ist egal).
Mit foreach durchiterieren, wenn der strcmp matcht, return array val.
Das ist ein Dreizeiler.

Falls du deinen Enum behalten willst, obwohl enums nicht wirklich zum durchiterieren geeignet sind, koenntest du dir diese Iterator-Klasse ansehen:
http://www.drdobbs.com/when-enum-ju...ion-c/184403955


wergor schrieb am 19.01.2016 um 11:23

Zitat von Obermotz
Asoo. Dann bleib ich bei meiner Variante. String-Array sauber aufstellen (ob jetzt ausm JSON, einem Textfile oder im Code, ist egal).
Mit foreach durchiterieren, wenn der strcmp matcht, return array val.
Das ist ein Dreizeiler.
ich glaube ich stehe gerade auf dem schlauch. meinst du return array index?

Zitat von Obermotz
Falls du deinen Enum behalten willst, obwohl enums nicht wirklich zum durchiterieren geeignet sind, koenntest du dir diese Iterator-Klasse ansehen:
http://www.drdobbs.com/when-enum-ju...ion-c/184403955
die enums würde ich mir gerne behalten, sonst muss ich erst wieder an anderer stelle in einer lut die indices nachschlagen.


Obermotz schrieb am 19.01.2016 um 13:59

Also die schoenste Loesung waere eine Hashmap: http://stackoverflow.com/a/3578247


Vinci schrieb am 19.01.2016 um 14:14

Zitat
#include <map>
#include <iostream>
#include <cassert>

Vielleicht sollt ma erst amal fragen wie viel Flash er denn hat? :p
Das Klumpat da oben braucht vermutlich scho amal >70K oder so...

Viel Potential zum "optimieren" seh ich eigentlich nicht. Viel schneller oder kleiner als deine Liste wirds vermutlich nicht werden.
Und "schöner" fällt im Embedded Bereich nicht unter optimieren :p


wergor schrieb am 19.01.2016 um 17:39

ich habe derzeit noch ca 160kb flash frei, aber das programm ist noch lange nicht fertig ;)
mein eigener naiver ansatz wäre gewesen ein array von structs zu erstellen:

Code: CPP
struct command_inst_
{
	const PROGMEM char* string;
	uint16_t command;
};

command_inst_ command_list_[NUM_CMDS];
dann könnte ich einfach drüber iterieren und den zum string passenden command zurückgeben, das würde aber wahrscheinlich in sachen geschwindigkeit, speicherverbrauch und lesbarkeit nix bringen :D




overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2025