Serial Communication and Variable Storage
tdeyle
Posts: 85
Hey everyone;
Simply put, I have an ELM322 OBDII (On-Board Diagnostic) device that I am trying to get to communicate with the Prop.
The protocol between the two is simple since the chip accepts regular ASCII Symbols with an "AT" prefix when giving direction to the ELM322; or hex characters, with no prefix, to give direction to the OBDII system. Both type of commands are terminated with a carriage return, "13".
I am looking to interface the two chips to display polled results to an LCD.
I am quite the beginner with the Prop, and programming general, and as such, arrived at a standstill. I am now trying to see if someone could lend a hand.
My issue is that I have been able to, with the Prop, reset the ELM322 ("ATZ" command), turn character echoing off ("ATE0" command), and display the Chip's version number, ("ATI").
I am working on getting the ELM chip to transmit back the status of the Fuel System from the OBDII, ("0103" command). I have come as far as getting the Prop to display the result on a Serial LCD. Since I do not have the ability to work on the program whilst in the vehicle, I end up getting a "NO DATA" reply.
My issue is, I would like to store this reply into a variable so that I can manipulate it, i.e., some of the replies will require formula to display data that makes sense and instead of a "NO DATA" reply, I could put N/A with a CASE loop.
I need the variable to hold enough data, the longest result would be "NO DATA". I am currently using the Extended Full Duplex Serial Object to communicate and find that it is near impossible, due to my lack of understanding, to store the replies into a variable.
I am looking to do this with nine different parameters, or PIDs as they are called, looped as fast as the ELM322 can manage to transmit them, since the ELM is based on a much slower PIC12C5XX Micro, it is rated at a nominal data rate of 9600 Baud.
Any help given is greatly appreciated.
Let me know if I need to post the code...
TDII
Simply put, I have an ELM322 OBDII (On-Board Diagnostic) device that I am trying to get to communicate with the Prop.
The protocol between the two is simple since the chip accepts regular ASCII Symbols with an "AT" prefix when giving direction to the ELM322; or hex characters, with no prefix, to give direction to the OBDII system. Both type of commands are terminated with a carriage return, "13".
I am looking to interface the two chips to display polled results to an LCD.
I am quite the beginner with the Prop, and programming general, and as such, arrived at a standstill. I am now trying to see if someone could lend a hand.
My issue is that I have been able to, with the Prop, reset the ELM322 ("ATZ" command), turn character echoing off ("ATE0" command), and display the Chip's version number, ("ATI").
I am working on getting the ELM chip to transmit back the status of the Fuel System from the OBDII, ("0103" command). I have come as far as getting the Prop to display the result on a Serial LCD. Since I do not have the ability to work on the program whilst in the vehicle, I end up getting a "NO DATA" reply.
My issue is, I would like to store this reply into a variable so that I can manipulate it, i.e., some of the replies will require formula to display data that makes sense and instead of a "NO DATA" reply, I could put N/A with a CASE loop.
I need the variable to hold enough data, the longest result would be "NO DATA". I am currently using the Extended Full Duplex Serial Object to communicate and find that it is near impossible, due to my lack of understanding, to store the replies into a variable.
I am looking to do this with nine different parameters, or PIDs as they are called, looped as fast as the ELM322 can manage to transmit them, since the ELM is based on a much slower PIC12C5XX Micro, it is rated at a nominal data rate of 9600 Baud.
Any help given is greatly appreciated.
Let me know if I need to post the code...
TDII
Comments
If you just want to store the information, you can use an array of bytes for each string you want to store and terminate each string with a zero byte. You'll have to store the text one character at a time since the only receive routines in the FullDuplexSerial driver are single character routines. There are built-in routines in Spin for copying a block of bytes (BYTEMOVE), comparing two strings for equality (STRCOMP), and determining the length of a string (STRSIZE).
So I have to store the strings that I know will come up, then compare them to the strings that are sent from the ELM chip?
Or store them as they are received one byte at a time?
It looks as though you are saying that I have a few avenues...
TDII
This is from the DAT block were I have created two byte arrays named Error and CAP_FS_Str. The Error array shows the string that will be produced if there is no data response from the ELM chip.
Below is the Public block setup for the CAPture Fuel System Method. It sends out a string, 0103, with carriage return, that will instruct the ELM chip to reply with the status of the Fuel System. The Prop will store the reply into the CAP_FS_Str array. A case loop compares the two arrays to see if they match, if they do, it displays "N/A".
I added a snippet at the end to clear the screen and display the contents of both arrays. The problem I see is that the display shows:
When I erase the contents of the @ERROR array in the DAT block, I find I get:
So, I thought maybe I am mentioning the error array somewhere else in the program and it is "mirroring" the received data that is filled into the other array, but I am not.
What am I missing?
Any help is appreciated.
TDII
I tried that before, but thought I needed to add a Zero to the end of the string in CAP_FS_STR.
It works now!
Thanks again.
TDII
I have successfully, with Mike's help, been able to get the Prop chip and the ELM chip to exchange information with each other for several different OBDII parameters, or PIDs.
I have found that, due to my knowledge of proper coding, I make my code as bulky as possible then try to trim it after it works. In my opinion, it is not the way I would like to do it, I believe one should be able to draw up "lean" code at the onset of the project.
Below is a snippet of code that compares the contents of a pair of Arrays that are given by a previous method.
This leads to the following piece:
As stated, there are several different parameters that need to be gathered, compared to the error array and calculations made. I wanted to sum all of these methods into one method using the following code, starting at the StrComp IF Loop:
This would call this method:
Finally, I added subbed in a dummy array value of "FF" to test the code. On the LCD, I get 445% instead of 100%.
I added some code to display the variables after the calculation loop:
My problem is that for some reason, even though the first byte and second bytes of TempVar are valued at FF, (dec 7070), CalcVar is equated to decimal 15 but CalcVar[noparse][[/noparse]0] stays at F, (dec 70)??
I have tried to take out certain aspects of the code, eg., separating the gathering loop from the conversion loop, etc. but to no avail.
You can see that having several methods to calculate, etc. would be a waste of code, thus, you would understand my determination with getting this to work.
Any help, is greatly appreciated.
TDII
Post Edited (tdeyle) : 7/6/2007 7:32:33 PM GMT
2) You've presented a lot of code fragments and it's not clear to me what you're asking. Start with the format of the responses from the OBDII. What are the different formats that you need to process? Can you list what the different responses are. Are all the numbers hex values? Are some of them decimal? Is there a delimiter like a comma or space used? Are the responses fixed format (like 4 hex digits)?
The responses of the ELM chip are in a "pseudo hex" format, they look like Hex characters but are in fact ASCII symbols.
For example if you transmit:
to the ELM chip, you will receive the status of the Engine Load from the ELM:
In this example, I will use:
The first four bytes are replies from the ELM giving:
"4" - Indicates an ELM Response, "1" - OBDII Mode, "04" - PID, "FF" - PID Data
I only process the last two bytes of data in this example, but there are others that have 4 bytes, (ex. RPM).
Since these are ASCII Characters, not Hex, I need to convert them to the proper values. The case loop in the CALC method, converts the values received from the ELM.
In this example, "FF" or "7070" would be converted into "1515".
This is where the problem lies since, using this method, the result after the conversion is "7015". This value gets carried further into the method and is output as 445% instead of 100%.
The only delimiter that is present is the Carriage Return (13), on the Tx string to the ELM chip. I have removed the default "," declaration from Extended_FDSerial to ensure this.
I have posted the code, less fragmented, to clarify the process.
The first method performed after the LCD setup is:
Which calls the ELM_Rx method:
This calls the Calc method with various parameters, shown below:
After this, I placed some debug code to show me what the values of some of the variables are:
The method continues and assigns a calculation, based on the value of CNum, that it needs to perform on the variables.
TDII
and you'd do
Post Edited (Mike Green) : 7/6/2007 10:45:23 PM GMT
When I express it as a byte variable, I do not get a reading, I believe it is aborting on the first "if" statement.
TDII
TDII
upper or lower case letters)
To be quite honest, I'm not sure how this and Mike's code would compare for speed and size,
but my feelings are this would be a bit quicker because·there are·less spin functions, but
larger because of the lookup (lookdown) table.
My C background would also tend to cause me to write the repeat as:
repeat while strlen-- > 0
·
There was initially no action on the LCD screen so I coded a program that would display the raw strings straight from the ELM chip with no formatting.
The results I get on the LCD are:
I tweaked the lcd.str(@EL_DatStr), adding [noparse][[/noparse]1, 2 and 3] to the Array to see what each one contained. This is what I got, shown as [noparse][[/noparse]1, 2 an 3], repsectively:
Seeing this, I rewrote lcd.str(@EL_DatStr) to read lcd.str(@EL_DatStr[noparse][[/noparse] 3]) and grouped everything in a Repeat loop.
After this change, I get looping data, (43 ., 42 ., 45 ., etc.) as well as some other strings: (DATA .). Which, if you reveal the whole string, reads: "NO DATA ." Now, that is why I have the STRCOMP, to compare the incoming strings with the @Error array, which reads, "NO DATA ",0 but it seems that it is not working.
I increased the pause from 100ms to 1000ms, hoping that it would allow the chips to communicate better. However, it didn't work, so I am led to believe it is due to the ELM chip communicating with the OBDII network.
My questions, is there something wrong with the STRCOMP section?
Is there any other way to differentiate between real data and NO DATA?
I am guessing that the reason why the HexToBin method did not work was due to the fact that the string will never equal to four, thus aborting the routine after the first question.
TDII