Pages: [1]   Go Down
Author Topic: SerialEvent() & Serial.read() mehr als 64Bytes  (Read 793 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

gibt es eine Möglichkeit über die Console mehr 64Bytes einzulesen, wenn man serialEvent() benutzt?


Danke
Peter
Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 266
Posts: 21656
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 266
Posts: 21656
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nach meiner Erklärung verstehe ich Deine Frage nicht.
Grüße Uwe
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:


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);
    }
  }
}
Logged

"The old Europe"
Offline Offline
Edison Member
*
Karma: 1
Posts: 2005
Bootloaders suck!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

* daten im seriellen buffer ? --> in den grossen hineinkopieren (array) und index hochzaehlen
* bearbeitungsbuffer voll ? --> auswerten

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:

Code:
int main(void)
{
        init();
#if defined(USBCON)
        USBDevice.attach();
#endif
        setup();
        for (;;) {
                loop();
                if (serialEventRun) serialEventRun();
        }
        return 0;
}

und in 'HardwareSerial.cpp'

Code:
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:

Code:
void loop(void) {
  // irgendwas start
  //
  // irgendwas ende

  if(Serial.available()) {
    // mach irgendwas anderes
  }
}


« Last Edit: May 22, 2012, 04:58:45 pm by madworm » Logged

• Upload doesn't work? Do a loop-back test.
• There's absolutely NO excuse for not having an ISP!
• Your AVR needs a brain surgery? Use the online FUSE calculator.
My projects: RGB LED matrix, RGB LED ring, various ATtiny gadgets...
• Microsoft is not the answer. It is the question, and the answer is NO!

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 266
Posts: 21656
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

madworm, könnte das Problem daher kommen, daß er mit Strings arbeitet und nicht mit char und einem Array?
Grüße Uwe
Logged

"The old Europe"
Offline Offline
Edison Member
*
Karma: 1
Posts: 2005
Bootloaders suck!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Auch moeglich ;-)

Wenn er

Code:
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.
« Last Edit: May 22, 2012, 05:53:49 pm by madworm » Logged

• Upload doesn't work? Do a loop-back test.
• There's absolutely NO excuse for not having an ISP!
• Your AVR needs a brain surgery? Use the online FUSE calculator.
My projects: RGB LED matrix, RGB LED ring, various ATtiny gadgets...
• Microsoft is not the answer. It is the question, and the answer is NO!

Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Vielen Dank, dass ihr für mich eure Nacht zum Tag gemacht habt smiley
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.


Logged

Pages: [1]   Go Up
Jump to: