I'm having trouble with LIN communication on an Arduino Mega 2560 using Serial.read(). Here are the details:
Issue: Unable to perform Serial.read() for LIN communication.
Hardware: Arduino Mega 2560 with Microchip MCP2003 LIN Transceiver.
Communication: Using Serial1 TX and RX for communication.
Objective: To check the status of an actuator, but unable to capture RX data with Serial.read(). Using the code below.
Serial1.end(); // To make a break field of LIN, change the B/R
Serial1.begin(linBaudRateBreak); // 9600 bps
Serial1.write(0x00); // break field of LIN
Serial1.end();
Serial1.begin(linBaudRate); // actual B/R 19200 bps
Serial1.write(0x55); // sync field of LIN
Serial1.write(0x42); // command to confirm the actuator stasus
// Actually, I have confirmed with an oscilloscope that the RX signal is reaching the Arduino Mega RX1 (IC pin 45).
// Despite the presence of the signal waveform, Serial.read() is not capturing it.
if (Serial1.available() >= 10)
{
for (int i = 0; i < 20; i++)
{
rxBuffer[i] = Serial1.read();
}
// Filter the RX data
if (rxBufferV[0] == 0x55 && rxBufferV[1] == 0x42)
{
for (int i = 0; i < 11; i++)
{
statusDataV[i] = rxBufferV[i];
}
}
}
Troubleshooting:
Confirmed the another Arduino Mega boards, same result (not hardware fault)
Tested on both Arduino IDE 1.8 and Arduino IDE 2.2, with consistent results.
Could anyone provide insights or advice on resolving this issue?
Post an annotated schematic showing exactly how it is wired. Be sure to note any wires over 10"/25cm in length. Many of us do not read frizzes. Post your code using code tags per the forum recommendations.
unable to read from RX1/19.
The 4.7kΩ pull-up resistor follows the application notes in the datasheet.
The CS pin is set to HIGH after boot and is not changed afterward.
WAKE and VREN are open and not used, and the system is operational with the signal from TX1/18.
I'm posting the code using code tags. Does it look correct?
Serial1.end();
Serial1.begin(linBaudRateBreak); // To make a break field of LIN, setting the lower B/R
Serial1.write(0x00);
Serial1.end();
Serial1.begin(linBaudRate); // Actuator specified B/R: 19200 bps
Serial1.write(0x55); // To make a sync field of LIN
Serial1.write(0x42); // Protected ID field of LIN, listening the actuator status
if (Serial1.available() >= 10) // This part will not work
{
for (int i = 0; i < 20; i++)
{
rxBuffer[i] = Serial1.read();
}
// Filter the RX data
if (rxBuffer[0] == 0x55 && rxBuffer[1] == 0x42)
{
for (int i = 0; i < 11; i++)
{
statusData[i] = rxBuffer[i];
}
}
}
Thanks for your response.
I too have simplified my approach to thinking that RX should just work with Serial.read(), but it's not working correctly.
I've confirmed with an oscilloscope that the waveform is being input, but it's not being read.
I haven't deciphered the waveform with a logic analyzer.
You wait until there are 10 bytes in the buffer. Then you fill a buffer with 20 bytes, but we don't know if that buffer is large enough and since there could be only 10 bytes, the rest is -1 or 0xFF, depending on the buffer. Then you check if the first one is 0x55 and the second one 0x42. Only then you copy 11 bytes to an other buffer. But we don't see how you print them to the Serial Monitor, maybe you don't.
That are about 5 possible problems that could fail. All you want to do is to check if you can read a byte. Just reading one byte is enough to know that you can read bytes.