Pages: [1] 2 3   Go Down
Author Topic: What is the Arduino Uno Serial buffer size?  (Read 18082 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am reading information from my motorcycle's ECM via serial connection on the Arduino Uno R3. I am supposed to read a 107 byte series, but I am only getting the first 62 bytes. The header in the series says there are supposed to be 100 bytes of info (plus 7 for the header) so I know the ECM is trying to send all of it.

Is the buffer size only 62 bytes? How can I get around this so I can read all 107 bytes and save them into an array?
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49330
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is the buffer size only 62 bytes?
The buffer size is 64 bytes.

Quote
How can I get around this so I can read all 107 bytes and save them into an array?
Generally, the thing to do is read as fast as it arrives. Without seeing your code, we have no idea why you aren't doing this. There is nothing to get around, except to reading before the data is lost.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17294
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What is the baud-rate of the serial data you are receiving? That will have a bearing of how fast you must read the data from the serial buffer into your own user defined buffer of the size required to hold the message. But bottom line you should not be reliant on the size of the serial buffer, but rather set a baud-rate such that you can transfer characters fast enough into your own buffer such that no serial buffer over-runs occurs.

Lefty

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The baud rate that the ECM is 9600 sending and receiving, so I am using 9600 for the Arduino as well. Hmmm, maybe the delay I am using is causing part of the problem, but that doesn't help if the buffer is only 64 bytes. I wonder why I am receiving 62 bytes instead...

Here is my code I am using:
Code:
/* 
 This program is used for an Arduino to request and retrieve
 data from an 07 Buell XB9SX Lightning ECM DDFI-2,
 EEPROM Version: BUEIB
 
 Currently the Arduino successfully sends a request code and
 receives only 62 bytes of the run-time response, and displays
 on the LCD screen and via serial monitor.
 
 Created by Michael Blaylock
 */

// include the library code:
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>

//new serial pins for ECM, 0 and 1 caused interferance from PC
#define rxPin 2
#define txPin 3

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
byte inArray[9]; //request code for real-time data
byte outArray[107]; //real-time data series from ECM
byte long Value;
int First = 0;

void setup(){
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // initialize the serial communications:
  // define pin modes for tx, rx:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  // baud rate for the ECM is 9600
  mySerial.begin(9600);
  Serial.begin(9600);
  inArray[0]=0x01; //SOH
  inArray[1]=0x00; //Emittend
  inArray[2]=0x42; //Recipient
  inArray[3]=0x02; //Data Size
  inArray[4]=0xFF; //EOH
  inArray[5]=0x02; //SOT
  inArray[6]=0x43; //Data 1 //0x56 = Get version, 0x43 = Get runttime data
  inArray[7]=0x03; //EOT
  inArray[8]=0xFD; //Checksum
  //Stream request data series to ECM as HEX
}

//print only 1 response to serial monitor to avoid flooding
void display() {
  if(First == 0) {
    for (int i=0; i<107; i++){
      Serial.println(outArray[i],HEX);
    }
    First = 1;
  }
}

void loop() {
  lcd.setCursor(0,0);
  for (int i = 0; i<9; i+=1){
    mySerial.write(inArray[i]);
    lcd.print(inArray[i],HEX); //print sent HEX code
  }
  // when characters arrive over the serial port...
  if (mySerial.available()) {
    // wait a bit for the entire message to arrive
    delay(100);
    lcd.setCursor(0, 1);
    // read all the available characters
    while (mySerial.available() > 0) {
      // listen for new serial coming in:
      for (int i=0; i<107; i++){
        outArray[i] = mySerial.read();
      }
      //save specific bytes as useful variables
      //concatenate 2 byte RPM data
      unsigned Value = outArray[31] << 8 | outArray[30];
      //byte Value = outArray[90];
      lcd.setCursor(0,1);
      lcd.print("temp: ");
      lcd.print((Value*0.18-40)/2);
      //lcd.print(" ");
      //lcd.print(outArray[28],HEX);
      //lcd.print(outArray[29],HEX);
      display(); 
    }
  }
}
« Last Edit: March 12, 2012, 02:13:05 pm by Blaylock1988 » Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
        outArray = mySerial.read();

outArray is not an element of an array.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Should I have:

Code:
outArray[i] = mySerial.read();
?

I found the formatting I have been using from another thread on the forums.
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
      for (int i=0; i<107; i++){
        outArray = mySerial.read();
      }

Given the location of that line, it would make sense.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49330
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Hmmm, maybe the delay I am using is causing part of the problem
It doesn't help. But look at this:
Code:
    while (mySerial.available() > 0) {
      // listen for new serial coming in:
      for (int i=0; i<107; i++){
        outArray = mySerial.read();
      }
Suppose 8 bytes have arrived. The while condition will be true, so you read all 107 of the 8 bytes. Does that really seem like a good idea?

Code:
#define rxPin 2
#define txPin 3
Good.

Code:
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);
Give complete control of the pins to SoftwareSerial.

Code:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
Then, muck with them, anyway. Not a good idea.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26289
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's a side effect of not using CODE TAGS when posting code.
Note the italics that appeared.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I missed that. The whole thing is a quote, so it's all in italics.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
      for (int i=0; i<107; i++){
        outArray = mySerial.read();
      }

Given the location of that line, it would make sense.

I fixed it as code in my post.

I was using the same code and was sending the wrong checksum so the ECM was sending me a 10 byte error. It was reading that fine but the rest of the outArray was empty with 0xFF.

So I guess what is happening is it is writing mySerial.read() to outArray 107 times? If I tell it to write mySerial.read() to outArray i location, wouldn't it be trying to write the entire buffer to that one location, or will it write the very first byte in the buffer to the i location in the outArray?
« Last Edit: March 12, 2012, 02:14:00 pm by Blaylock1988 » Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49330
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
wouldn't it be trying to write the entire buffer to that one location
Time to go read the documentation on the Serial.read() function. It does not read "the entire buffer" at once. It reads one byte at a time. So, it would only write one byte to outArra[ i ].

Of course, that isn't you real problem.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok so doing outArray[ i ] = mySerial.read() should fix my problem?

It sounds like I was unintentionally writing the entire buffer at once, when I should be writing the first incoming byte of the buffer to outArray[ i ].

The ECM is supposed to send out 107 bytes every time unless it is sending out an error message.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I changed it to outArray[ i ] = mySerial.read() and the problem still persists.

I tested it and it says that the buffer is overflowing.

It looks like when you use the mySerial.read() function, it doesn't clear out the previous values that were read, so the buffer fills up to 64 and no more values come in.

How can I clear each byte that has already been read from the buffer so that It does not overflow?

EDIT: So I rearragned the location of the mySerial.read() and some other things and I was able to read 67 of the 107 bytes. Am I just not reading fast enough? I am using the correct baud for my ECM. I'll post the revised code, I just need to clean it up so you guys can make sense of it.
« Last Edit: March 15, 2012, 10:11:22 pm by Blaylock1988 » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18778
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Is the buffer size only 62 bytes? How can I get around this so I can read all 107 bytes and save them into an array?

A suitable method is described here:

http://www.gammon.com.au/serial

Code:
// wait a bit for the entire message to arrive
    delay(100);

You don't need any delays if you follow my method.
Logged


Pages: [1] 2 3   Go Up
Jump to: