Uno Hardware Serial Baud Rate 10400

Hello

I have a problem with hardware serial.

I have found on the internet a code to reading the obd KKL kw1281 protocol.(I have attach the code)
The code it works very good with software serial with baudrate 10400.
My main problem is that when i add i2c requestEvent fuction with wire.write() the software serial lost same data when it come a request event from i2c.
To solve this problem i decide to make the serial communication with hardware serial.

My problem is that the hardware serial it dosent work at this baud rate.At the start of the code it receiving the first 3 bytes 0x55, 0x01, 0x8A but after that it dosent work.

has anyone any idea what i must to do ?

Thanks you in advance

arduino_kw1281_v0.2.ino (14.6 KB)

NewSoftwareSerial.cpp (13 KB)

NewSoftwareSerial.h (3.39 KB)

My problem is that the hardware serial it dosent work at this baud rate.At the start of the code it receiving the first 3 bytes 0x55, 0x01, 0x8A but after that it dosent work.

has anyone any idea what i must to do ?

Attach the code that doesn't work. Looking at the code that does work isn't going to help.

Let us see the theoretical aspect of your case in order to decide if the opted Bd is workable–

1. Bd = fosc/16(UBRR + 1) //U2X = 0 , asynchronous normal speed)
===> 10400 = 16*106/16 (UBRR + 1)
===> UBRR (Contents of the UBRRH and UBRRL Registers ) = 8.6 ----> 9

2. Error[%] = (Bdclosest match/ Bd - 1) * 100 = (10000/10400 - 1)*100) = -3.8 %.
[Bdclosest match = fosc/ 16(9 + 1) = (100000/10) = 10000]

3. Recommended Maximum Receiver Bd Error for Normal Sped Mode at Frame length 10 = +/- 2%.

4. Conclusion:
The opted Bd is out-of-specification?

Sorry
You are correct i upload the hardware serial code

main.ino (15.5 KB)

GolamMostafa:
Let us see the theoretical aspect of your case in order to decide if the opted Bd is workable–

1. Bd = fosc/16(UBRR + 1) //U2X = 0 , asynchronous normal speed)
===> 10400 = 16*106/16 (UBRR + 1)
===> UBRR (Contents of the UBRRH and UBRRL Registers ) = 8.6 ----> 9

2. Error[%] = (Bdclosest match/ Bd - 1) * 100 = (10000/10400 - 1)*100) = -3.8 %.
[Bdclosest match = fosc/ 16(9 + 1) = (100000/10) = 10000]

3. Recommended Maximum Receiver Bd Error for Normal Sped Mode at Frame length 10 = +/- 2%.

Thanks for the reply

So it is possible to read the serial with this baudrate?
can i slove the problem if i chage crystal?
because the car ecu support only 10400.

What you mean with opted Bd?

And i have notice that many time Serial receive that i send for first byte.

Thanks you

can i slove the problem if i chage crystal?

Sure. Just work the equations the opposite direction, to determine what the crystal frequency needs to be to get an acceptable error rate. Then buy a crystal of that frequency and solder it in place of the existing one.

Be sure to change EVERYTHING else that the Arduino does that depends on clock frequency.

What you mean with opted Bd?

I have used the word opt to refer your chosen Bd which is 10400.

yes i can not change the baud rate

you think if i change crystal the problem will solved?

The hard question is that you may come up with a calculation that might suggest a very odd-valued (frequency) crystal which mat not be available in the market. So, you have to make a sound judgement depending on these parameters.

Know the frame length of your async telemetry : START Bit (1) + Data Bit (7 or 8), Parity Bit (0 or 1) + STOP Bit (1 or 2). It is needed; because, the %error varies with these parameters. Let us assume frame length = 10. Acceptable error in Bd is: +/- 2% (10192 <–10400–> 10608).

===> 10400 = 8*10616(UBRR+1) //assume fclkSYS = fosc/2 = 8 MHz
===> (UBRR+1) = 48.08
===> UBRR = 47.08 ----> 47

===> Bd = 8*106/16(UBBR+1)
===> Bd = 10416 (allowable range: 10192 to 10608 to comply with +/- 2% error for Bd = 10400)

If you are using Arduino UNO, there is no need to change the crystal; leave it as it is at 16 MHz. Change the CLKPR (Clock Prescaler) setting (Fig-1) to obtain an operating frequency of 8 MHz.

Figure-1: CLKPR Register of Arduino UNO/NANO/MEAGA

Now the question is – will this Serial.begin(10400) instruction work? Probably, it will work with another Arduino; but, it will not work with the Serial Monitor as there is no option to set the Bd of the Serial Monitor at 10400 Bd. The available Bds for the Serial Monitor of IDE-1.8.5 are: 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, …, 2000000.

Hello

for testing i try this code:

#define CLOCK_PRESCALER_1   (0x0)
#define CLOCK_PRESCALER_2   (0x1)
#define CLOCK_PRESCALER_4   (0x2)
#define CLOCK_PRESCALER_8   (0x3)
#define CLOCK_PRESCALER_16  (0x4)
#define CLOCK_PRESCALER_32  (0x5)
#define CLOCK_PRESCALER_64  (0x6)
#define CLOCK_PRESCALER_128 (0x7)
#define CLOCK_PRESCALER_256 (0x8)


void setup() {
  Serial.begin(115200);
  Serial.println("Starting");
  setClockPrescaler(CLOCK_PRESCALER_2);
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, HIGH);
  Serial.println(millis() / 2);
  delay(1000 / 2);
  digitalWrite(13, LOW);
  delay(1000 / 2);
}

// Initialize global variable.
static uint8_t __clock_prescaler = (CLKPR & (_BV(CLKPS0) | _BV(CLKPS1) | _BV(CLKPS2) | _BV(CLKPS3)));

inline void setClockPrescaler(uint8_t clockPrescaler) {
  if (clockPrescaler <= CLOCK_PRESCALER_256) {
    // Disable interrupts.
    uint8_t oldSREG = SREG;
    cli();

    // Enable change.
    CLKPR = _BV(CLKPCE); // write the CLKPCE bit to one and all the other to zero

    // Change clock division.
    CLKPR = clockPrescaler; // write the CLKPS0..3 bits while writing the CLKPE bit to zero

    // Copy for fast access.
    __clock_prescaler = clockPrescaler;

    // Recopy interrupt register.
    SREG = oldSREG;
  }
}

but to see the text on serial monitor i must set the baud rate to 57600(115200/2)

so in my option i must set the prescale CLOCK_PRESCALER_2 and serial.begin(20800) to work correct on 10400 correct?

and the i2c will work correct if i change the prescale?

Thank you so much for the help

and the i2c will work correct if i change the prescale?

We are talking about UART Port. Correct? Why is I2C here?

The codes that you have posted is copied and pasted or you have prepared it?

You should try to write your own codes to operate the UART Port at 10400 Bd.

1. Initialize the UART Ports of UNO-1/UNO-2 for using register level instructions for the following parameters: Bd 10400, Data Bits 8, No parity, Stop Bit 1. Load 0x00 into UBRRH Register and 47 into UBRRL Register.

2. Use register level instructions to set CKPR Register at division factor 2 for UNO-1/UNO-2.

3. Connect a LCD with UNO-2 to monitor message to be arrived from UNO-1 at Bd 10400. You have no opportunity to use Serial Monitor neither for UNO-1 nor for UNO-2.

4. Send the following message to UNO-2. char s[5] = {'F', 'i', 'n', 'e', '\0'}; via UART Port of UNO-1 by executing the instruction: Serial.print(s);.

I found the setClockPrescaler fuction and i write the code to test it.but i write baud rate 115200 and this actually is 57600 thats why i shay that maybe i must set the double baud rate. In this code if i set UBRRH=0 and UBRRL=47 it will works with serial monitors? I am trying to test it with serial monitor to see the actually baud rate. Because if i test it with two arduinos with CKPR =2 will work but maybe both run on work baud rate correct?

I told for i2c because in the future i want to add some i2c request.

Thanks for help

any ideas?

Hey, I found your project really interesting. Have you found a solution to your issue?