Forum: Compiler & IDEs Vergleichstabelle USART


von Marius (Gast)


Lesenswert?

Hallo Leute,
ich bin ein C Anfänger und brauche einen kurzen Gedankenanstoß von Eurer 
Seite.
Aufgabe:
Ich möchte mehrere Pumpen Ansteuern. Die Pumpleistung wird über ein 
Steuerwort eingestellt welches ATMEGA169P über einen Port an 
Pumpencontroller ausgibt. Die Werte für Steuerwort sende ich über USART 
an ATMEGA. Die Kommunikation über USART steht, Pumpen Steuerung 
funktioniert auch.
Problem:
Ich möchte eine Art Tabelle erstellen in der alle erlaubten Werte für 
Steuerwort gespeichert sind. Und so soll der Beispielablauf erfolgen:

1.  Der User sendet ein gewünschtes Steuerwort von PC über USART an 
ATMEGA

2.   Das Programm durchsucht die Tabelle und vergleicht den empfangenen 
Wert mit den gespeicherten erlaubten Werten.

3.   Ist der empfangene Wert als erlaubt gespeichert wird ein Ok über 
USART and den User gesendet und Pumpencontroller aktualisiert.

Und hier brauche ich eure Hilfe. Wie erstelle ich eine solche Tabelle? 
Mit welchem Befehl durchsuche ich diese und vergleiche mit gesendeten 
Werten?

Vielen Dank in Voraus
Marius

von Jan (Gast)


Lesenswert?

Schau doch einfach in der Mainschleife ob etwas empfangen wurde.
Dann gehste mit ner while schleife das array durch in dem die 
Steuerworte gespeichert sind.

uint8_t i;
while(i>Anzahldersteuerworte,i++)
{
if (Empfangeneswort==steuerworttabelle[i])
{
tu was;
return 1;
}
return 0;
Das return 0 wird nur erreicht wenn kein Steuerwort mit deiner Tabelle 
übereinstimmt.

p.s. Steuerworte  brauchen viel Platz versuch es lieber mit einzelnen 
Buchstaben K für alles Ok  F für Fehler usw


mfg Jan

von Marius (Gast)


Lesenswert?

Hi ,
ich glaube ich habe es total falsch beschrieben. Über USART bekomme ich 
Strings wie
„Pump1 0“ ….. „Pump1 100“ (Pumpe 1 mit 0% Leistung bis 100% Leistung)
„Pump2 0 …...“Pump2 100“ (Pumpe 2 mit 0% Leistung bis 100% Leistung)
.
.
.
„PumpX 0“…...“PumpX 100“ (Pumpe X mit 0% Leistung bis 100% Leistung)

Diesen Strings muss ich dann das entsprechende Steuerwort zuweisen und 
an den Pumpencontroller senden. Da ich ca. 1000 unterschiedliche Strings 
habe (außer Pumpen werden noch andere Bauteile angesteuert) weiß  ich 
nicht wie ich das am besten löse. Kann ich eine Tabelle erstellen in der 
den Strings das entsprechende Steuerwort zugewiesen ist z.B Pump1 0 
=0x16. Ich müsste dann beim Empfang eines Strings die Tabelle 
durchsuchen und so das passende Steuerwort bekommen. Wahrscheinlich ist 
das komplett falsch was ich da vorhabe, aber wie gesagt ich habe noch 
nicht viel Erfahrung mit C und hoffe auf Eure Hilfe.
Ich brauche keine fertige Codes nur vielleicht die ungefähre 
Vorgehensweise oder Eure Meinung ob das Problem überhaupt so lösbar ist.

Grüße Marius

von Klaus W. (mfgkw)


Lesenswert?

Das hört sich für mich nicht komplett falsch an.
Bei mehreren Tausend würde ich aber nicht einfach ein
Feld nehmen, in dem die Werte irgendwie drinstehen (und
jedesmal das ganze Feld linear durchlaufen werden),
sondern ich würde die Elemente im Feld alphabetisch
sortiert ablegen (entweder schon vor dem Kompilieren,
oder notfalls bei Programmstart einmal mit qsort()
sortieren lassen) und dann mit bsearch() nach den
Einträgen suchen.

Dadurch muß man bei ca. 1000 Einträgen nicht 1000
Strings vergleichen, sondern maximal 10.
Bei einer Million Strings etwa 20 Vergleiche etc. dank
Laufzeitordnung O(log n).

Ggf. legt man nicht nur die Strings im Feld ab, sondern
je eine struct mit dem String und mehr Info, z.B. ein
Zeiger auf eine Funktion, die das Kommando bearbeitet.

Falls gleich jemand schreit, daß bsearch() böse ist, weil
es rekursiv arbeitet und deshalb Stack benötigt:
Nicht verrückt machen lassen.
Schließlich ist die Anzahl Elemente ja fest, und demnach
auch die Anzahl der Rekursionsebenen.
Bei den z.B. 1000 Einträgen braucht man also auf dem
Stack Platz für lediglich 10 bsearch()-Aufrufe, mehr nicht.

von Klaus W. (mfgkw)


Lesenswert?

Eine andere laufzeiteffiziente Möglichkeit wäre, aus jedem
String einen Hashwert zu berechnen und mit diesen Hashwerten
ein switch zu bauen, in das man mit dem zur Laufzeit
berechneten Hashwert des aktuellen Kommandos reingeht.
Ist aber eher umständlich und fehlerträchtig, weil bei den
ganzen case nur Konstanten stehen dürfen, man müsste also
da jeweils manuell berechnete Hashwerte eintragen.
Das würde ich nur machen, wenn ich diesen Quelltextabschnitt
automatisch generiere und nicht von Hand erzeuge.
Es muß ja auch geprüft werden, daß kein Wert doppelt vorkommt.

von Karl H. (kbuchegg)


Lesenswert?

Marius schrieb:
> Diesen Strings muss ich dann das entsprechende Steuerwort zuweisen und
> an den Pumpencontroller senden. Da ich ca. 1000 unterschiedliche Strings
> habe (außer Pumpen werden noch andere Bauteile angesteuert)

Das hört sich für mich allerdings nach einem komplett falschen Ansatz 
an.

Solche Dinge beginnt man, indem man sich eine Art Sprache überlegt.

PUMP1 100
und
PUMP1 10

sind nämlich dasselbe Kommando, mit jeweils einem anderen Argument und 
nicht einfach nur 2 unterschiedliche Strings.

Die Zahl bei PUMP1 wird wahrscheinlich die Pumpennummer sein. d.h. man 
baut sich hier eine Sprache die zb so aussieht

"PUMP" PumpNr  Wert

Das Kommando besteht aus insgesammt 3 Teilen (in diesem Fall)

* Dem eigentlichen Kommando  "PUMP"
Dieses sagt aus, dass sich das Kommando auf eine Pumpe bezieht und dass 
irgendeiner Pumpe einen neuen Wert zugewiesen bekommen soll

* Das erste Argument         PumpNr
Das ist einfach nur eine Zahl und identifiziert, auf welche Pumpe sich 
das Kommando bezieht

* Dem zweiten Argument       Wert
Wieder handelt es sich um eine Zahl, die den Wert angibt, auf den die 
Pumpe mit der Nummer <PumpNr> zu setzen ist

Der Empfänger erhält einen kompletten String

PUMP 3 56

er beginnt damit, den String in seine Bestandteile zu zerlegen.
  PUMP
  3
  56

Der erste Bestandteil ist das Kommando. Hier ist es das Kommando "PUMP". 
Und natürlich weiß der Empfänger, dass auf das Kommando "PUMP" noch 2 
Argumente kommen, die in beiden Fällen Textrepräsentierungen von Zahlen 
darstellen. Also wendet er zb atoi() auf die beiden Strings an, und 
erhält so die jeweiligen Zahlenwerte.

Jetzt hat man die Einzelteile vorliegen.
Weiters muss man sich noch raussuchen, wie sich das Steuerwort deiner 
Pumpensteuerung zusammensetzt. D.h. es wird irgendeine Vorschrift geben, 
mit der man aus der Pumpen Nummer und den Wert das entsprechende 
Steuerwort errechnen kann.

von Klaus W. (mfgkw)


Lesenswert?

Das schließt das bisher gesagte ja nicht aus.

Ich verstehe die Frage so, daß er erst nach dem ersten Teil,
z.B. "PUMP", weiß, wer der Empfänger ist und dem dann den Rest
übergibt.
Es kann ja sein, daß eine Pumpe einen zusätzlichen Wert braucht,
ein anderer Empfänger dagegen meinetwegen einen String und was
anderes.

Dann macht so eine Art Tabelle schon Sinn, weil man den String
erst nur soweit betrachtet, bis der Empfänger feststeht, dann
ruft man diesen mit dem restlichen String auf und der holt
sich dann die Info raus, die er braucht.
So hat man auch das Wissen des Empfängers beisammen gehalten
und braucht keinen Dispatcher, der alles analysiert und deshalb
wissen muß, was beispielsweise die Punpe genau an Infos
braucht.

Daß es allerdings gleich 1000 verschiedene Empfänger sein sollen,
kommt mir auch etwas fraglich vor...

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> Das schließt das bisher gesagte ja nicht aus.

Grundsätzlich nicht.

Ich denke allerdings, dass er sich die Tabelle so vorstellt

empfangener String     Steuerwort zur Steuerung
-----------------------------------------------
"PUMP1 0"              0x16
"PUMP1 1"              0x17
"PUMP1 2"              0x18
"PUMP1 3"              0x19
....


und diese "Tabelle" macht nun wirklich keinen Sinn.
(Das erklärt auch, wie er ratzfatz auf 1000 unterschiedliche 
Steuerstrings kommt)

> Daß es allerdings gleich 1000 verschiedene Empfänger sein sollen,
> kommt mir auch etwas fraglich vor...

Ditto.
Ich halte die 1000 Steuerstrings wieder mal für eine Sackgasse, in die 
sich der Progammierer durch mangelndes Wissen über Stringverarbeitung 
verirrt hat. Jemand der 1000 Geräte ansteuern soll, hat mit dem Aufbau 
und Durchsuchen von Tabellen sicher keine Schwierigkeiten :-)

Sollten es aber tatsächlich 1000 unterschiedliche Geräte sein, mit 1000 
unterschiedlichen Steuerkommandos, dann unterstütze ich natürlich deinen 
bsearch() Vorschlag. Macht absolut Sinn.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.