I am new to this site, but I have got a problem and You might be able help me out. I have got a car cluster which talks and listens to a 0V/+12V serial line. My goal is to send some extra commands to the instrument cluster. I'm using the MEGA's Serial2 for this and Serial to monitor the whole network.

The problem is, I have to wait still the line goes idle / silent so my message does not interrupt any other lines sent by other devices on the network.

I have got this so far:

#define Kbus Serial2
#define get_Kbus_data serialEvent2
#define Kbus_rx 17  
#define Kbus_tx 16
byte Kdata; 
uint8_t left_blinker[10]={0xD0, 0x08, 0xBF, 0x5B, 0x20, 0x00, 0x04, 0x00, 0x00, 0x18};
int time_Kbus;
void setup()
  Serial.begin(9600, SERIAL_8E1); 
  Kbus.begin(9600, SERIAL_8E1);

void loop()

if(millis()- time_Kbus > 1 ) Kbus.write(left_blinker, sizeof(left_blinker));     

void get_Kbus_data()
  Kdata = Kbus.read(); 
//  Serial.write(Kdata); 
  time_Kbus = millis();  

I am using two opto-isolators to get the proper 0V/+12V signals.


simulate this circuit – Schematic created using CircuitLab

I'm using 4N35 optos and a 2N3904 as Q1

I have noticed one thing while working with this. The Arduino does not send the starting zeros of, like 0x08 goes out as > 8 so maybe the recieving end does not recognise it?!

I can read the line using this circuit and an other code, but I haven't tested the "sender" side of it.

I think this is all I have.

UPDATE #1 = Missing junction between the two optos and GND line fixed.

  • \$\begingroup\$ did you check the speed of the opto's. both the rise and fall. \$\endgroup\$
    – mpflaga
    Jan 29, 2014 at 22:14
  • \$\begingroup\$ Is your cluster's bus protocol UART 8E1 9600. Note that 8 Even is unlikely where 8N1, 7E1 or 7O1. I don't follow the statement "0x08 goes out as > 8 s" \$\endgroup\$
    – mpflaga
    Jan 29, 2014 at 22:25
  • \$\begingroup\$ I meant I am trying to send this: D0 08 BF 5B 20 00 04 00 00 18 Arduino turns it into this: D08BF5B20040018 "The bus' physical layer is an open collector setup pulled high (+12v) by the bus, and pulled low by the talker. This means that the normal voltage on the wire is +12v (the battery voltage, or Vbatt). A bit is transmitted by pulling low or shorting the bus with the ground momentarily. This is the reverse of many digital signals where the normal voltage is 0v and is raised high to send a bit. Serial communications on the bus are 9600 bps, 8 data bits, Even parity, 1 stop bit." \$\endgroup\$
    – Zoszko
    Jan 29, 2014 at 22:45
  • \$\begingroup\$ Apart from right at the beginning (D0 08 becomes D0 8B) all the other corruptions are losses of "00". Is this a clue? Ignore me if I'm being stoopid. \$\endgroup\$
    – Andy aka
    Jan 29, 2014 at 22:55
  • \$\begingroup\$ It's like D0 is the ID of the sender unit 08 is the length BF is the target and than the actual commands 5B is for Lamp Status and than the control bytes. 18 at the end is the checksum. D0 08 BF 5B 20 00 04 00 00 18 Means the following: From LCM (Light Control Module) to Global: Lamp Satus: Indicator_Left Indicator_sync All_ok So if the Arduino deciedes that we don't need those 0s its gonna be a complete mess. Just like if we dont wait for communication clearance. \$\endgroup\$
    – Zoszko
    Jan 29, 2014 at 23:34

3 Answers 3


I'm not sure about the way you have opto1's diode wired - I'm thinking it should have its junction with opto2's emitter grounded.

If you trace the circuit through you have bus->R5->diode->transistor->bus - this cannot possibly do anything sensible - no current can pass through that circuit because there is no third connection to ground or power.

Maybe you have drawn it wrong but as it stands nobody is likely to help unless it is fixed because nobody can really know what you are trying to achieve. Maybe I'm wrong?

enter image description here

  • \$\begingroup\$ likely opto2's emitter and opto1's cathode are meant to be connected to ground. \$\endgroup\$
    – mpflaga
    Jan 29, 2014 at 22:16
  • \$\begingroup\$ @mpflaga that's what I said dude but thanks for confirmation. \$\endgroup\$
    – Andy aka
    Jan 29, 2014 at 22:18
  • \$\begingroup\$ Yeah I did it wrong! :D It's grounded. The speed of the 4N35 is tr= 7μs, tf= 7μs according to the datasheet this is "High-Speed Switching" \$\endgroup\$
    – Zoszko
    Jan 29, 2014 at 22:40

I believe your code and circuit are sending the correct string. Where it is your receiving code is stripping the leading padded zero's (as clued by Andy's comment)

As you are sending

D0 08 BF 5B 20 00 04 00 00 18

and you state you are receiving D08BF5B20040018, where if you arrange the same data as follows it appears to be correct.

D0  8 BF 5B 20  0  4  0  0 18

I see your code using:


and would think this would be obvious in the output, the linefeed remarking each received character.

Note that the byte received is still a whole integer regardless of the print's display of the leading zero being dropped. To see both nibbles including leading zero's you can use the printf function.

#include <stdio.h>
sprintf(charVal, "%02X", Kdata);
  • \$\begingroup\$ Thanks :) Now I have got the correct debug info. But I can't see the message on the network. (I'm using an other device on an other computer to monitor the communication.) Maybe it's the circuit, I will check everything once again just to make sure it's working as it sould be. \$\endgroup\$
    – Zoszko
    Jan 30, 2014 at 18:50

I have picked up other pieces of the k-bus (ibus) system so it's seems like I was missing something line an internal pullup. I'm using the ~same code (it has been ported to a duemilanove) and now it works like a charm. If anybody needs help with k-bus (ibus) related projects, contact me. enter image description here


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.