I've spent about 2 years familiarizing myself with SAE OBD II communications protocols. I purchased the ELM327 OBD II CAN Interpreter, based on a PIC18F2480. As a test module, I printed a PCB board that uses a PIC18F25K50 for USB communication to my laptop. The initial goal is to send a command from the laptop to the K50 which is then sent serially to the ELM. I rigged an LCD screen to display (from the K50) communications both ways. I have the LCD verifying commands from the PC. However, the ELM327 Data Sheet claims it sends "ELM327 v2.1" when fired up, and when given "ATZ" command. I cannot seem to get the appropriate response from the ELM.
I rigged a logic analyzer to both Comm pins to see if it at least looked like it should. Sending "ATZ" from the PC is converted to 0x03 for the variable ByteCount (indicating 3 bytes of data to be transmitted; ATZ), 0x41 ("A"), 0x44 ("T), 0x5A ("Z"). The LCD confirms the K50 is receiving this from the PC via USB. From the K50 I send "ATZ" then $0D, which is the Carriage Return value. From the K50, the logic analyzer shows 0xA5, 0x8A, 0x96, 0xAC. Response from ELM is NULL, NULL. I tried MSB & LSB First, I tried Auto Baud Detect on the Logic Analyzer, I triple checked the 8 bits, 1 stop bit, no parity settings...
Next, the ELM327 has a couple BAUD rate options. Pin 6 tied to Vdd sets the initial baud at 38400, which is the option I chose. The punch line is I am unable to get the K50 talking with the ELM properly. I tried using the HSERIN/OUT commands setting the DEFINEs, but communication couldn't be verified. I then sent & received transmissions directly through the TXREG1 and RCREG1. Still no success. If I manually load values to represent an ELM transmission, the USB properly displays them, so the USB side seems fine. UART is not something I've worked with extensively. My inclinations are I'm not processing the data correctly between the K50 & ELM. Here is the pertinent code:
Code:;Configurations: #CONFIG CONFIG PLLSEL = PLL3X ;3x clock multiplier CONFIG CFGPLLEN = ON ;PLL Enabled CONFIG CPUDIV = NOCLKDIV ;CPU uses system clock (no divide) CONFIG LS48MHZ = SYS48X8 ;System clock at 48 MHz, USB clock divider is set to 8 CONFIG FOSC = INTOSCIO ;Internal oscillator CONFIG PCLKEN = OFF ;Primary oscillator shutdown firmware controlled CONFIG FCMEN = OFF ;Fail-Safe Clock Monitor disabled CONFIG IESO = OFF ;Oscillator Switchover mode disabled ; CONFIG PWRTEN = OFF ;Power up timer disabled CONFIG BOREN = ON ;BOR controlled by firmware (SBOREN is enabled) CONFIG BORV = 190 ;BOR set to 1.9V nominal ; CONFIG LPBOR = OFF ;Low-Power Brown-out Reset disabled CONFIG WDTEN = ON ;WDT enabled in hardware (SWDTEN ignored) CONFIG WDTPS = 512 ;1:512 CONFIG CCP2MX = RC1 ;CCP2 input/output is multiplexed with RC1 CONFIG PBADEN = OFF ;PORTB<5:0> pins are configured as digital I/O on Reset CONFIG T3CMX = RC0 ;T3CKI function is on RC0 CONFIG SDOMX = RB3 ;SDO function is on RB3 CONFIG MCLRE = OFF ;MCLR pin disabled; RE3 input enabled CONFIG STVREN = ON ;Stack full/underflow will cause Reset CONFIG LVP = OFF ;Single-Supply ICSP disabled ; CONFIG XINST = OFF ;Instruction set extension and Indexed Addressing mode disabled #ENDCONFIG INCLUDE "descript.bas" ' Include the USB & HID descriptors INCLUDE "DT_INTS-18.bas" INCLUDE "ReEnterPBP-18.bas" Define OSC 48 ;Interrupt Processor: ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler RX_INT, _Get_Elm, PBP, yes ;USART Transmission Received endm INT_CREATE ;Creates the interrupt processor ENDASM ; --- *** Oscillator Related SFRs *** ---------------------------------------------------------------------------------- OSCCON = %01110000 ;INTOSC 16 MHz, PLL Defined OSCCON2 = %10010010 ;PLL Enabled, HFINTOSC Running OSCTUNE.7 = 1 ;3X PLL ; --- *** USB SFRs *** ------------------------------------------------------------------------------------------------- UCON = %00001110 UCFG = %00010100 ; --- *** USART SFRs *** ----------------------------------------------------------------------------------------------- TXSTA1 = %00100100 ;24h, Yields 38400 Baud ;TXSTA1 = %00100000 ;20h, Yields 9600 Baud RCSTA1 = %10010000 ;90h, .2 = FERR, .1 = OERR BAUDCON1 = %01000000 SPBRG = 77 ;38400 Baud @ 48MHz, 0.16% PIE1.5 = 1 ;RCIE PIR1.5 = 0 ;RCIF PIE1.4 = 0 ;TXIE INTCON = %11000000 ;Variables: b0 VAR BYTE BANK0 SYSTEM ;Used for For/Next Loops b1 VAR BYTE BANK0 SYSTEM ;Used for For/Next Loops CmdCt VAR BYTE ;Similar to ByteCount, for ELM327 CmdSet VAR WORK.1 ;Indicates a Command has been received from the PC ElmBuf VAR WORK.3 ;ELM Data Received before Init_LCD Completed ElmSet VAR Work.0 ;End of Transmissions USART RX (Input from ELM), denoted by $D0 (CR) Hin0 VAR BYTE BANK0 SYSTEM ;USART Input from ELM327, BYTE0 InBufIndex VAR BYTE BANK0 SYSTEM ;Index used to move BYTES from Hinx to InBuf[InBufIndex] Work VAR BYTE ;Working Bits ' Alias for easy access to bit variables: hmRptVarBitArray0 var byte ' Endpoint 1 IN variables: ' ======================== ElmData var byte[23] OER var hmRptVarBitArray0.0 FER var hmRptVarBitArray0.1 ' Endpoint 1 OUT variables: ' ========================= ByteCount var byte CmdData var byte[23] Goto start ' Skip around interrupt handler ' ************************************************************************ ' Subroutines: ' ************************************************************************ ; --- *** RX_INT Interrupt Handler from ELM327 *** --------------------------------------------------------------------- Get_Elm: Hin0 = RCREG1 ; RCSTA1.4 = 0 ;CLOERR ; RCSTA1.4 = 1 ;CLOERR IF (Hin0 <> $0D) AND (Hin0 <> $29) THEN ;CR or ">" ElmData[InBufIndex] = Hin0 InBufIndex = InBufIndex + 1 ;EP1XmtDataReady = TRUE GOTO Leave ELSEIF Hin0 = $0D THEN ;Carriage Return b1 = InBufIndex - 1 ElmData[b1] = Hin0 FOR b0 = InBufIndex TO 22 ElmData[b0] = 0 NEXT b0 EP1XmtDataReady = TRUE InBufIndex = 0 GOTO Leave ENDIF Leave: ; USBService @ INT_RETURN InitUSBVars: USB_Enum_Complete = 0 return ' ************************************************************************ ' USB Init Code: ' ************************************************************************ start: gosub InitUSBVars RTS = 1 ;Active Low, ELM Request To Send Work = 0 ;Start all Working Bits at 0 InBufIndex = 0 ;Clear Input Buffer Index for ELM UART USBW_On = 0 Pause 10 USBInit ' Init USB and wait until configured HandleEp1Rcv = FALSE MainLoop: USBService ; Must service USB regularly HandleEp1Rcv = FALSE ;HIDMaker created USB related code goes here next DoHandleEp1Rcv: HandleEp1Rcv = TRUE ' Indicate that we have data to handle GOSUB Send_Elm ;We now have data from the USB to send to ELM ExitEp1Rcv: OER = RCSTA1.1 ;UART Over Run Error FER = RCSTA1.2. ;UART Framing Error EP1XmtDataReady = TRUE ;More HIDMaker generated USB code Send_Elm: RTS = 0 DO LOOP WHILE PIR1.4 = 0 TXREG1 = $29 FOR b0 = 0 TO (ByteCount - 1) DO LOOP WHILE PIR1.4 = 0 TXREG1 = CmdData[b0] NEXT b0 DO LOOP WHILE PIR1.4 = 0 TXREG1 = $0D HandleEp1Rcv = FALSE RTS = 1 USBService RETURN


		
		
						
					

Bookmarks