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
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
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
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.
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.
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.
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...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.