"We are back" « oc.at

c++ / arduino: string zu variable parsen

wergor 02.01.2016 - 15:42 3458 10
Posts

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: vulkanland
Posts: 4111
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

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
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.
Bearbeitet von Obermotz am 02.01.2016, 15:54

11Fire01

Here to stay
Registered: Dec 2002
Location: austria
Posts: 2417
json file falls das für c++ gibt :p

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: vulkanland
Posts: 4111
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

Administrator
Legends never die
Avatar
Registered: Aug 2003
Location: nö
Posts: 25476
Wie ist general_variable_:: DISPLAY_AVAILABLE definiert?

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: vulkanland
Posts: 4111
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

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
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
Bearbeitet von Obermotz am 19.01.2016, 09:45

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: vulkanland
Posts: 4111
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.
Bearbeitet von wergor am 19.01.2016, 11:24

Obermotz

Fünfzylindernazi
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
Also die schoenste Loesung waere eine Hashmap: http://stackoverflow.com/a/3578247

Vinci

hatin' on summer
Registered: Jan 2003
Location: Wien
Posts: 5832
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
Bearbeitet von Vinci am 19.01.2016, 14:16

wergor

connoisseur de mimi
Avatar
Registered: Jul 2005
Location: vulkanland
Posts: 4111
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
Bearbeitet von wergor am 19.01.2016, 17:40
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz