Schematic to use with Chris Gadd's OBDII object.
sccoupe
Posts: 118
Does anyone have a good schematic available that is tested to work with Chris Gadd's OBD2 object? There is one in the Spin code, but I cannot seem to make it work. I added a MCP2551 to a Propellor proto board but cannot get it to work. Its not connected to a vehicle but to a Microchip can bus analyzer. I should see CAN packets when the PID list is requested but I only get error frames. Ive checked that the analyzer is working correctly by hooking it up to a J1939 simulator and all is well. Thoughts, ideas?
Thanks
Thanks
Comments
The transmitter is hard-coded to 500Kbps, 11-bit standard frame, only ever tested with a 2009 Chevy Cobalt. It shouldn't ever send an error frame, as the writer inserts a stuffed bit after five consecutive 1's or 0's, never getting to the sixth that triggers the error.
If you just want something to look at, I'd use something like: That should give you the most control over what it sends, and hopefully what you see on the analyzer.
I tested them as much as I could without an actual CANbus to connect to.
CANbus Monitor - array - Archive.zip
CANbus Monitor - single - Archive.zip
In the main method of the CANbus monitor-array object, Data needs to equal ID + 4 * 8
In the PASM section of both reader objects, under parse_DLC_loop, 'rcl t1,#1' needs to be changed to 'rcl Temp_DLC,#1'
One more: again in the PASM section of the readers, under the Parse CRC_loop there needs to be an instruction between the movd and the instruction that it modifies. Simply move the add instruction down one line.
So far no luck with this, but still playing around. The new reader and main program (even with latest fix) do not send anything to the terminal program and cause passive CAN errors as soon as I send anything from the Microchip CAN Analyzer. If I use the code below for the main program and the original can read object(modified to not reset on other ID's that are not 7E8 and 7DF), I can send frames though the Microchip Analyzer and the Prop will send the 8 data bytes to the terminal program with no CAN errors.
I'd just assumed that any acks would come from other devices on the bus, and that the analyzer would carry on regardless.
CANbus Monitor - basic - Archive.zip
CANbus Monitor - array 0.1 - Archive.zip
Thanks
Thanks!
Rodney
This code seems to be really stable and testing has been going great. Now messing with different speeds and running into issues. Changing the frqa move from 500khz to 250khz is causing a lot of bus errors. I've tried tweaking the 250khz long value in small increments in case it was just a slight timing issue but with no good results. Your calculation for the frequency (Frequency = 2^32 * 12.5ns * bitrate) i'm having troubles fully understanding.
Frequency = 500
2^32 = 4294967296
12.5 = 12.5
bitrate = 500000
None of this calculates so I have something wrong above.
It should be worth noting that if I leave everything at the 500khz and set the PLL to 8 from 16, everything works great at 250kbps. Also, what are your thoughts on 1mbit bus support? Your notes say not to expect much faster than 500kbps. Is this a running out of time (prop not fast enough) problem or a stability problem. Here I've tried just doubling the 500khz long value with no success.
Also, one other thing just to clarify.... A long address like 0x000CB800 will not be handled as the lower 11 bits are zero, but 0x000CB801 would be handled correctly?
Thanks again for your help Chris, this is some very good code you have put together here.
The writer object uses a waitcnt instruction to establish a 500Kbps transmit speed. 1 / 500K = 2us, 2us / 12.5ns = 160. In order to have the writer work at 250Kbps, change the delay to 320.
The reader object uses a counter set to 500KHz. 2^32 * 12.5ns * 500_000 = 26_843_546. For 250KHz, use 13_421_773. The reader begins monitoring the input pin when the counter passes 270 degrees, and samples when a transition occurs or when the counter rolls over 0 degrees, so that should work the same regardless of the frequency.
In the Parse_Acknowledge section, I use a djnz loop to create a 2us delay for sending the acknowledge bit. For 250Kbps mov Delay_counter,#40 needs to be changed to mov Delay_counter,#80. 50ns * 80 = 4us.
Been a while since I looked at this code, but I don't see any other obvious gotchas.
As for the top speed, that's due to the Prop not being fast enough to sample the pin on a transition, determine if it's a real or a stuffed bit, decrement or reset the stuffed-bit counter, parse the bit, and update the CRC, or if there was no transition and the counter rolled over to 0, determine if the bit should've been stuffed, and still do everything else.
It could be made faster by storing every bit in a buffer and processing it afterward, though the acknowledge bit would be tricky; it'd either have to ack every message or no message. I spent a good bit of time optimizing it, though it's still entirely possible that one of the Prop gurus could find a more efficient routine.
A long address like 0x000CB800 would be transmitted as 00000000000, 0x000CB801 would be sent as 00000000001. The reader supports 29-bit IDs, but the writer object would need to be modified. Following the Add_IdentA section, add two 1's for SRR and IDE to indicate an extended frame, then add eighteen bits of Ident_B. Everything after that should work the same.
CANbus 1Mbps Main - Archive.zip
On this new reader.... Does the CAN side keep updating the variables with ID and Data regardless of the FDS reading those variables? In your other code, if the buffer is full the new data is dumped until a buffer spot is open, but its difficult for me to find such a thing in the new code so, I'm unsure of how it is operating even though the new code doesn't have a buffer. The ID's seem to come though great at 1Mbit and the data appears to come though as well, but seems to be less reliable. I wonder if the reader is writing over the data variables before the FDS transmits the entire string or is this even possible?
Thanks again!
Some further info added here. In the attached picture, the top portion is the terminal showing only the 0x444 ID. The lower portion shows the full bus info. The data '15 13 00 00 07 00 DA 25' is the correct data for it, but strangely it appear to more often than not, use the correct first two bytes and then use the last 6 bytes from ID 0x111. I suspect that the over writing is occurring but am also confused that it is not more random in nature.
CANbus 1Mbps Main 0.05 - Archive.zip
The rdlong operation checks for room in the buffer, setting the zero flag if there's room. The following line jmps to the end if there isn't room.
Many thanks again Chris. This is all great work!
Dunno what to make of the extended frames.
CANbus 1Mbps reader 0.06 - Archive.zip
Check it out at the Obex
Thank.
Thanks!
For the version that you're working with: The 40 is the length of the acknowledge pulse, you might try uncommenting the top lines and tweaking the #20 and seeing if that makes the other devices are happy. Also try the 1Mbps reader again, in addition to the earlier bug--caused by resetting the stuffed bit counter to 5 rather than 4 following a stuffed bit, which only became a problem in certain bitstreams, and during testing only showed up in the CRC--I also found a total noob mistake of using ina in the destination field. The hopefully fixed version is in the obex.
What i've seen so far is that #26 seems to get it much closer to 2us at 500k. Interesting is that this time seems to swing wildly from as low as 0.5us to 2.7us from the Propeller, but is much more stable at 2.25us to 2.5us when measured from the CAN Analyzer. Funny you mention the MCP2515, I just had a few arrive today for this purpose. If it comes down to it, I'll add one just to do the ACK. Crazy to do so but it would work.
No idea why some devices are having problems with that.