Hallo,
gibt es eine Möglichkeit über die Console mehr 64Bytes einzulesen, wenn man serialEvent() benutzt?
Danke
Peter
Hallo,
gibt es eine Möglichkeit über die Console mehr 64Bytes einzulesen, wenn man serialEvent() benutzt?
Danke
Peter
So wie ich die Funktion SerialEvent() verstanden habe ist das eine Interruptfunktion die auf den eingang von daten auf der seriellen Schnittstelle reagiert. In dieser Funktion kannst Du dann die Daten aus der seriellen Schnittstelle auslesen. So ergibt sich nie das Problem des Bufferüberlaufs des Eingangsbuffers.
Grüße Uwe
Sorry, mein Fehler. Es ging um Serial.available() (im Zusammenhang mit SerialEvent)
das kann halt nur 64Byte lesen. Ich bräuchte es aber so, dass ich ca 300 Bytes einlesen kann.
Nach meiner Erklärung verstehe ich Deine Frage nicht.
Grüße Uwe
Das Problem ist das Serial.available() nur die ersten 64 Byte einer Konsoleneingabe lesen kann.
Für meine Zwecke sollten es aber deutlich mehr sein,..300 ca.
Ich habe folgenden Code:
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
void setup()
{
inputString.reserve(800);
Serial.begin(38400);
setupBlueToothConnection();
}
void loop()
{
if (stringComplete) {
Serial.println(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
}
void setupBlueToothConnection()
{
Serial.print("Setting up Bluetooth link");
Serial2.begin(38400);
delay(1000);
sendBlueToothCommand("\r\n+STWMOD=0\r\n");
sendBlueToothCommand("\r\n+STNA=modem\r\n");
sendBlueToothCommand("\r\n+STAUTO=0\r\n");
sendBlueToothCommand("\r\n+STOAUT=1\r\n");
sendBlueToothCommand("\r\n+STPIN=0000\r\n");
delay(2000); // This delay is required.
Serial2.print("\r\n+INQ=1\r\n");
delay(2000); // This delay is required.
Serial.print("Setup complete");
}
void sendBlueToothCommand(char command[])
{
char a;
Serial2.print(command);
}
void serialEvent2() {
while (Serial2.available()) {
// get the new byte:
char inChar = (char)Serial2.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == ';') {
stringComplete = true;
//Serial.println(inputString);
}
}
}
Wo ist das problem?
Der input buffer der seriellen ports sollte eigentlich nur ein kleiner zwischenspeicher sein, so dass kein datenverlust auftritt wenn die daten nicht sofort aus dem datenregister ausgelesen UND verarbeitet werden koennen. Das kopieren erledigt ein interrupt. Er ist nicht dafuer gedacht ein komplettes datenpacket fuer die bearbeitung vorzuhalten.
In der regel ist die verarbeitungsgeschwindigkeit wesentlich hoeher als der eingehende datenstrom. Daher ist es ueberhaupt kein problem daten aus dem seriellen buffer in einen 2ten groesseren buffer zu kopieren. Sobald der dann voll ist kann er bearbeitet werden.
Also:
Es ist auch sinnvol den begin und das ende eines datenpaketes durch geeignete marker erkennbar zu machen.
Noch etwas zu SerialEvent()...
Wenn man sich die 'main.cpp' anschaut, dann sieht das so aus:
int main(void)
{
init();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
und in 'HardwareSerial.cpp'
void serialEventRun(void)
{
#ifdef serialEvent_implemented
if (Serial.available()) serialEvent();
#endif
#ifdef serialEvent1_implemented
if (Serial1.available()) serialEvent1();
#endif
#ifdef serialEvent2_implemented
if (Serial2.available()) serialEvent2();
#endif
#ifdef serialEvent3_implemented
if (Serial3.available()) serialEvent3();
#endif
}
Durch etwas linker-trickserei ist das so hingebogen, dass es nur ausgefuehrt wird, wenn die funtion auch vom benutzer implementiert worden ist. Sonst wird das wegoptimiert. Interrupts spielen da nicht hinein. Es wird somit erzwungen, dass nach der normalen loop() auch 1x diese funktion aufgerufen wird. Persoenlich finde ich das konstrukt unnoetig.
Das ganze ist 100% aequivalent zu:
void loop(void) {
// irgendwas start
//
// irgendwas ende
if(Serial.available()) {
// mach irgendwas anderes
}
}
madworm, könnte das Problem daher kommen, daß er mit Strings arbeitet und nicht mit char und einem Array?
Grüße Uwe
Auch moeglich
Wenn er
Serial.println(inputString.reserve(800));
verwendet, dann sollte als rueckgabewert eine "1" kommen, wenn es erfolgreich war. Ist der angeforderte platz zu gross, dann einen "0". Mit einem ATmega168 klappt es mit "800" jedenfalls nicht mehr. Da ein 328er 2k RAM hat, sollte das noch tun.
Vielen Dank, dass ihr für mich eure Nacht zum Tag gemacht habt
Ich habe einen Mega 2560, so sollten die 800 Zeichen kein Problem sein. Ich werde heute abend oder am Wochenende noch ein bisschen probieren und das Ergebnis mitteilen.