Wie oben schon geschrieben der Eingangspuffer ist mir zu klein mit 64 Byte, die Nachricht ist 107 Byte groß. Gibt es dafür Abhilfe ? Leider finde ich dazu keine Blogs Einträge ect. Gruß
Vermutlich reicht es, die Hilfe oder das Manual zu lesen, wie man die Größe einstellt. Es würde mich wundern, wenn die Arduion-Lib völlig ohne Doku daherkommt.
D. Chung schrieb: > Wie oben schon geschrieben der Eingangspuffer ist mir zu klein mit 64 > Byte, die Nachricht ist 107 Byte groß. Warum änderst du nicht SERIAL_BUFFER_SIZE?
D. Chung schrieb: > Leider finde ich dazu keine Blogs Einträge ect. Alleine auf's Klo gehen kannst du aber schon, oder musst du dafür auch vorher erst einen Blog lesen? D. Chung schrieb: > Gibt es dafür Abhilfe ? Ja: C-Buch lesen, verstehen und das Datenblatt zum Controller suchen, lesen, verstehen und verstehen wie der UART funktioniert und dann ganz easy den Controller so programmieren wie du es brauchst. Alternativ: Arduino-Dokumentation lesen? (http://arduino.cc/en/Reference/Serial) Das Puffer-Array größer machen? Oder aber, einfach hinnehmen, weiterhin das selbstständige denken verweigern und dumm und vermeindlich glücklich sterben. Troll dich!
Die Daten in kleineren Stücken lesen und/oder schreiben.
Das ist ja geil. Jetzt brauchen die Arduino-User schon ein Video damit sie verstehen wie sie ein Define ändern können um den Puffer größer zu machen. Dokumentation lesen is wohl "zu 80's". Aber dennoch ein Tipp an dich: Die Lösung für dein Problem ist NICHT, den Buffer größer zu machen, sondern anständigen Code zu schreiben. Du kannst die Daten auch in kleineren Blöcken empfangen. Es muss nicht alles in den Puffern der Library Platz haben. Man versucht allgemein die Libraries so wenig wie möglich zu verändern, sofern es geht überhaupt nicht! Denn wenn du deinen Code weitergibst müsstest du auch die Lib mitgeben. Was passiert in ein paar Monaten wenn es ein Update gibt? Dann musst du diese Änderungen wieder ausführen.
meckerziege schrieb: > Das ist ja geil. Jetzt brauchen die Arduino-User schon ein Video damit > sie verstehen wie sie ein Define ändern können um den Puffer größer zu > machen. > Dokumentation lesen is wohl "zu 80's". Bald gibt es Videos, die erklären, wie Videos geschaut werden.
Hallo Zusammen, hier ein kleine Umfrage, bitte zutreffendes ankreuzen: [ ] 80% der geposteten Anworten eines Threads im Mikrocontrollernetz helfen dem Fragenden freundlich und zielgerichtet weiter [ ] nur 1% der Antworten stammen von besserwisserischen Nörglern [ ] es gibt immer mal wieder eine Perle unter den Antworten, die dem Fragenden weiterhilft. [ ] Ich würde weiterhin im Mikrocontrollernetz posten
Wahnsinn ^^, hätte ich eine Lösung dafür hätte ich sicher nichts hier rein geschrieben . Beim MAC OS kann ich die lib nicht bearbeiten die schon Standard dabei sind. Zumindestens finde ich bisher keinen Speichertort dafür ;-). Zweite Möglichkeit wäre ein Ringpuffer, nur ich bekomme es nicht hin ;-)... Beispiele dazu sind auch raarr und wenn für mich unverständlich.
D. Chung schrieb: > Zumindestens finde ich bisher keinen Speichertort dafür ;-). Hat das MAC OS denn keine Suchfunktion? In der Regel kriegt man passendere Antworten, wenn man gleich angibt, daß man kein Windows benutzt. Die Leute können ja nicht in Deinen Kopf schauen.
D. Chung schrieb: > Beim MAC OS kann ich die lib nicht bearbeiten die schon Standard dabei > sind. Das dürftest Du frei erfunden haben, eine solche Bearbeitungsverhinderung für die Arduino Core-Library gibt es sicher auch beim MAC OS nicht. > Zumindestens finde ich bisher keinen Speichertort dafür ;-). Damit dürftest Du dem Problem schon näher kommen. Bei Deinem geringen Kenntnisstand ist es allerdings fraglich, ob Dein Problem wirklich in den Arduino-Core Libraries liegt oder nicht eher Deinen mangelhaften Programmierkenntnissen zuzuschreiben ist. Und ob es wirklich angebracht ist, mit so geringen Kenntnissen in den Core-Libraries herumzufuhrwerken. > Zweite Möglichkeit wäre ein Ringpuffer, nur ich bekomme es nicht hin Ein einfaches Array mit Zählindex reicht nicht? Wie wird denn Deine Nachricht gesendet, kann man irgendwie feststellen, wo sie zuende ist? Ist das letzte Zeichen der 107 Byte irgendwie ein spezielles Stopzeichen und kennzeichnet das Ende der Nachricht? Oder ist das erste Zeichen der Nachricht ein spezielles Startzeichen? Oder gibt es immer eine kleine Sendepause zwischen zwei Nachrichten?
Ja du kannst mir ja gerne mitteilen wo ich diese finden sollte, es gibt eine Ordner dazu aber darin befinden sich nur die lib die ich selbst hinzugefügt habe. Ich hab auch nie behauptet das meine Programmierkenntnisse sehr gut wären , dann würde ich mich wohl hier nicht austoben.... > Wie wird denn Deine Nachricht gesendet, kann man irgendwie feststellen, > wo sie zuende ist? Ist das letzte Zeichen der 107 Byte irgendwie ein > spezielles Stopzeichen und kennzeichnet das Ende der Nachricht? Oder ist > das erste Zeichen der Nachricht ein spezielles Startzeichen? Oder gibt > es immer eine kleine Sendepause zwischen zwei Nachrichten? --> http://www.ecmspy.com/cgi-bin/runtime.cgi Was ich nur darüber weiß ist das was man hier findet . Ich stelle eine Anfrage und gleich im Anschluss antwortet mir das ECM mit 107 Byte . Die letzten zwei Byte sind einmal für End of text und Checksum. Ich wüsste nicht das es eine Sendepause gäbe. Plausibel würde mir ein Ringpuffer erscheinen aber ich weiß nicht wie ich das am besten angehe . Ein kleiner Ausschnitt ->
1 | ByteNumber = 0; |
2 | inArray[0] = 0x01; //SOH |
3 | inArray[1] = 0x00; //Emittend |
4 | inArray[2] = 0x42; //Recipient |
5 | inArray[3] = 0x02; //Data Size |
6 | inArray[4] = 0xFF; //EOH |
7 | inArray[5] = 0x02; //SOT |
8 | inArray[6] = 0x43; //Data 1 //0x56 = Get version, 0x43 = Get runttime data |
9 | inArray[7] = 0x03; //EOT |
10 | inArray[8] = 0xFD; //Checksum |
11 | requestData(); |
12 | "
|
13 | "
|
14 | //Send data request to ECM
|
15 | void requestData(void) { |
16 | WaitTimer = millis(); |
17 | Serial.println("Request to ECM"); |
18 | |
19 | for (int i = 0; i < 9; i += 1){ |
20 | mySerial.write(inArray[i]); |
21 | }
|
1 | void loop() { |
2 | |
3 | if (mySerial.available()) { |
4 | //fill the data array
|
5 | outArray[ByteNumber ++] = mySerial.read(); |
6 | |
7 | Serial.print("ByteNumber"); |
8 | Serial.print(ByteNumber); |
9 | Serial.print(" ,"); |
10 | Serial.println(outArray[ByteNumber]); |
11 | |
12 | |
13 | |
14 | }
|
15 | |
16 | else { |
17 | ByteNumber = 0; |
18 | if ((millis() - WaitTimer) > 2000) { |
19 | |
20 | mySerial.flush(); |
21 | ByteNumber = 0; |
22 | Serial.println("Reset"); |
23 | // Serial.println(millis() - WaitTimer);
|
24 | mySerial.flush(); |
25 | WaitTimer = millis(); |
26 | requestData(); |
27 | delay(2000); |
28 | |
29 | }
|
30 | }
|
31 | |
32 | |
33 | |
34 | if (ByteNumber > 107) { // process it |
35 | ByteNumber = 0; // ready for next time |
36 | |
37 | callTPS(); |
38 | callATemp(); |
39 | callSpeed(); |
40 | callRPM(); |
41 | callPulsewidth(); |
42 | callLogger(); |
43 | WaitTimer = millis(); |
44 | requestData(); //restart data |
45 | delay(1000); |
46 | |
47 | }
|
48 | }
|
:
Bearbeitet durch User
D. Chung schrieb: > Was ich nur darüber weiß ist das was man hier findet . > > Ich stelle eine Anfrage und gleich im Anschluss antwortet mir das ECM > mit 107 Byte . Die letzten zwei Byte sind einmal für End of text und > Checksum. OK, mal abgesehen davon, dass man "gleich" nochmal genauer definieren müßte, ob damit 100 Mikrosekunden, 5 Millisekunden oder 1 Sekunde gemeint ist, reicht zum Empfangen natürlich der Standardmäßige serielle Eingangspuffer voll aus. > Ich wüsste nicht das es eine Sendepause gäbe. Aber in dem Fall, dass Du eine "Anforderung" sendest, weißt Du, wann die Sendung eintrifft, nämlich nach dem Absenden der Anforderung. Das Vorgehen zum Empfangen ist also: - Du definierst einen Byte-Puffer von 107 Bytes Größe - Du definierst einen Byte-Zähler Erste mögliche Programmlogik: Sobald Du Deine Anforderung gesendet hast, setzt Du den Byte Zähler auf 0 und wartest auf die 107 eintreffenden Zeichen. Zweite mögliche Programmlogik: Sobald das Startzeichen SOH empfangen wird, setzt Du den Byte Zähler auf 0 und wartest auf die 107 eintreffenden Zeichen. Such Dir was aus! > Plausibel würde mir ein Ringpuffer erscheinen aber ich weiß nicht wie > ich das am besten angehe . Du hast von keinem Ringpuffer irgendeine Ahnung. Und Du brauchst dafür auch keinen Ringpuffer, nur ein einfaches Array.
Kannst du das zur Nr eins nochmals genauer erläutern ? Du meinst ich sollte eine Klasse definieren ? Wie gesagt ich bin hier eher ein Anfänger und beiß mich gerne durch aber, dafür braucht es meist konkrete Ansätze.
D. Chung schrieb: > Kannst du das zur Nr eins nochmals genauer erläutern ? > Du meinst ich sollte eine Klasse definieren ? Nein. Ein ganz stink normales Array, das gross genug ist. Und dazu einen Zähler, der einfach nur mitzählt, wieviele Bytes schon in diesem Buffer sind und wo daher das nächste zu empfangene Zeichen abgelegt werden muss. Mit einem Array wirst du ja doch wenigstens umgehen können! Wenn nicht, dann lerne es
1 | unsigned char Data[200]; // Platz genug |
2 | unsigned char nextByte; |
3 | |
4 | void loop() |
5 | {
|
6 | if( Serial.available() ) { |
7 | data[nextByte] = Serial.read(); |
8 | nextByte++; |
9 | }
|
10 | |
11 | .... wenn genug Bytes beisammen sind, dann werte sie aus |
12 | .... und/oder setze nextByte wieder auf 0, damit die nächsten Bytes |
13 | .... wieder vom Begin des Arrays an abgelegt werden |
14 | }
|
Wo genau ist da jetzt das Problem mit dem 64 Byte Buffer der Serial Klasse? > Wie gesagt ich bin hier eher ein Anfänger und beiß mich gerne durch > aber, dafür braucht es meist konkrete Ansätze. Dann wird es Zeit, dass du ein paar absolute Basic Standardverfahren dir zur Gemüte führst. Bytes der Reihe nach in ein Array schreiben ist wahrlich keine Hexerei.
Kaj schrieb: > D. Chung schrieb: >> Leider finde ich dazu keine Blogs Einträge ect. > Alleine auf's Klo gehen kannst du aber schon, oder musst du dafür auch > vorher erst einen Blog lesen? > > Oder aber, einfach hinnehmen, weiterhin das selbstständige denken > verweigern und dumm und vermeindlich glücklich sterben. > > Troll dich! Beirag finde ich nicht gut.
und wenn du mutwillig ...
1 | ...
|
2 | delay(1000); |
3 | ...
|
dein Programm ausbremst, darfst du dich nicht wundern, wenn dir die Puffer hinten und vorne zu klein werden. Ich kann ja verstehen, dass jeder mal angefangen hat. Aber wer seinem µC absichtlich Prügel zwischen die Beinchen wirft und die Handbremse anzieht, sollte sich erst mal überlegen, was er da eigentlich tut. Wie die Sache mit der Funktion millis() funktioniert und wie man sich damit Aktionen so kapselt, dass sie in regelmässigen Zeitintervallen ausgeführt werden, hast du nicht wirklich verstanden bzw. mal darüber nachgedacht. Code einfach abschreiben ist dann doch ganz einfach zu wenig. Da, in diesen delays liegt dein Problem und nicht in zu kleinen Buffern. Denn pikanterweise scheint der Rest des Codes bereits so geschrieben zu sein, dass es genau das von dir geschriebene Problem nicht gibt. D.h. der, von dem du abgeschrieben hast, hat das schon alles bedacht. Mit dem ergänzen der delays und noch einer weiteren Änderungen hast du allerdings alles wieder zerstört.
:
Bearbeitet durch User
D. Chung schrieb: > Kannst du das zur Nr eins nochmals genauer erläutern ? > Du meinst ich sollte eine Klasse definieren ? > Wie gesagt ich bin hier eher ein Anfänger und beiß mich gerne durch > aber, dafür braucht es meist konkrete Ansätze. Anbei ein sehr konkreter Ansatz. Mit einer receiveData() Funktion, die verschiedene Statuscodes zurückliefert und sogar schon eine rudimentäre Fehlerüberprüfung enthält.
1 | #include <SoftwareSerial.h> |
2 | SoftwareSerial mySerial(8, 9); // RX, TX |
3 | // Besser: SoftwareSerial Library durch AltSoftSerial ersetzen!
|
4 | |
5 | #define REQUESTINTERVALL 5000
|
6 | #define MESSAGETIMEOUT 3000
|
7 | #define SOH 0x01
|
8 | #define EOT 0x03
|
9 | |
10 | #define MSGBYTES 107
|
11 | byte inArray[MSGBYTES]; // Platz zum Speichern von 107 Bytes |
12 | byte ByteNumber = 0; |
13 | unsigned long lastRequestTime; |
14 | boolean requestPending=false; |
15 | |
16 | void request() |
17 | {
|
18 | // hier die Anforderung senden
|
19 | inArray[0] = 0x01; //SOH |
20 | inArray[1] = 0x00; //Emittend |
21 | inArray[2] = 0x42; //Recipient |
22 | inArray[3] = 0x02; //Data Size |
23 | inArray[4] = 0xFF; //EOH |
24 | inArray[5] = 0x02; //SOT |
25 | inArray[6] = 0x43; //Data 1 //0x56 = Get version, 0x43 = Get runttime data |
26 | inArray[7] = 0x03; //EOT |
27 | inArray[8] = 0xFD; //Checksum |
28 | for (int i = 0; i < 9; i += 1) mySerial.write(inArray[i]); |
29 | lastRequestTime=millis(); // Zeit der letzten Datenanforderung merken |
30 | Serial.println("Request pending..."); |
31 | ByteNumber=0; // Zähler zurücksetzen |
32 | requestPending=true; |
33 | }
|
34 | |
35 | // Einige Ergebniscodes für den Datenempfang
|
36 | enum {PENDING, NOTPENDING, TIMEOUT, DATAERROR, OK}; |
37 | |
38 | byte receiveData() |
39 | {
|
40 | if (!requestPending) // kein Request anhängig |
41 | {
|
42 | while (mySerial.available()) mySerial.read(); // Eingangspuffer leeren |
43 | return NOTPENDING; // Kein Request anhängig |
44 | }
|
45 | if (millis()-lastRequestTime>MESSAGETIMEOUT) // Timeout, keine vollständige Antwort |
46 | {
|
47 | requestPending=false; |
48 | return TIMEOUT; |
49 | }
|
50 | if (mySerial.available()==0) return PENDING; // Es wird auf weitere Zeichen gewartet |
51 | char c=mySerial.read(); |
52 | inArray[ByteNumber]=c; |
53 | ByteNumber++; |
54 | if (ByteNumber<MSGBYTES) return PENDING; // Es wird auf weitere Zeichen gewartet |
55 | // Der folgende Code wird ausgeführt, wenn alle Zeichen empfangen wurden
|
56 | requestPending=false; |
57 | ByteNumber=0; |
58 | // Fehlerüberorprüfung
|
59 | if (inArray[0]!=SOH || inArray[105]!=EOT) return DATAERROR; |
60 | // Wenn keine Fehler, dann Daten OK
|
61 | return OK; |
62 | }
|
63 | |
64 | void printData() |
65 | {
|
66 | // Empfangene Codes numerisch dezimal ausgeben
|
67 | for (int i=0;i<MSGBYTES;i++) |
68 | {
|
69 | Serial.print(inArray[i]); |
70 | Serial.print('\t'); |
71 | if ((i+1)%10==0) Serial.println(); |
72 | }
|
73 | Serial.println(); |
74 | }
|
75 | |
76 | void setup() { |
77 | Serial.begin(9600); |
78 | Serial.println("Good night and good luck!"); |
79 | }
|
80 | |
81 | void loop() { |
82 | unsigned long now=millis(); |
83 | if (now-lastRequestTime>=REQUESTINTERVALL) request(); |
84 | switch (receiveData()) |
85 | {
|
86 | case TIMEOUT: Serial.println("REQUEST TIMEOUT");break; |
87 | case DATAERROR: Serial.println("DATA ERROR");break; |
88 | case OK: printData();break; |
89 | }
|
90 | }
|
Wie hier im Thread schon erwähnt: Für Programme, die schnell reagieren sollen, sind Blockierungen der Programmausführung mit der "delay" Funktion absolut tabu. Wenn Du mit Arduino irgendwelche Aktionen zu timen hast, wie zum Beispiel Anforderungsintervalle oder Timeoutintervalle, dann immer nur über den Stand des millis() Timers durch Zeitpunktvergleich, aber nie durch "blockierendes Warten" ("busy waiting"). Schau's Dir an! Falls Dein Controller nicht genügend HardwareSerial-Schnittstellen hat, sollte für die Softwaremulation besser nicht die zur Arduino-Software gehörende SoftwareSerial Library verwendet werden, sondern praktisch immer viel besser geeignete Drittanbieter-Library "AltSoftSerial".
Danke Dir für deine Antwort. Zu einem Abschnitt hätte ich eine Frage byte receiveData() ......... char c=mySerial.read(); inArray[ByteNumber]=c; ByteNumber++; .... Er liest jetzt zu jedem Durchlauf in das Array ein und erhöht ByteNumber um 1 und das auch wenn nichts im Puffer steht kann das richtig sein ? Oder liege ich falsch ? Gruß
Schau einfach auf die Zeile davor. Das beantwortet die Frage.
D. Chung schrieb: > Er liest jetzt zu jedem Durchlauf in das Array ein und erhöht ByteNumber > um 1 und das auch wenn nichts im Puffer steht kann das richtig sein ? Was denkst du, welchen Zweck das unmittelbar vorhergehende
1 | if (mySerial.available()==0) return PENDING; |
hat?
D. Chung schrieb: > Er liest jetzt zu jedem Durchlauf in das Array ein und erhöht ByteNumber > um 1 und das auch wenn nichts im Puffer steht kann das richtig sein ? > > Oder liege ich falsch ? Ja. Eine Funktion kann mit "return" vorzeitig verlassen werden und davon mache ich reichlich Gebrauch.
1 | if (mySerial.available()==0) return PENDING; // Es wird auf weitere Zeichen gewartet |
Wenn keine Zeichen im Eingangspuffer sind, wird die Funktion vorzeitig mit dem Returncode "PENDING" verlassen. Der Nachfolgende Code mit dem Auslesen des seriellen Eingangspuffers wird also nur dann ausgeführt, wenn sich mindestens ein Zeichen im Eingangspuffer befindet.
Da
1 | if (millis()-lastRequestTime>MESSAGETIMEOUT) // Timeout, keine vollständige Antwort |
2 | {
|
3 | requestPending=false; |
4 | return TIMEOUT; |
5 | }
|
sollte sicherheitshalber noch ein
1 | if (millis()-lastRequestTime>MESSAGETIMEOUT) // Timeout, keine vollständige Antwort |
2 | {
|
3 | requestPending=false; |
4 | ByteNumber=0; // <------- |
5 | return TIMEOUT; |
6 | }
|
rein.
:
Bearbeitet durch User
Zum Verständnis hier noch ein Link: http://www.amazon.de/Programmieren-C-Reference-Manual-deutscher-Sprache/dp/3446154973/
Ohje sry ja , sollte ich eigentlich wissen. Habs irgendwie übersehen oder nicht mehr daran gedacht .... Danke
D. Chung schrieb: > Beim MAC OS kann ich die lib nicht bearbeiten die schon Standard dabei > sind. Zumindestens finde ich bisher keinen Speichertort dafür ;-). - Arduino-Applikation im Finder-Fenster finden. - Kontextmenü aufrufen (d.h. bei gedrückter ctrl-Taste draufklicken. Entspricht dem "Rechtsklick" bei Windows). - Da sollte es den Punkt "Paketinhalt zeigen" geben. - Dann sieht man das "Innere" der Applikation, d.h. das ist eigentlich ein Verzeichnis mit allerlei Unterverzeichnissen. Contents -> Ressources -> Java, und dann wird's interessant. Aber auch ich bin der Meinung, daß der Empfangspuffer einer allgemeinen serial-Lib nicht der richtige Ort ist, komplette Protokoll-Messages zwischenzulagern.
Danke, nach 5 Jahren MAC mal wieder was neues gelernt. Ich teste den Code jetzt demnächst mal und berichte ob er funktioniert oder auch nicht. Ich hatte irgendwann mal C++ gelernt, mit MC hatten wir aber dann recht wenig bis gar nichts am Hut das kam nur durch meine Interesse... die einzige Schnittstelle die ich schon mal benutzt hab und das erfolgreich war der I2C Port. Man vergisst doch relativ schnell einiges, und verliert das Gefühl oder den Blick für die kleinen wichtigen Dinge.... Auch unter den blöden Antworten waren, waren mal nützliche infos beigemischt also einen Dank an die Rund ;-). Gruß
Beitrag #7090390 wurde von einem Moderator gelöscht.
Beitrag #7090396 wurde von einem Moderator gelöscht.
Cool, das Programmier-Buch gibt es immer noch bei Amazon. Das kann ich also immer noch empfehlen.
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.