Hallo, folgendes Problem möchte ich lösen. Ich habe einen char Buffer dieser enthält einen Text. Nun soll zur Laufzeit, wenn ein bestimmtrest Wort vorkommt soll ab diesem Wort danach alles mit printf ausgegeben werden. Welche Möglichkeit gibt es da?
mit strstr nach dem Wort suchen, den zurückgelieferten Zeiger für die Ausgabe nutzen.
Flo schrieb: > Welche Möglichkeit gibt es da? Viele. Suchst du eine zur Laufzeit schnelle oder eine einfach zu realisierende ?
Flo schrieb: > Welche Möglichkeit gibt es da? Die einfachste Möglichkeit ist in einem Forum deiner Wahl zu betteln, dass dir jemand den Code schreibt. Das funktioniert immer, und du musst nicht einmal denken.
Ansonsten kann man auch bei google "c string functions" eingeben, und erhält 354000000 Ergebnisse z.B. https://beginnersbook.com/2014/01/c-strings-string-functions/ Da müsste man dann denken.
Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere Möglichkeit? Es wird beim Empfang von seriellen Daten eingesetzt.
Flo schrieb: > Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere > Möglichkeit? > Es wird beim Empfang von seriellen Daten eingesetzt. Es ist erst Donnerstag. Den einen Tag hättest du noch warten können.
Flo schrieb: > Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere > Möglichkeit? Hast du dir denn vorher Gedanken gemacht, was schnell und langsam in diesem Fall bedeutet? Oder ist es einfach nur gefühlt langsam?
Flo schrieb: > Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere > Möglichkeit? > Es wird beim Empfang von seriellen Daten eingesetzt. Dass das auf einem PC zu langsam zum Empfang von seriellen Daten ist, halte ich für sehr unwahrscheinlich.
Flo schrieb: > Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere > Möglichkeit? > Es wird beim Empfang von seriellen Daten eingesetzt. Wahrscheinlich wartet er noch auf das fehlende r. Oder wie sieht dein Programm aus?
Die Applikation ist in C/C++ geschrieben. Ich benutze windows.h um auf die relevanten Funktionen für die serielle Schnittstelle zu nutzen. In einem Thread wird ständig geprüft ob Daten von der seirellen Schnittstelle anliegen.
OldMan schrieb: > Klaus W. schrieb: >> Oder wie sieht dein Programm aus? > > Das will niemand wirklich sehen ;-) Doch Damit ich heute noch mal ein Lächeln im Gesicht habe.
PittyJ schrieb: > OldMan schrieb: >> Klaus W. schrieb: >>> Oder wie sieht dein Programm aus? >> >> Das will niemand wirklich sehen ;-) > > Doch > > Damit ich heute noch mal ein Lächeln im Gesicht habe. Gerade den Code gesehen, es war sogar ein Lachen.
PittyJ schrieb: > Gerade den Code gesehen, es war sogar ein Lachen. Was hilft diese Arroganz jetzt dem TE? Um's konkret zu machen: * der gezeigte Code enthält keinerlei Auswertung der empfangenen Zeichen; aber genau um diese geht es ja eigentlich im Thread hier * immer mal was zu lesen und dann eine ganze Sekunde warten beschwört ja (je nach Baudrate) Datenverluste regelrecht herbei; ich habe keine Ahnung vom Windows-API, aber es sollte doch irgendeine API-Methode geben, mit der man auf ein (oder mehrere) Zeichen warten kann, genau an der Stelle sollte der Thread warten * einen Zeiger zuerst zu benutzen (pSeriell->LastInterruptTime=pSeriell->LastTime;) und danach zu testen, ob er nicht 0 ist, ist natürlich Humbug
:
Bearbeitet durch Moderator
Flo schrieb: > Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere > Möglichkeit? > Es wird beim Empfang von seriellen Daten eingesetzt. Ah, fein, 2 weitere Salamischeiben. Ja, üblicherweise verwendet man eine state-machine als Parser für Einzelzeichen, der im state sich merkt wie viele Zeichen vorher korrekt waren und bei erkannter Zeichenfolge ein flag setzt so dass nachfolgende Zeichen ausgegeben werden. Wie viele braucht es noch bis die Salami komplett ist ? Flo schrieb: > Die Applikation ist in C/C++ geschrieben Ähm, nein. Du hast irgendwas von irgendwo her kopiert ohne zu wissen was es tut.
Wenn Nachrichten eintreffen wird die Callback Funktion ausgeführt. In dieser Callback Funktion wird dann die Funktion RxFrame ausgeführt.
1 | void RxCallback() |
2 | {
|
3 | Len = Port.pM->ReceiveFrame(&Port, RxBuffer, UART_FRAME_SIZE); |
4 | if (Len ) |
5 | {
|
6 | |
7 | }
|
8 | }
|
Jörg W. schrieb: > PittyJ schrieb: >> Gerade den Code gesehen, es war sogar ein Lachen. > > Was hilft diese Arroganz jetzt dem TE? > Nein, die hilft ihm überhaupt nicht. Allerdings ist der Code nicht von ihm. Wer sich in Callbacks etc. begibt, der sollte schon mal einfache Stringverarbeitung kennen. Die Stelle, wo er die Vergleich machen möchte, befindet sich nicht im Sourcecode, sondern müßte komplett ergänzt werden. Das, was wir als Source sehen, ist ein Copy& Paste, ohne dass der TO wirklich eine Ahnung davon hat. Ich plädiere immer dafür, erst einmal ein paar Basics zu lernen. So einfach mal alle Stringfunktionen. Oder auch std::string, weil die angenehmer sind. Sorry: 90% Copy und Paste, die restlichen 10% aus dem Forum hier? So geht die Welt nicht.
Jörg W. schrieb: > immer mal was zu lesen und dann eine ganze Sekunde warten Sleep wartet nicht eine Sekunde, sondern eine Millisekunde. https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep
Ja genau nur eine Millisekunde. Ich bin aktuell dabei das ganze nochmals durchzugehen woran es genau liegen könnte. Im Prinzip werden mittels Thread geprüft ob Daten anliegen wenn ja sollen diese im Puffer gespeichert werden. Die Daten von der seriellen Schnittstelle haben eine Enderkennung "\r\n". Und ein gültige Nachricht beginnt immer mit einem + danach folgenden die Daten und zum Schluss werden zur Enderkennung die zwei Zeichen gesendet "\r\n".
DerEgon schrieb: > Jörg W. schrieb: >> immer mal was zu lesen und dann eine ganze Sekunde warten > > Sleep wartet nicht eine Sekunde, sondern eine Millisekunde. Ah OK. Trotzdem Mist: man wartet auf ein Ereignis und nicht stur 'ne Zeit ab. Unter Posix würde man poll() benutzen. Was auch immer Win-API da hat, sollte man nehmen.
Der Code wo ich da habe ich echter Mist. Bin da etwas überfragt. Brauche eigentlich nur für einen Test eine funktionierende serielle Kommunikation kann auch in C# sein.
Flo schrieb: > Brauche > eigentlich nur für einen Test eine funktionierende serielle > Kommunikation Gegenstelle ist ein Arduino? dann hätte ich als etwas schrägen Vorschlag: "processing" am PC. https://processing.org/ Diese API kommt dir dann evtl. vertraut vor: https://processing.org/reference/libraries/serial/index.html das ganze Graphik-Künstler-Video-Zeug was mitkommt muss man ja nicht nutzen.
Erstmal Danke Ernst, meine Gegenstelle ist ein spezieller Chip der mit at Kommandos gesteuert wird.
Um das also abzukürzen: du suchst also einen „AT Parser“. Wenn Du nicht in der Lage bist, einen nach Deinen Vorstellungen zu entwickeln, nimm doch als Vorbild eins der ca. 42 Fantasillionen Beispiele: google „at parser“.
Was ich suche/brauche ist ein gescheite C Applikation für eine serielle Kommunikation.
Na dann! Frau zum Shoppen/Freundin schicken, Kanne Kaffee kochen und frisch ans Werk! Morgen mittag hast Du es halbwegs am laufen…🥳 Wenn Du dann noch konkrete Fragen hast…
So ich bins nochmal. Hab nun mal was eigenes aufgesetzt. Jetzt ist es aber nach wie vor so, dass wenn ich zyklisch jede 100ms UART Nachrichten (pro Frame 256 bytes) versende die von der Gegenstelle gesendeten Nachrichten nicht sofort empfangen kann.
1 | CSerial::CSerial(char* com_port, DWORD COM_BAUD_RATE) |
2 | {
|
3 | connected_ = false; |
4 | |
5 | io_handler_ = CreateFileA(static_cast<LPCSTR>(com_port), |
6 | GENERIC_READ | GENERIC_WRITE, |
7 | 0, |
8 | NULL, |
9 | OPEN_EXISTING, |
10 | FILE_ATTRIBUTE_NORMAL, |
11 | NULL); |
12 | |
13 | if (io_handler_ == INVALID_HANDLE_VALUE) |
14 | {
|
15 | if (GetLastError() == ERROR_FILE_NOT_FOUND) |
16 | printf("Warning: Handle was not attached. Reason: %s not available\n", com_port); |
17 | }
|
18 | else { |
19 | |
20 | DCB dcbSerialParams = { 0 }; |
21 | |
22 | if (!GetCommState(io_handler_, &dcbSerialParams)) |
23 | {
|
24 | printf("Warning: Failed to get current serial params"); |
25 | }
|
26 | |
27 | else
|
28 | {
|
29 | dcbSerialParams.BaudRate = COM_BAUD_RATE; |
30 | dcbSerialParams.ByteSize = 8; |
31 | dcbSerialParams.StopBits = ONESTOPBIT; |
32 | dcbSerialParams.Parity = NOPARITY; |
33 | dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE; |
34 | |
35 | if (!SetCommState(io_handler_, &dcbSerialParams)) |
36 | printf("Warning: could not set serial port params\n"); |
37 | else
|
38 | {
|
39 | connected_ = true; |
40 | PurgeComm(io_handler_, PURGE_RXCLEAR | PURGE_TXCLEAR); |
41 | }
|
42 | }
|
43 | }
|
44 | }
|
1 | string CSerial::ReadSerialPort(int reply_wait_time) |
2 | {
|
3 | |
4 | DWORD bytes_read; |
5 | char inc_msg[1]; |
6 | string complete_inc_msg; |
7 | bool began = false; |
8 | |
9 | unsigned long start_time = time(nullptr); |
10 | |
11 | ClearCommError(io_handler_, &errors_, &status_); |
12 | |
13 | while ((time(nullptr) - start_time) < reply_wait_time) |
14 | {
|
15 | if (status_.cbInQue > 0) |
16 | {
|
17 | if (ReadFile(io_handler_, inc_msg, 1, &bytes_read, NULL)) |
18 | {
|
19 | began = true; |
20 | |
21 | if (inc_msg[0] == '\n') |
22 | return complete_inc_msg; |
23 | |
24 | if (inc_msg[0] != '\n') |
25 | complete_inc_msg.append(inc_msg, 1); |
26 | }
|
27 | else
|
28 | return "Warning: Failed to receive data.\n"; |
29 | }
|
30 | }
|
31 | return complete_inc_msg; |
32 | }
|
1 | bool CSerial::WriteSerialPort(char* data_sent) |
2 | {
|
3 | DWORD bytes_sent; |
4 | |
5 | unsigned int data_sent_length = strlen(data_sent); |
6 | |
7 | if (!WriteFile(io_handler_, (void*)data_sent, data_sent_length, &bytes_sent, NULL)) |
8 | {
|
9 | ClearCommError(io_handler_, &errors_, &status_); |
10 | return false; |
11 | }
|
12 | else
|
13 | return true; |
14 | }
|
Bist du sicher, dass du das aufgesetzt hast? Einerseits die teilweise ordentlichen, nicht trivialen Programmteile, die du postest. Andererseits das Unverständnis von Basics und mangelnde Kenntnis von einfachsten Stringroutinen. Deine ersten Tests waren in C. Jetzt kommt hier C++? Für mich sieht das mehr so aus, als dass du nur eine neue Quelle für Copy&Paste erschlossen hast.
Flo schrieb: > Gibt es dazu noch Möglichkeiten dies zu optimieren? Code verstehen, deinen tatsächlichen Flaschenhals finden, dann reparieren. So kann dir das keiner sagen. Selbst mit 'ner UART von 1 MBaud ist ein heutiger PC locker in der Lage, da einige strstr()-Aufrufe auf das Resultat anzuwenden, ohne dass irgendwas klemmt. Wenn da bei dir was nicht funktioniert, liegt das also ganz sicher nicht an strstr() (oder ähnlichen Standardfunktionen), sondern an irgendwas ganz anderem. Dafür müsstest du aber erstmal wissen, was du da überhaupt tust. Danach müsstest du analysieren, warum es bei dir zu langsam wird. Erst dann brauchst du drüber nachzudenken, wie man es "optimiert".
Flo schrieb: > COM_BAUD_RATE Es wird für immer ein Rätsel bleiben. Werden Wetten für den Wert angenommen?
Dirk B. schrieb: > Werden Wetten für den Wert angenommen? Irgendwas möglichst hohes. Weil das laggt sonst.
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.