PHP код:
	
#include <SoftwareSerial.h>
#define rxPin 3 
#define txPin 2
#define K_IN  0
#define K_OUT 1
#define READ_ATTEMPTS 125
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);
char command;                                                 //Terminal Commands
char pid_reslen[] =                                         //PID Lengths
{
  // pid 0x00 to 0x1F
  4,4,2,2,1,1,1,1,1,1,1,1,2,1,1,1,
  2,1,1,1,2,2,2,2,2,2,2,2,1,1,1,4,
  // pid 0x20 to 0x3F
  4,2,2,2,4,4,4,4,4,4,4,4,1,1,1,1,
  1,2,2,1,4,4,4,4,4,4,4,4,2,2,2,2,
  // pid 0x40 to 0x4E
  4,8,2,2,2,1,1,1,1,1,1,1,1,2,2
};
long tempLong;
char str[40];
void setup()  {
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  digitalWrite(txPin, HIGH);
  delay(500);
  pinMode(K_IN, INPUT);
  pinMode(K_OUT, OUTPUT);
  pinMode(13, OUTPUT);
  mySerial.begin(9600);
  mySerial.println("-=Arduino OBD2 Terminal=-");
}
void loop() {
  command = mySerial.read();
  switch (command) {
  case '1':
    obdConnect();
    break;
  case '2':
    mySerial.println("MIL Selected");
    get_pid(0x01, str, &tempLong);
    break;
  case '3':
    mySerial.println("RPM Selected");
    get_pid(0x03, str, &tempLong);
    break;
  case '4':
    mySerial.println("MAF Selected");
    get_pid(0x10, str, &tempLong);
    break;
  }
}
int obdConnect(){
  mySerial.println("Attempting ECU initialization...");
  if (iso_init() == 0){
    mySerial.println("PASS");
    return 0;
  }
  else{
    mySerial.println("FAIL");
    return 1;
  }
}
byte iso_init()
{
  byte b;
  serial_tx_off();                             //disable UART so we can "bit-Bang" the slow init.
  serial_rx_off();
  delay(3000);                                 //k line should be free of traffic for at least two secconds.
  
  
  digitalWrite(K_OUT, HIGH);                // drive K line high for 300ms
  delay(300);
  // send 0x33 at 5 bauds
  
  digitalWrite(K_OUT, LOW);                  // start bit
  delay(200);
  b=0x33;
  for (byte mask = 0x01; mask != 0; mask <<= 1)
  {
    if (b & mask) 
      digitalWrite(K_OUT, HIGH); 
    else
      digitalWrite(K_OUT, LOW);
    delay(200);
  }
  digitalWrite(K_OUT, HIGH);                // stop bit + 60 ms delay
  delay(260);
  
  Serial.begin(10400);                        // switch now to 10400 bauds
  
  byte i=0;                                    // wait for 0x55 from the ECU (up to 300ms)
  while(i<3 && !iso_read_byte(&b)){
        i++;
  }
  mySerial.println(b, BYTE);
  if(b != 0x55){
        return 1;
  }
  
  iso_read_byte(&b);
  mySerial.println(b, BYTE);                    // wait for kw1 and kw2
  iso_read_byte(&b);
  mySerial.println(b, BYTE);
  iso_write_byte(~b);                         // send ~kw2 (invert of last keyword)
  iso_read_byte(&b);
  mySerial.println(b, BYTE);          // ECU answer by 0xCC (~0x33)
  if(b!=0xCC)
    return 1;
  
  return 0;
}
void serial_rx_off() {
  UCSR0B &= ~(_BV(RXEN0));  
}
void serial_tx_off() {
   UCSR0B &= ~(_BV(TXEN0));  
   delay(20);                                 //allow time for buffers to flush
}
void serial_rx_on() {
  Serial.begin(10400);
}
boolean iso_read_byte(byte * b)
{
  int readData;
  boolean success = true;
  byte t=0;
  while(t != READ_ATTEMPTS  && (readData=Serial.read())==-1) {
    delay(1);
    t++;
  }
  if (t>=READ_ATTEMPTS) {
    success = false;
  }
  if (success)
  {
    *b = (byte) readData;
  }
  return success;
}
void iso_write_byte(byte b)
{
  serial_rx_off();
  Serial.print(b);
  delay(10);    
  serial_rx_on();
}
byte iso_checksum(byte *data, byte len)
{
  byte i;
  byte crc;
  crc=0;
  for(i=0; i<len; i++)
    crc=crc+data[i];
  return crc;
}
byte iso_write_data(byte *data, byte len)
{
  byte i, n;
  byte buf[20];
                      // ISO header
  buf[0]=0x68;
  buf[1]=0x6A;        // 0x68 0x6A is an OBD-II request
  buf[2]=0xF1;        // our requesterХs address (off-board tool)
  // append message
  for(i=0; i<len; i++)
    buf[i+3]=data[i];
  // calculate checksum
  i+=3;
  buf[i]=iso_checksum(buf, i);
  // send char one by one
  n=i+1;
  for(i=0; i<n; i++)
  {
    iso_write_byte(buf[i]);
  }
  return 0;
}
// read n byte(s) of data (+ header + cmd and crc)
// return the count of bytes of message (includes all data in message)
byte iso_read_data(byte *data, byte len)
{
  byte i;
  byte buf[20];
  byte dataSize = 0;
  for(i=0; i<len+6; i++)
  {
    if (iso_read_byte(buf+i))
    {
      dataSize++;
    }
  }
  
  memcpy(data, buf+5, len);
  delay(55);    //guarantee 55 ms pause between requests
  return dataSize;
}
boolean get_pid(byte pid, char *retbuf, long *ret)
{
  byte cmd[2];                                                    // to send the command
  byte buf[10];                                                   // to receive the result
  
  byte reslen = pid_reslen[pid];                                 // receive length depends on pid
 
  cmd[0]=0x01;                                                    // ISO cmd 1, get PID
  cmd[1]=pid;
  
  iso_write_data(cmd, 2);                                         // send command, length 2
  
  if (!iso_read_data(buf, reslen))                                 // read requested length, n bytes received in buf
  {
      mySerial.println("ISO Read Data Error.");
      return false; 
  }
  *ret=buf[0]*256U+buf[1];                                         // a lot of formulas are the same so calculate a default return value here
  
  mySerial.print("Return Value ");
  mySerial.print(pid, DEC);
  mySerial.print(" : ");
  mySerial.println(*ret);
  
  return true;
}