Code for https://youtu.be/b3TxFYFKEt0
This is CircuitPython. I have since re-written it in Arduino Wire (C++), and am now working on the KLine KWP2000 element of the project.

import board
import busio
import time
import adafruit_sdcard
#import adafruit_pcf8523
import microcontroller
import digitalio
import storage
import os

switch = digitalio.DigitalInOut(board.A5)
switch.direction = digitalio.Direction.INPUT
switch.pull = digitalio.Pull.UP

#Zeitronix Packet format, bytes[]
#[0] always 0
#[1] always 1
#[2] always 2
#[3] AFR
#[4] EGT Low
#[5] EGT High
#[6] RPM Low
#[7] RPM High
#[8] MAP Low
#[9] MAP High
#[10] TPS
#[11] USER1
#[12] Config Register1
#[13] Config Register2

#led = digitalio.DigitalInOut(board.D13)
#led.direction = digitalio.Direction.OUTPUT

SD_CS = board.D10
# Connect to the sdcard and mount the filesystem.
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
cs = digitalio.DigitalInOut(SD_CS)
sdcard = adafruit_sdcard.SDCard(spi, cs)
vfs = storage.VfsFat(sdcard)
storage.mount(vfs, "/sd")

uart = busio.UART(board.TX, board.RX, baudrate=9600, timeout=10)

#date = rtc.datetime() # will use this for the filename
# this board doesn't seem to have enough ram for the rtc library & sd & everything else going on here.. getting an allocation error
#filename = str(date.tm_year) + "-" + str(date.tm_mon) + "-" + str(date.tm_mday) + "-" + str(date.tm_hour) + "" + str(date.tm_min)
filename = "2017-09-11-test"
filename += ".csv"

def getPacket():
	rcdbyte = [None] * 3
	packet = [0] * 15
	packet[0] = time.monotonic()
	i = 0
	while True:
		rcdbyte[i] = uart.read(1)	#read a single byte
		if rcdbyte[i] == None:	#if we got an empty byte, assume the serial link is down, and return zeros.
			return packet
		if rcdbyte[i] == b'\x02' and rcdbyte[i-1] == b'\x01' and rcdbyte[i-2] == b'\x00': # we got our 3 bytes in order for the start of packet
			packet[1] = 0
			packet[2] = 1
			packet[3] = 2

			for x in range(4, 15):	#get the rest of the packet.
				byte = uart.read(1)
				if byte == None:	#if we got an empty byte, assume the serial link is down, and return zeros.
					packet[x] = 0
					return packet
				packet[x] = byte[0]
			return packet
		i += 1
		if i == 3:
			i = 0

#this is currently configured so that you have to short the pin to ground momentarily to start logging, then again to stop.
while True:
	if switch.value == False:
		time.sleep(0.2)
		f = open("/sd/" + filename, "w")
		while switch.value == True:
			packet = getPacket()
			f.write('{}\n'.format(packet))
			print('.',end='')
		f.close()
		time.sleep(0.2)