Hi All,
Once again back for some help! I did post a topic the other week, where I am trying to communicate with an automotive ECU to pull real time data from it. I have the spec sheet and the ECU uses an RS232 lead and a baudrate of 230400. The ECU also works on request response, so you must send it a command, and then it will reply. If you send the wrong command, or use the wrong baudrate you will not get a response.
I have been using an Arduino UNO, and softwareSerial to communicate with the ECU, and I could send a request and get a response back. The problem I had is the response was incorrect in terms of format and content. I tried a few things, and the payload that appeared in the serial monitor was always incorrect. However I could use a USB/TTL adapter,connected to the MAX232 adapter im using, along with a PC comm port tool, and I could send the same command as Im sending in the Arduino code and get a valid response.
So the only thing left to try was a more capable board in terms of clock speed...
Based on this I bought an Arduino Due. and modified the code slightly, so instead of the MAX232 being used by softwareSerial its connected to Serial1 , pins 18 and 19.
Now, I see the transmission of the message, but I get no response. I tried the same test with the USB/TTL adapter and that still works fine. I also tried a loop back test by bridging pins 2 and 3 in the MAX232 and I can see the transmitted message come back and display in the serialMonitor.
So given that the :
- Request is correct,
- I'm using the same MAX232 adapter as with the UNO and with the direct to PC test which both get responses from the ECU.
- I'm using the same code just modified to set the MAX232 to the available Serial1 connections.
- The baudrate of 230400 when used on the UNO and the PC com port tool gets a response
The only thing I can think of, is that when Im setting the baudrate for Serial1 to 230400 on the Due somehow its not? No idea if thats possible! I have tried 250000 and 115200 just to check and again, I can see the response sent but the ECU does not respond.
One other thing that maybe relevant - I was unable to download the 'Arduino SAM (32-bits ARM Cortex M3)' I suspect as Im on a managed laptop. I was unable though to download 'Arduino SAM (32-bits ARM Cortex M3) with ARM64 support' which allowed me to select the board in the IDE. Im assuming this isnt causing this issue but should be noted.
Does anyone have any thoughts? The code Im using is below:
//#include <SoftwareSerial.h>
//#include <AltSoftSerial.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;
};
//##### Removed as using Due hardware pins 18, 19
//SoftwareSerial Serial2 (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: ");
Serial1.write(req, sizeof(req));
Serial.println();
}
void setup() {
/* Init debug serial for serial monitor*/
Serial1.begin(230400);
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) */
rx_idx = 0;
delay(2000);
Serial.println("Initialized software serial");
start_reporting_req();
}
/* 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 (Serial1.available()) {
rx_buf[rx_idx++] = Serial1.read();
}
for (int i = 0; i < (rx_idx); i++) {
#if (DEBUG == 1)
Serial.print(rx_buf[i], HEX);
Serial.print(" ");
#endif
}
Serial.println("\n");
}