Hi All,
I have been on here a few times recently and its been really useful - so I'm back again with my latest issue!
I am trying to connect to a standalone automotive ECU in order to stream some live data from it in order to make a simple dash. The ECU connection is made via an RS232 cable, and I'm using an Arduino Uno with a MAX232 shield.
The ECU firstly needs an initial request in order to start streaming data, but will then need tester present ACks to be sent cyclically every 1-2s. The ECU should respond to the initial request without an ACKs though obviously.
The ECU connection is set to a baudrate of 230400 as specified by the manufacturers (earlier ECU FW was 112500, but I've checked and mine is definitely the later FW requiring 230400).
So presently, I can send the request to the ECU, and I see the TX led on the MAX232 flash. I then see about 2s worth of flashing on the RX led, showing I'm receiving data which is great. However the data im recieving when printed to the serial monitor is incorrect.
I am seeing every time I connect:
Received:
4E 85 31 A0 8 2 0 CD 80 20 2 10 0 1 21 0 8 1 44 40 83 80 1 2 40 4 4 1C C0 46 (only part of the message exemplified here)
But what I should see according to the ECU documentation and what I see when I use the manufacturers tuning sw is:
Received:
4D 45 47 01 0F 00 02 00 6C 00 03 00 04 11 00 02 12 00 00 0F 00 02 10 00 01 (only part of the message exemplified here)
The 0x4D and 0x45 are key - they appear in every request and response and are used as sync bytes. So at the minute Im not sure exactly what is happening. If anyone could offer any suggestions that would be much appreciated!
Ive attached the code below, there isnt anything there at the minute to deal with sorting the received data, I just want to get the correct initial response first, and deal with the frame processing after:
#include <SoftwareSerial.h>
#define DEBUG (1)
/**************************************************/
/* ECU Comms */
/**************************************************/
#define MIN_FRAME_LEN (10)
#define MAX_FRAME_LEN (768)
#define SYNC_CH_0 ('M')
#define SYNC_CH_1 ('E')
#define MSG_TYPE_REQ (0x0)
#define MSG_TYPE_RSP (0xF)
#define CLASS_ID_REPORT (0x0)
#define MSG_ID_REPORT (0x0)
#define MSG_ID_ACK (0x1)
#define MSG_ID_SET_STATE (0x2)
byte rx_buf[MAX_FRAME_LEN];
int rx_idx;
unsigned int rx_frame_len;
struct proto_frame {
byte sync_ch[2];
unsigned int len;
byte type;
byte class_id;
byte msg_id;
};
SoftwareSerial Comms_serial(8, 9); //232_TX,232_RX // Config to assign Digital io ports for the RS232 Shield
struct proto_frame rx_frame;
/* This is to create and send a request to the Me221, in order to get a response back. This will be sent once,
and for persistent comms need to introduce a cyclical Ack sent every 1s*/
void start_reporting_req() {
byte req [] = { 0x4D, 0x45, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x05, };
Serial.print("Sending: ");
Comms_serial.write(req, sizeof(req));
Serial.println();
}
void setup() {
/* Init debug serial for serial monitor*/
Serial.begin(9600);
Serial.println();
Serial.println("Serial debug line open");
/* Init ECU comms - check baudRate, its dependant on Me221 FW version:
115200 baud rate (for versions <2.1.2.)
230400 baud rate (for versions >=2.1.2) */
Comms_serial.begin(230400);
rx_idx = 0;
delay(2000);
Serial.println("Initialized software serial");
start_reporting_req();
}
/* This is to chop and decipher the frame reported back to us. Each frame needs to be segmented in order to dechiper the
data we rhave received from the ECU*/
/* Main loop that handles the buffered response byte by byte and checks for sync bytes (M E) to signify the start of the frame.
If successful message received, its sent for processing*/
void loop() {
while (Comms_serial.available() && rx_idx < MAX_FRAME_LEN) {
rx_buf[rx_idx++] = Comms_serial.read();
}
Serial.print("Received ");
Serial.println(rx_idx);
for (int i = 0; i < (rx_idx - 1); i++) {
#if (DEBUG == 1)
Serial.print( rx_buf[i], HEX);
Serial.print(" ");
#endif
}
Serial.println("\n");
}