Arduino Uno Reading Tx/Rx from Car Head Unit.

Image from Reply #19 so we don't have to download it. See this Image Guide

...R

Please don't post pictures of text. Just copy and paste the text.

The first version of your code (like this)

/*if (mySerial.available()) {
  Serial.write(mySerial.read());
}*/

is the more correct version.

But why aren't you using the example from Serial Input Basics the way I wrote it? Why have you moved the code out of the function recvWithEndMarker() and into loop()?

...R

Okay I tried this... but no output...

#include <SoftwareSerial.h>


SoftwareSerial mySerial(10, 11); // RX, TX


const byte numChars = 32;

char receivedChars[numChars];   // an array to store the received data


boolean newData = false;


void setup() {

    Serial.begin(57600);

    Serial.println("<Arduino is ready>");

    

    // set the data rate for the SoftwareSerial port

    mySerial.begin(9600);

}


void loop() {

    recvWithEndMarker();

    showNewData();

}


void recvWithEndMarker() {

    static byte ndx = 0;

    char endMarker = '\n';

    char rc;

    

    while (mySerial.available() > 0 && newData == false) {

        rc = mySerial.read();


        if (rc != endMarker) {

            receivedChars[ndx] = rc;

            ndx++;

            if (ndx >= numChars) {

                ndx = numChars - 1;

            }

        }

        else {

            receivedChars[ndx] = '\0'; // terminate the string

            ndx = 0;

            newData = true;

        }

        //flush(rc);

    }

}


void showNewData() {

    if (newData == true) {

        Serial.print("This just in ... ");

        Serial.println(receivedChars);

        newData = false;
}
    }

samrishi_24:
Okay I tried this... but no output...

It would be a huge help if you would write more than the absolute minimum and tell what are your thoughts about the problem.

Anyway, now we seem finally to have reached the stage where we have a known program and a basis for testing, so let's move on from there.

Do you KNOW that 9600 baud is the correct rate for your stereo AND that the stereo always sends a LineFeed at the end of its messages?

Is it necessary to send a message to the stereo before it will send a message back?

...R

Then I replaced the endMarker to '\0' then got some output when idle and when pressed any button then a lot of same garbage output...

No, I dont know the exact baud rate of the control panel...
But I tried serial.begin with all the baud rates from 2400 to 115200...

No, its not required to send the message to the control panel/stereo.. I just want to receive the values from that control panel... so that I can validate that which button is pressed... thats all I want....

samrishi_24:
Then I replaced the endMarker to '\0' then got some output when idle .

I am not going to waste my time trying to help if you keep fiddling with the code. It took from Reply #1 to Reply #22 to get it right.

Also, I asked you NOT to post pictures of text.

On top of all that, you don't seem to be thinking logically about the problem at all ...

You say "I tried serial.begin with all the baud rates from 2400 to 115200..." But how could changes to the baud rate for Serial have anything to do with it when Serial is not connected to the the stereo?

On the other hand you do seem to be receiving some characters which suggests that you have the correct baud rate - at least on that occasion. What baud rate was SoftwareSerial using when you received those characters?

...R

I am sorry, I am increasing your frustration level... I am completely unaware of all these things... I just gone through the internet to read the buttons of control panel via Aurdino to use it in my own car.

If am wasting your time... then i am sorry for that i will not post any thing from now..

but from the above post of mine..
i meant to say that mySerial.Begin i have tried with all....
but when i get the proper input is when these baud rates are set...

Serial.Begin(57600)
mySerial.Begin(9600)

Then i can see all these inputs in the monitor at 57600..

Yes you are right i am receiving the characters and when i press button i see a lot of characters... that means data is coming from the control panel... but the thing is they are looking like garbage for me to read the correct button....

So, I have two confusions...

  1. Data is coming continuously even i dont press any button (in slow speed)..
  2. When i press a button lot of data displays but in the garbage form as i have shown you in the images...

samrishi_24:
So, I have two confusions...

Let's go back to the version of the program you posted in Reply #22.

Try that again and tell me what output it produces. DO NOT make any changes to the program.

...R

Nothing on the monitor... also tx light is not blinking...

OK. Now try this modified version - I have marked the new lines. Post the output that you get.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

void setup() {
    Serial.begin(57600);
    Serial.println("<Arduino is ready>");
    
    // set the data rate for the SoftwareSerial port
    mySerial.begin(9600);
}

void loop() {
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (mySerial.available() > 0 && newData == false) {
        rc = mySerial.read();
            // show the characters as they arrive   // NEW
        Serial.write(rc);   // NEW
        Serial.println();   // NEW

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
        //flush(rc);
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
}
    }

...R

Thanks for helping... And sorry in advance because I am attaching the images here... as I am using arduino from my mobile...

So this one is the output of your program....

And dec values using Serial.println(rc,DEC)...

When i press buttons on the Control panel of car... then lots of values comes.. but only these values...

You now seem to be receiving data reliably - you just don't know what the data represents or how it is formatted, You need the datasheet or the user manual for the stereo to get a description of the data.

You could try using one or other of the numbers you see as the end-marker and see what happens.

I don't think I can help further without seeing the datasheet.

...R

Ohkk... :frowning:

But one more thing... Is it normal that the monitor is showing the data continuously even if I dont press any button. But if i press a button than it shows a lot of garbage data or spaces....

And last thing... Can we read the UART data directly using Arduino?
Or we need any CAN reader like CAN Shield or something else to read this... ??

samrishi_24:
But one more thing... Is it normal that the monitor is showing the data continuously even if I dont press any button.

Without being able to see the datasheet I cannot say.

...R

Hi, I finally figured out to get the unique value from the Car's Head panel input and send the command to the JVC radio as per the input.
Everything seems to be working fine, just the problem is the SendCommand(Key) function is not working properly as expected. It works sometimes, like sometimes I have to click the button twice or thrice to make it work, sometimes it works in the first time and some times it works twice even if i pressed it once...

But every times it shows that the key is there using Serial.println(Key) function... and it has been sent to the function SendCommand(Key) but still it doesn't works every time...

So just want to know that is there anything wrong in the code...

#include <SoftwareSerial.h>
 
SoftwareSerial mySerial(7, 5); // RX, TX
String readString;
 
//JVC Controls
#define VOLUP       0x04
#define VOLDOWN     0x05
#define SOURCE      0x08
#define EQUALIZER   0x0D
#define MUTE        0x0E
#define TRACKFORW   0x12
#define TRACKBACK   0x13
#define FOLDERFORW  0x14
#define FOLDERBACK  0x15
#define UNKNOWN1    0x37
#define UNKNOWN2    0x58
 
// Connect optocoupler input through a 1k resistor to this pin
#define OUTPUTPIN   8 // D8
// On-board LED, useful for debugging
#define LEDPIN     13 // D13
// Pulse width in µs
#define PULSEWIDTH 527
// Address that the radio responds to
#define ADDRESS 0x47
void setup()
{
  Serial.begin(57600);
  //Serial.setTimeout(2000);
  mySerial.begin(9600);
  pinMode(OUTPUTPIN, OUTPUT);    // Set the proper pin as output
}
 
unsigned char GetInput(int number, int prevNumber)
{
  if(number == 143)
    return TRACKBACK;
    else if(number == 140)
    return TRACKFORW;
    else if(number == 142)
    return FOLDERBACK;
    else if(number == 139)
    return FOLDERFORW;
    else if(number == 1)
    return VOLUP;
    else if(number == 255)
    return VOLDOWN;
    else if(number == 60)
    return MUTE;
    else if(prevNumber == 52 && (number == 32 || number == 37 || number == 38))
    return SOURCE;
   
    return 0;
}
 
 int prevNumber=0;
void loop() {
  
  while (mySerial.available()) {
    delay(10); 
    int number = mySerial.read();
    mySerial.flush();
      unsigned char Key = GetInput(number, prevNumber);  // If any buttons are being pressed the GetInput() function will return the appropriate command code
      if (Key) {  // If no buttons are being pressed the function will have returned 0 and no command will be sent
        Serial.println(Key);
        SendCommand(Key);
    }
    prevNumber = number;
  
}
}
 
 
 
 
// Send a value (7 bits, LSB is sent first, value can be an address or command)
void SendValue(unsigned char value) {
  unsigned char i, tmp = 1;
  for (i = 0; i < sizeof(value) * 8 - 1; i++) {
    if (value & tmp)  // Do a bitwise AND on the value and tmp
      SendOne();
    else
      SendZero();
    tmp = tmp << 1; // Bitshift left by 1
  }
}
// Send a command to the radio, including the header, start bit, address and stop bits
void SendCommand(unsigned char value) {
  unsigned char i;
  Preamble();                         // Send signals to precede a command to the radio
  for (i = 0; i < 3; i++) {           // Repeat address, command and stop bits three times so radio will pick them up properly
    SendValue(ADDRESS);               // Send the address
    SendValue((unsigned char)value);  // Send the command
    Postamble();                      // Send signals to follow a command to the radio
  }
}
// Signals to transmit a '0' bit
void SendZero() {
  digitalWrite(OUTPUTPIN, HIGH);      // Output HIGH for 1 pulse width
  digitalWrite(LEDPIN, HIGH);         // Turn on on-board LED
  delayMicroseconds(PULSEWIDTH);
  digitalWrite(OUTPUTPIN, LOW);       // Output LOW for 1 pulse width
  digitalWrite(LEDPIN, LOW);          // Turn off on-board LED
  delayMicroseconds(PULSEWIDTH);
}
// Signals to transmit a '1' bit
void SendOne() {
  digitalWrite(OUTPUTPIN, HIGH);      // Output HIGH for 1 pulse width
  digitalWrite(LEDPIN, HIGH);         // Turn on on-board LED
  delayMicroseconds(PULSEWIDTH);
  digitalWrite(OUTPUTPIN, LOW);       // Output LOW for 3 pulse widths
  digitalWrite(LEDPIN, LOW);          // Turn off on-board LED
  delayMicroseconds(PULSEWIDTH * 3);
}
// Signals to precede a command to the radio
void Preamble() {
  // HEADER: always LOW (1 pulse width), HIGH (16 pulse widths), LOW (8 pulse widths)
  digitalWrite(OUTPUTPIN, LOW);       // Make sure output is LOW for 1 pulse width, so the header starts with a rising edge
  digitalWrite(LEDPIN, LOW);          // Turn off on-board LED
  delayMicroseconds(PULSEWIDTH * 1);
  digitalWrite(OUTPUTPIN, HIGH);      // Start of header, output HIGH for 16 pulse widths
  digitalWrite(LEDPIN, HIGH);         // Turn on on-board LED
  delayMicroseconds(PULSEWIDTH * 16);
  digitalWrite(OUTPUTPIN, LOW);       // Second part of header, output LOW 8 pulse widths
  digitalWrite(LEDPIN, LOW);          // Turn off on-board LED
  delayMicroseconds(PULSEWIDTH * 8);
  // START BIT: always 1
  SendOne();
}
// Signals to follow a command to the radio
void Postamble() {
  // STOP BITS: always 1
  SendOne();
  SendOne();
}