I have a program on my PC that logs RAM vales and flashes my cars ECU. I want to rework the program to be able to put it on a RPi and do it wirelessly as having a laptop in the vehicle is not wise under the conditions im seeking to log. Ive recreated the cables hardware and am able to successfully spy on all hex communications to a point. Im using an Arduino Nano to write data received on RX at 10400 baud to an SD card. Everything runs successfully until I reach 64 characters. Up until 64 bytes one signal from one side, plus the response from the other side = 255. I realize Im running into the receive buffer limit of the Serial port. My code goes:
if (Serial.available()) {
d = Serial.read();
myFile = SD.open("info2.csv", FILE_WRITE);
myFile.print("RX,");
myFile.println(d, HEX);
myFile.close();
}
and just loops. My understanding is that when Serial.read() is called that the Serial Input Buffer should clear. What am I doing wrong?
Do you have to open and close the file every time you want to write something to it. It appears this operation is slow compared with the speed that the serial buffer is being filled.
Im dont. The data recorded matches with the expected data for the first 64 bytes. I think that part of this is I am recieving with no breaks. Because the system uses a bidirectional line, i pick up both sides on RX. In Column A, TX is the role I want my device to take on, RX is the information transmitted back. TX is blue, RX is red. Column B is the hex for the data being transferred. Column C is the Decimal value. Column D is either the ASCII character represented, or the Decimal value of the last two transmissions, with 255 representing a complement returned. The next few steps should be 4/5VT, or a hex sequence of 34, CB, 2F, D0, 35, CA, 56, A9, 54, AB.
1. At Bd = 10400 (assume frame length 10-bit), a character takes about 961 us to arrive. The charcaters are coming from Serial Port asynchronously and they enter one after another in the 64-byte wide Serial FIFO Buffer of NANO. 64 charcaters would take about 61504 us (61 ms).
2. You take out one character (d = Serial.read()) from BUFFer and then wait for (file open time, a + file write time, b + file write time, c + file close time, d) a+b+c+d us.
3. It is very much sure (as @6v6gt has pointed out in Post#1) that during this waiting time of Step-2, the BUFFer gets filled up and the charcaters that are arriving later are lost. As a result, you are just taking out 64 charcaters from the BUFFer.
4. One solution is to open the file in the setup() function and then close it once reception is complete. You perform only the myFile.println(d, HEX) instruction. The myFile.print("RX,") could be executed only once in the setup() function. You are certainly safe to receive and record all the characters.
Are you attempting to manually unpick can bus frames (or something similar) and where have you got the specification of the data format you are receiving ?
That file which appears in the spreadsheet was not generated from that sketch fragment or, if it was, you have heavily modified it.
So, if I understand you correctly now, the data you are collecting does not match your expectations and you are concluding that there is a problem with the serial buffer.
Can you attempt to get on complete data frame into an array, without the overhead of continuously writing to the SD card during data collection. At the end, write the array to the SD card. If that works, then start looking at optimising the process of writing to the SD card by, for example, writing larger blocks.
So in an attempt to reduce waste in the buffer and SD card ive gotten hopelessly lost and gone backwards. On my Arduino Nano I could get the first 64 bytes of the communication as expected, but once the seria buffer filled up it all went to gibberish. I reconfigured the circuitry to operate at 3.3v and have tried with both a Adalogger at 48 Mhz and a M4 Feather running at 120 Mhz. On both of these I start out receiving junk. Im not even trying to save to an SD card. Im printing to Serial at 115200. I wish I could just use a second serial on the Nano but there isnt one. Do i just need to order a mega?
This is for a Bosch ME7 ECU. It runs a KWP2000 or ISO 9141-2 protocol at 10400. I am just trying to get down the process of connection and reading general info, but would like to be able to log. After a 5 baud initialization bit of 0x01 it responds in 10400 with 0x55 and then following bits. My laptop is running through a FTDI232R breakout connected to an LM339 to handle the level shift from 3.3 to 12v. The TX output of the ftdi232r is also tied to the rx port of the nano, and duee to the nature of the bidirectional k line im getting both tx and rx signals. Im trying to check what Im doing vs a good reference and everything lined up on the Nano up to the filling of the buffer.
10400 baud is not particularly fast so software serial should be OK.
Try the Nano in original configuration but change the program to write into a say 256 byte array instead of interleaving reads of your ECU with writes to the serial monitor. When the array is full, then dump it to the serial monitor. If that gets you further then start optimizing it to respect the number of characters in a frame.
edit:
maybe something like this (untested)
#include <SoftwareSerial.h>
SoftwareSerial ecu(2, 3); // RX, TX - enter your pin numbers here
byte buf[256] = {0} ;
int bufIndex = 0 ;
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for Native USB only
}
Serial.println("ECU reader");
// set the data rate for the SoftwareSerial port
ecu.begin(10400);
}
void loop() // run over and over
{
if (ecu.available()) {
if ( bufIndex < 256 ) {
buf[ bufIndex ] = ecu.read() ;
bufIndex ++ ;
}
else {
// dump buffer
for ( int i = 0 ; i < 256 ; i++ ) {
Serial.print( buf[ i ] ) ;
Serial.print( ' ' ) ;
}
Serial.println() ;
while ( 1 ) ; // stop here after dumping 1 buffer
}
}
}