Miata Turbo Forum - Boost cars, acquire cats.

Miata Turbo Forum - Boost cars, acquire cats. (https://www.miataturbo.net/)
-   MEGAsquirt (https://www.miataturbo.net/megasquirt-18/)
-   -   $130 Bosch 4.9 sensor CAN-bus WB (https://www.miataturbo.net/megasquirt-18/%24130-bosch-4-9-sensor-can-bus-wb-87232/)

stefanst 01-06-2016 02:59 PM

$130 Bosch 4.9 sensor CAN-bus WB
 
Wideband Controller | LSU 4.9 | CJ125 | Lambda meter | ALM-Board

A while ago I have managed to read the CAN bus info from the MS3 with an Arduino compatible microcontroller. It really wasn't all that difficult, especially since I had a code-base I could download.
Feeding data into the MS doesn't seem to be all that much more difficult. The attached CAN-enabled WB sensor seems to be fairly easily configurable. So in theory I would ASSUME that it should be possible to make this work.

Now here's my dilemma: I don't understand the CAN bus protocol at all. In order for me to put in the work to learn it, I would like to be reasonably certain that the time and effort aren't wasted. That means something useful, other than pure knowledge, would have to come out of it- for example a cool WB sensor directly hooked up via CAN bus.

A search on the MSEXTRA forums yields no useful information on this.

Does anybody here have enough knowledge of CAN bus protocol to make a quick judgement?

cyotani 01-06-2016 03:16 PM

CAN is a pretty simple protocol. You might be able to pull out the information you need from the TinyIOX module firmware that has a serial input and CAN output for Innovate widebands.

stefanst 01-06-2016 03:59 PM

I don't think their FW is public domain. Just checked their website and the FW I could find looks like it's already compiled. Or maybe I'm missing something? If so I would appreciate a pointer!

aidandj 01-06-2016 04:31 PM

In for results.

4strings 01-06-2016 04:31 PM

You can check out this crazy project using a teensy board:

https://github.com/merkur2k/MSCan_Gauge/tree/teensy

It's doing a boat load of stuff over CAN BUS.

shuiend 01-06-2016 04:43 PM

Just FYI Bowling and Grippo are working on a Wideband module that will work better then anything else on the market in the sub $5000 category. It should work over the MS can bus perfectly and be far more configurable and do more error checking then the other widebands on the market. It will use the Bosch 4.9 sensor, have a price point between $250-500, and should be out by the end of the year. I am hoping to get my hands on an alpha version on it in the March-May time frame. If what all Bruce has let on it will do, I will be getting rid of all my AEM and Innovative widebands in all my cars.

stefanst 01-06-2016 04:48 PM

Sounds interesting, but....
$500 (because we know where their pricing is headed since MS-Pro) vs. $130. We're driving Miatas, so that means we're on a budget.
$370 for being more configurable and doing more error checking? That's almost a complete set of tires!

shuiend 01-06-2016 04:54 PM


Originally Posted by stefanst (Post 1297244)
Sounds interesting, but....
$500 (because we know where their pricing is headed since MS-Pro) vs. $130. We're driving Miatas, so that means we're on a budget.
$370 for being more configurable and doing more error checking? That's almost a complete set of tires!

Well it seems Bruce has actually got a site up with info. Here is more information about widebands then you will probably ever want to know.

The real thing is all sub $5000 widebands at the moment are horribly inaccurate for many reasons and most vendors don't tell you that. They also do not do any corrections based on sensor temps and such. After listening to Bruce talk about it at the Megameet I now trust widebands even less.

Joe Perez 01-06-2016 05:00 PM


Originally Posted by shuiend (Post 1297248)
The real thing is all sub $5000 widebands at the moment are horribly inaccurate for many reasons and most vendors don't tell you that.

I'm extremely curious as to the nature of the horrible inaccuracy.

I ask only because, several years ago, I got really bored and ran an OEM-type 4 wire narrowband sensor in parallel with my LC-1, which was about a year old at the time (having recently replaced an AEM UEGO which was, by any objective measure, not an especially good product.)

Presupposing that, by its nature, the narrowband sensor is always accurate at the stoichiometric point, I datalogged the two for comparison, to see if the LC-1 always reported crossing 14.7 at the same point as the narrowband. Aside from a relatively trivial amount of lag, I observed it to be pretty much dead-on-balls accurate, at least at the stoich point.

shuiend 01-06-2016 05:54 PM


Originally Posted by Joe Perez (Post 1297249)
I'm extremely curious as to the nature of the horrible inaccuracy.

I ask only because, several years ago, I got really bored and ran an OEM-type 4 wire narrowband sensor in parallel with my LC-1, which was about a year old at the time (having recently replaced an AEM UEGO which was, by any objective measure, not an especially good product.)

Presupposing that, by its nature, the narrowband sensor is always accurate at the stoichiometric point, I datalogged the two for comparison, to see if the LC-1 always reported crossing 14.7 at the same point as the narrowband. Aside from a relatively trivial amount of lag, I observed it to be pretty much dead-on-balls accurate, at least at the stoich point.

I honestly can't explain it because there is a ton of technical math involved that is a good bit above my level of understanding. I wish they would get the video of Bruce's wideband presentation from the MegaMeet up. The parts I sort of understand is that the Nernst cell and oxygen pump cell have a lot of variation based on a million things. Temperature of the wideband plays a huge part into it. Most of the variations and issues can be worked out an compensated for, but manufactures don't do any of it. I honestly suggest giving this site a read over if you have some time.

jstck 01-06-2016 06:10 PM


Originally Posted by stefanst (Post 1297216)
Wideband Controller | LSU 4.9 | CJ125 | Lambda meter | ALM-Board

...

Does anybody here have enough knowledge of CAN bus protocol to make a quick judgement?

Looking at the documentation for that Wideband controller, it seems it should work with Megasquirt. You probably have to set its CAN bus bitrate to 500kbps and send "standard" 11-bit ID's (as opposed to the default 29-bit "extended" frames), but it looks like there are settings for that.
At least my MS3Pro runs at 500kbps and I haven't seen anywhere that can be changed, and it afaik only receiving "standard" (not extended) frames is supported.

If I read things right, you get the lambda value (or maybe the AFR, not sure) as a 16-bit unsigned little-endian int value (L2U) at 2 bytes offset, which you divide by 4098 (or more precisely, multiply by 65535 and divide by 16). It also gives a bunch of other data with varying degrees of usefulness for the ECU.

stefanst 01-06-2016 06:35 PM

Thanks jstck!
Looks like I'll have to start reading stuff now...

cyotani 01-06-2016 07:36 PM


Originally Posted by stefanst (Post 1297234)
I don't think their FW is public domain. Just checked their website and the FW I could find looks like it's already compiled. Or maybe I'm missing something? If so I would appreciate a pointer!

Sorry, I thought their code was open source. Rev knows the answers to the questions your asking but I'm not sure if he's willing to share that info since it's similar to a product he sells.

stefanst 01-06-2016 08:39 PM

Yeah, I would understand Rev not chipping in here.

gooflophaze 01-06-2016 10:02 PM

So a quick overview.. it won't work unless the code is opened.

Just because it speaks CAN doesn't mean it will speak MSCan.

In MSCan you're writing directly to memory. When you set up Wideband over CAN in Tunerstudio, you're telling MS to "Broadcast a request packet". The req contains the address (block:offset) of where the AFR ratio is stored on the MS. To respond, you do a msg_write to block:offset with data of the AFR.

As far as functionality.. I wrote a library to read LC1's serial stream, display it on my gauge (4strings - yeap, that's my original code) with a difference between what MS3 was reading through analog vs the digital stream. My LC1 was well grounded, but the readings were surprisingly accurate. I don't recall seeing an offset difference of more than .1 AFR for longer than a few MS, which could have explained by buffer (and when I say a few MS, I mean the image was ghosted).

Joe Perez 01-06-2016 10:11 PM


Originally Posted by shuiend (Post 1297278)
I honestly can't explain it because there is a ton of technical math involved that is a good bit above my level of understanding. I wish they would get the video of Bruce's wideband presentation from the MegaMeet up. The parts I sort of understand is that the Nernst cell and oxygen pump cell have a lot of variation based on a million things. Temperature of the wideband plays a huge part into it. Most of the variations and issues can be worked out an compensated for, but manufactures don't do any of it. I honestly suggest giving this site a read over if you have some time.

I have read most of the site linked to. It's heavy on theory, and talks a great deal about what makes it the perfect wideband sensor with regard to the potential shortcomings of lesser designs. (eg: the AEM, which lacks free-air calibration, and pretty much every other system which doesn't use an external thermocouple).

What I didn't see was any discussion at all, even in the abstract, as to the magnitude of the improvement of these design features, nor the conditions under which they are manifest. Are we talking about a 0.5% improvement in accuracy? 2%? 10%? And is this across the board, or only at cold idle, or only at WOT when EGT is > [some large number], or only when driving up a 6% grade at part-throttle on a balmy spring evening just after a rain as the swallows sing faintly but distinctly in the distance?


To a certain extent, it reads like a site meant to overwhelm the casual reader with the impression that "I know what I'm talking about," without actually providing much in the way of useful facts.



Edit: The B&G article spends a great deal of time waxing on about temperature and the need for an external thermocouple. At the very end, they acknowledge that this isn't the only way to do it. Sensor temperature can be estimated with a high degree of accuracy my measuring the resistance across the reference cell. This is how the OEMs do it, as well as the Innovate LC-2. This method actually reduces measurement uncertainty somewhat (as compared to an external thermocouple) by taking into account the operation of the sensor heater.

aidandj 01-06-2016 10:19 PM

How do I alpha

stefanst 01-06-2016 10:28 PM


Originally Posted by gooflophaze (Post 1297340)
So a quick overview.. it won't work unless the code is opened.

Just because it speaks CAN doesn't mean it will speak MSCan.

In MSCan you're writing directly to memory. When you set up Wideband over CAN in Tunerstudio, you're telling MS to "Broadcast a request packet". The req contains the address (block:offset) of where the AFR ratio is stored on the MS. To respond, you do a msg_write to block:offset with data of the AFR.

As far as functionality.. I wrote a library to read LC1's serial stream, display it on my gauge (4strings - yeap, that's my original code) with a difference between what MS3 was reading through analog vs the digital stream. My LC1 was well grounded, but the readings were surprisingly accurate. I don't recall seeing an offset difference of more than .1 AFR for longer than a few MS, which could have explained by buffer (and when I say a few MS, I mean the image was ghosted).

I seriously doubt that they will open up their code. So we have the same problem as with all the others: No direct communication.
We could read it over serial (or in this case SCI) and then send it via CAN to the MS. Just like Rev or TinyIOX do.
So in order to save $60 as compared to an LC-2 you'd have to deal with an unknown piece of electronics. Meh.

Now if the sensor that Lars announced ends up on the $250 side of the range rather than the $500 side it would be worth it. We'll see, but I won't be holding my breath.

jstck 01-07-2016 02:56 AM


Originally Posted by gooflophaze (Post 1297340)
In MSCan you're writing directly to memory. When you set up Wideband over CAN in Tunerstudio, you're telling MS to "Broadcast a request packet". The req contains the address (block:offset) of where the AFR ratio is stored on the MS. To respond, you do a msg_write to block:offset with data of the AFR.

That is one of the two overall ways to get CAN data into Megasquirt (or any ECU), one device (MS) saying "hey, device with ID 100, give me data from table 111 offset 222" and the other device (WB controller) responding. This is what you set up in the "CAN EGO, GPS" menu item / dialog. MS can do this for a few specific things (EGO, GPS, VSS and Gear#) plus a bunch of "generic values" (under "CAN Parameters") that you can then use in various places.

The other method is just listening on data being broadcast, which is what you set up under "CAN receiving" where you specify an ID (the ID of the WB), an offset (the offset in the 8-byte data packet), and how the data is formatted. You can apply a "linear transformation" to map the data from some input range to whatever unit is needed.
This is what you would do for this WB controller, which just does broadcast stuff 100 times a second without anyone asking it for anything. Store this value as one of the CAN ADC items, and then use that as the EGO port under "AFR / EGO Control".

The thing that seems a bit odd to me is the data format, where "full output" (65535) corresponds to lambda 16.0. Making that into an AFR is just some math away (something like AFR = input * (16 * 14.7) / 65535) but that will have to be "simplified" a bit since Tunerstudio only accepts integer divisors/multipliers (+/-32767). Losing the 5th significant digit of the AFR value should not be much of a problem though.

Reverant 01-07-2016 03:18 AM

The PWC has been "almost there" for about 5 years. I grew tired of waiting, and made my own. Direct CAN comms to the ECU, 4.9 sensor support, and thorough details about the sensor status, including heater, Nerst cell, pump cell, vground status.

The PWC may be a million times better than the current offerings on the market, however it says it requires a "Calibrated" sensor to work properly. I don't think this will fly well with a lot of people.

stefanst 01-08-2016 04:07 PM


Originally Posted by jstck (Post 1297379)
...
The thing that seems a bit odd to me is the data format, where "full output" (65535) corresponds to lambda 16.0. Making that into an AFR is just some math away (something like AFR = input * (16 * 14.7) / 65535) but that will have to be "simplified" a bit since Tunerstudio only accepts integer divisors/multipliers (+/-32767). Losing the 5th significant digit of the AFR value should not be much of a problem though.

Ugh.
So we'd end up with a multiplier of 49 and a divider of 13653. Weird, but it works. If you're running E85 do your own damn math :giggle:

Savington 01-08-2016 04:10 PM


Originally Posted by shuiend (Post 1297278)
The parts I sort of understand is that the Nernst cell and oxygen pump cell have a lot of variation based on a million things. Temperature of the wideband plays a huge part into it.

How much variation?

Joe Perez 01-08-2016 04:29 PM


Originally Posted by Savington (Post 1297787)
How much variation?

That's exactly what I want to know.

My wristwatch, a nice-looking analog device made in Denmark by Skagen and costing about a hundred dollars, is wrong. By that, I mean that at last check, it's about three seconds slow relative to GPS time, despite the fact that I calibrate it once every month or two.

Three seconds is a huge error if you're a TV station. It can cost you tens of thousands of dollars if it happens during prime time. This is why nearly every piece of equipment in my station (well, those related to on-air operation, anyway) are referenced to an industrial GPS receiver with two antennas on a UPS, which is backed up by a second industrial GPS receiver with two antennas on a different UPS, both of which are on an automatic failover switch with dual power supplies.

But that's an extreme example. It's the $5,000 wideband sensor of timekeeping.

For most practical purposes, such as catching a train, attending a meeting, showing up for a dinner reservation, etc., being three seconds late is no big deal. It's functionally indistinguishable from actually being on time.


I'm only aware of one article in which a variety of wideband systems were subjected to comparative testing under controlled conditions using reference gas. You can read it here: http://tunertools.com/articles/FordMuscle.pdf

In that test, the LC-1 was determined to be accurate to within a tolerance of +/- 0.1 AFR under the test conditions.

Was this a sufficient test? Well, it obviously didn't involve an actual running engine, or account for variables such as heat, vibration, moisture, aging, etc. So I'm sure that a more meaningful test could be performed. Until someone actually does that, however, and publishes the results, claims that "affordable wideband systems are horribly inaccurate" must be taken lightly. The only data I can find suggests that an LC-1 is, in fact, a $100 Danish wristwatch.

stefanst 02-16-2016 09:30 AM

I just took the plunge and ordered a board. Let's see where we go from here.

stefanst 02-19-2016 08:44 AM

Received the board and sensor yesterday. That thing is tiny! I did read the 1" x 2.5" for the board, but didn't really appreciate how small that is. The quality is so-so. It's definitely not something produced in mass quantity. The board is run-of-the-mill China quality. Assembly looks halfway decent. All solder connections seem to be solid. The whole board looks like it was sprayed with about 20 coats of hairspray after assembly. They really put the protective lacquer on thick and quick.

So far I have not been able to read anything from it using an Arduino with a CAN shield. Not exactly sure what I'm doing wrong. I hope I'll have some more time to play with it this weekend.

If anybody here has experience using the Seeedstudion CAN shield with extended frames please let me know. I may be screwing up with the extended frames somehow.

jstck 02-19-2016 09:43 AM

I didn't use the Seeedstudio shield but a cheapo ebay one with the same chips on it (MCP2515 + MCP2551), and was able to read both standard and extended frames with that. Can link you to some example code that worked well enough for me.

Other things to watch out for that I've seen is the "+" and "-" sides of the CAN bus being mislabelled (swapped), and general randomness in which CAN components have an internal 120ohm termination resistor or not.

Edit: Another thing that bit me was the CAN bus bitrate. When you initialize the MCP2515 controller you tell it what speed to run at, but that bitrate is based on the controller being clocked at 16MHz. The CAN interface adapters I got were clocked at 8MHz so it ended up running at half of whatever bitrate I told it. Using CAN_1000KBPS made it run at 500Kbps though. From the looks of the pictures the Seeedstudio one has a 16MHz crystal on it so that may be a non-issue in your case though.

jstck 02-19-2016 09:56 AM

Here's some simple debug code I used that just outputs whatever stuff comes in on the CAN bus. I think this is the version I had that would also read extended frames properly (but I'm not near hardware that I can test on atm).

http://pastebin.com/KNXLFW5M

It doesn't use interrupts but just simple polling, so if frames come in quickly it will drop some due to the 500ms delay (which you can just lower), did that for readability of output.

stefanst 02-19-2016 10:36 AM

Thanks for the code. Having CanL and CanH confused is certainly a possibility. I would assume that this would cause some trouble. I may have confused them myself- even though I swear I did it right....

The WB does not have a terminating 120Ohm resistor, but at a wire length of maybe 20cm and 250kbps I don't think that would be the issue.

I'm pretty sure that my Seeedstudio shield uses the proper setup for bitrates, I used it to read gauge info from MS3, set at 500kbps. That worked.

I'll just run a RAW dump tonight, just reading the buffer every 100ms ir so and dumping it to serial. If the WB sends anything at all it should show up there.

stefanst 02-19-2016 09:36 PM

No dice. Even just posting the raw CAN bus data to my serial gets nothing. The WB must be doing something, because as soon as I plug it in, the "RX" LED on my CAN shield lights up.
Actually with jstck's code the "TX" LED lights up too. But with either one there's 0 bytes transmitted.

I tried BAUD rates from 100kbps to 1000kbps. Nothing

jstck 02-20-2016 03:48 AM

I think there is some kind of acknowledgement signals sent which might be what is causing TX to go on, but in that case it's really odd that it's not getting any data.

The only extended data I've meddled with was the MS3pro sending out "requests" when polling data (as set up in the CAN ADC, Vss and EGO dialogs), but I could see all those with that test code.
I honestly don't remember if I had to do anything with the mask/filter stuff, which I've never quite understood. There are a couple of lines about that (part of something I just copypasted from somewhere else), but since they are commented out I don't think so; I'm at least sure that for standard frames, setting no filters/masks whatsoever means it will receive everything.

Are you able to configure the O2/CAN controller to use standard frames to see if that makes a difference?

gooflophaze 02-20-2016 04:03 AM

I'll throw in with some of my code..

https://github.com/kckr/MSCan_Sniffe...Sniffer_V2.ino

that should display any CAN data coming across the wire, color coded to MSCan's packets if you use putty and each mcp2515 buffer displayed. I used it begin troubleshooting my own mscan development. You can reset the MCP2515's bitrate by playing with the CNF1-3 bits. Not sure if it'll parse correctly without some work for 11 bit ID's, but it should show anything broadcast.

stefanst 02-23-2016 09:57 AM

I was too lazy to figure out how the CNF1-3 bits on the mcp2515 actually meant. That datasheet is just waaaaaay too long for my OCD brain.

So last night I connected a cheap ESM327 based USB/OSBD2 scan tool to the board and lo and behold we have readings!
Raw data looks something like this:

3 0FF00 01 CC FA FC FF 12 9E 20 58
3 0FF00 01 47 F5 FC FF 7E B3 10 46
3 0FF00 01 B4 F4 FC FF A0 B3 00 FE

That is the correct address. The data returned makes sense as well. There were a few things that bug me a little, but nothing insurmountable:

- I kept receiving the error "1100 -- Heater circuit short to GND"
- The AFR only goes up to 16. Some cars run close to that in cruise
- FYI: the ALM uses the "SAE J1939 CAN (29 bit ID, 250 kbaud)" definition and NOT the "ISO 15765-4 CAN (29 bit ID, 250 kbaud)" definition.

I was using two different power supplies- one for 5V and another one for 12V. They were not connected. Turns out they need a common ground outside the ALM board and the "short to GND" error goes away.

While the AFR reported only goes up to 16% (and if you look at the data above, the AFR on top of my desk is apparently constant at 15.99), the sensor also gives us a percentage O2 that goes all the way to 20+%. Which is an AFR of infinity. The O2 reading also goes down to negative percentage, indicating a lack of oxygen, so we should be able to just convert the percentage O2 into an AFR value in the MS.

To do: Figure out how to send the proper message to the ALM in order to change the protocol to the MS-compatible "ISO 15765-4 CAN (11 bit ID, 500 kbaud)" definition. The manual just states to "PC send" the following (hex): "81 81 29 01 00 00 03" where the "81 81" puts it in programming mode and the "29 01 00" is the new address. The "00 03" at the end sets standard protocol and 500kbs.
So this sounds like I just write this raw data onto the bus and the ALM changes its' setup. That sounds a bit dangerous to me- what if some device on the bus accidentally sends "81 81" as a header? Am I missing something here?

cyotani 02-23-2016 10:19 AM


Originally Posted by stefanst (Post 1310274)

To do: Figure out how to send the proper message to the ALM in order to change the protocol to the MS-compatible "ISO 15765-4 CAN (11 bit ID, 500 kbaud)" definition. The manual just states to "PC send" the following (hex): "81 81 29 01 00 00 03" where the "81 81" puts it in programming mode and the "29 01 00" is the new address. The "00 03" at the end sets standard protocol and 500kbs.
So this sounds like I just write this raw data onto the bus and the ALM changes its' setup. That sounds a bit dangerous to me- what if some device on the bus accidentally sends "81 81" as a header? Am I missing something here?




You're not on the OBD bus are you? I'd keep the OEM CAN bus separate from your aftermarket CANbus if possible. If you do you should just have the Megasquirt and your CAN controller on the bus right? It should be safe to send that command out. Or just disconnect it from any bus and put it on the bench and send the command with an arduino or other micro controller. You should only need to write that setting once and It should save it.

gooflophaze 02-23-2016 10:47 AM

borrowing from https://developer.mbed.org/users/Fal...f0ce/MCP2515.h
125 kbps
CNF1/BRGCON1 b'00000011' 0x03

250 kbps
CNF1/BRGCON1 b'00000001' 0x01

500 kbps
CNF1/BRGCON1 b'00000000' 0x00

Throw that into CNF1 register, see if it'll pick it up.

stefanst 02-23-2016 10:51 AM


Originally Posted by cyotani (Post 1310291)
You're not on the OBD bus are you? I'd keep the OEM CAN bus separate from your aftermarket CANbus if possible. If you do you should just have the Megasquirt and your CAN controller on the bus right? It should be safe to send that command out. Or just disconnect it from any bus and put it on the bench and send the command with an arduino or other micro controller. You should only need to write that setting once and It should save it.

The meter is currently on my desk and not hooked up to any vehicle. My Miata doesn't have an OEM CAN bus either. So that's not a worry for me at this time. I was just wondering how this ALM meter would work in a normal car with a CAN bus so full of data that I certainly wouldn't feel comfortable with that board setup being changed so easily over the bus. But maybe that "81 81" is a reserved codeword that is part of the CAN spec. Who knows.

I was researching if I could use the ELM327 to send data out to the bus, but can't find any AT commands that would actually allow me to do so.

So once I get my Arduino or Teensy to actually communicate with the ALM, I should be able to reprogram it to MS3 specs.:jerkit:

jstck 02-23-2016 11:24 AM

Are you sure it's giving you the AFR value and not the lambda value? The spec sheet just talks about lambda, and that would in a way make more sense as it is independent of the stoichiometric ratio of the fuel being used. A max lambda value of 16 is ridiculously high (corresponds to a gasoline AFR of about 235:1, practically infinity), but in free air you have zero fuel and all of the oxygen, so it still would make sense here.
I do wonder what the heck "negative oxygen" would even signify though.

As for programming the ALM, I'm pretty sure you would still have to send a CAN bus packet to the correct ID (the ID of the ALM thingy). 81 81 is just the first two bytes of the 8 byte payload, and if it's addressed to anywhere else it should be ignored.

Not quite sure what the ID it receives those programming commands on actually is in the 29-bit extended world though.

cyotani 02-23-2016 11:29 AM


Originally Posted by stefanst (Post 1310306)
The meter is currently on my desk and not hooked up to any vehicle. My Miata doesn't have an OEM CAN bus either. So that's not a worry for me at this time. I was just wondering how this ALM meter would work in a normal car with a CAN bus so full of data that I certainly wouldn't feel comfortable with that board setup being changed so easily over the bus. But maybe that "81 81" is a reserved codeword that is part of the CAN spec. Who knows.

I was researching if I could use the ELM327 to send data out to the bus, but can't find any AT commands that would actually allow me to do so.

So once I get my Arduino or Teensy to actually communicate with the ALM, I should be able to reprogram it to MS3 specs.:jerkit:

Usually you keep aftermarket CAN devices on a secondary bus to not screw up with the OEM stuff. That's why a lot of aftermarket CAN products will have two CAN buses. One connects to the OBD buss in essentially a listen only mode or "SCAN Tool" device, and the other is to output any CAN messages without worrying about accidentally disabling all air bags.

If I were you I'd use an Arduino and CAN shield (or similar) as the middle translation bridge between your wideband and ECU. Have it read in the wideband CAN data then format it to the proper MegaSquirt CAN format and then transmit it out to the ECU via CAN.

stefanst 02-23-2016 11:39 AM


Originally Posted by jstck (Post 1310328)
Are you sure it's giving you the AFR value and not the lambda value? The spec sheet just talks about lambda, and that would in a way make more sense as it is independent of the stoichiometric ratio of the fuel being used. A max lambda value of 16 is ridiculously high (corresponds to a gasoline AFR of about 235:1, practically infinity), but in free air you have zero fuel and all of the oxygen, so it still would make sense here.
I do wonder what the heck "negative oxygen" would even signify though.

As for programming the ALM, I'm pretty sure you would still have to send a CAN bus packet to the correct ID (the ID of the ALM thingy). 81 81 is just the first two bytes of the 8 byte payload, and if it's addressed to anywhere else it should be ignored.

Not quite sure what the ID it receives those programming commands on actually is in the 29-bit extended world though.

DOH!

AFR != Lambda :idea:

Need to keep reading up on the bus protocol. So far I'm not even sure how to set a recipient address- all I've ever seen is broadcast.

I also just found this handy calculator for the CNF bits on the MCP251x series.
https://www.kvaser.com/support/calcu...ng-calculator/
Of course the values calculated with that tool in no way shape or form reflect the values that are defined in the Seeedstudio CAN library.

Will keep digging :-)

stefanst 02-23-2016 11:46 AM


Originally Posted by gooflophaze (Post 1310303)
borrowing from https://developer.mbed.org/users/Fal...f0ce/MCP2515.h
125 kbps
CNF1/BRGCON1 b'00000011' 0x03

250 kbps
CNF1/BRGCON1 b'00000001' 0x01

500 kbps
CNF1/BRGCON1 b'00000000' 0x00

Throw that into CNF1 register, see if it'll pick it up.

I'll give that a try!

stefanst 02-23-2016 10:43 PM

I'm baffled.

My Arduino shield works- but not with the ALM WB. I can read messages from MS3 at 500kbps no problem. I can even use different calculated settings for the CNF1-3 registers on the MCP2515 and it keeps working. Tried three different versions- they all worked. I can also send data from Arduino via CAN to the MS3 and have it displayed on gauges.

I'm just using the standard CAN receive routine from the examples. All it does is dump the CAN-buffer to serial. So if ANYTHING at all is received it gets printed. Loads of data comes from the MS3. But nothing at all from the ALM WB.

BTW: the ELM327 reader also reads the MS3 output, but it does throw a lot of "CAN ERROR" codes.

gooflophaze: Your code doesn't produce any output for me- not even reading from my MS3. I'm pretty sure I got the CS pin and the INT pin correct. The CNFs are the ones that I used with the Seeed library, so that's not it.

I must be doing something wrong, since all the parts work, I just can't get them to work together....

gooflophaze 02-23-2016 11:16 PM

With my code have you enabled a can broadcast from TS? By default my code doesn't do any requesting. Which arduino are you using?

edit: the seedstudio appears to be mostly identical to the sparkfun canbus shield.. d2 as interrupt, d10 as cs, stock spi pins. Not sure why my my code shouldn't work, serial is showing the can init?

stefanst 02-24-2016 12:26 AM

Yeah, broadcast was enabled. I'm sure I screwed something up. Will try again tomorrow.

gooflophaze 02-24-2016 03:55 AM

Weird.. I just ran the seedstudio library back to back with my code and both were able to pull data off the wire with the defaults (well, minus changing the chip select from 9 to 10).

Edit: I think I figured it out maybe.. add a SPI.transfer(0xC0); to reset and delay(100); to the beginning of setup()

and add

Serial.println(CANRead(CANCTRL), HEX);
Serial.println(CANRead(CNF1), HEX);
Serial.println(CANRead(CNF2), HEX);
Serial.println(CANRead(CNF3), HEX);

to the end. Both the sparkfun and seedstudio schematics are a little vague on their MCP2515 reset pin. If the CANread is printing 0x00, then MCP2515 isn't getting initted properly.

stefanst 02-24-2016 08:08 PM

Finally getting somewhere!

Your code used an apparently deprecated version of "attachInterrupt"
New code:
attachInterrupt(digitalPinToInterrupt(INT_PIN), ISR_can, FALLING);


Now I'm reading data from MS3 and from the WB. Now to get rid of all your parsing routines and do a simple HEX dump....

stefanst 02-24-2016 08:45 PM

@gooflophaze:
The data I'm reading using your code matches what I'm getting with the OBD2-reader!

I can see the actual data being stored in "databuffer". Where can I find the sender address?

Edit:
Of course the ultimate goal is to actually send data to the WB, reprogramming it.
Any chance you can help me with that?

Also: I have figured out part of the reason why the Seeed CAN library doesn't get any data. It seems to be the wrong initialization. Symptom: The MCP2515 doesn't pull the interrupt low after receiving from the WB. Using your code the interrupt pin gets pulled low. The RX line LED is flashing either way, so we know the transceiver is sending data to the 2515. But the 2515 can't do anything with the data when using the library. I'm using the same CNF registers as with your code, so the bitrate is set properly.

gooflophaze 02-24-2016 11:01 PM

Huh, guess I'll need to push a quick update then. There's an easy way of making it non-intterupt, just do a quick if (digitalRead(int_pin) == LOW) { MSParse();} or something like that. Moving from the registers to can packet.. quick and dirty I can do real quick.

if ((B00001000 & SIDL) == 0) {
// standard (not extended) can frame
CANid = SIDH; // copy
CANid = CANid << 3; // shift left 3 bits into 16bit int
CANid = CANid + ( (SIDL & B11100000) >> 5); // copy 3 bits, shift them right
}

bewm, there's your 11 bit can ID. not as clean as pulling from a can library.

But I would encourage (now that it's verified the MCP2515 is working) getting the seed library working. I wrote my code trying as bare metal as possible to minimize memory. Plus it helps illustrate the Buffers vs Megasquirt ordering (if you use an ANSI terminal).

stefanst 02-25-2016 12:34 AM

After confirmation that Arduino & MCP2515 are actually working, I hunted around Google for a bit and discovered a fixed CAN library here: https://github.com/coryjfowler/MCP_CAN_lib
Using that library I can read data and address from the WB with the Arduino.

Tomorrow I'll try and reprogram it to use 500kbps and standard frames.

Getting there!

russian 02-25-2016 11:52 AM


Originally Posted by stefanst (Post 1297234)
I don't think their FW is public domain. Just checked their website and the FW I could find looks like it's already compiled. Or maybe I'm missing something? If so I would appreciate a pointer!

bottom of MS3 Development Releases - Megasquirt EFI maybe?

Works in https://en.wikipedia.org/wiki/Public_domain would be "whose exclusive intellectual property rights have expired, have been forfeited, or are inapplicable."

MS is not public domain for sure. And while we are on this subject, MS is obviously not https://en.wikipedia.org/wiki/Open_source due to limitations under which they allow you to look at their source code. But they do show their source codes, at least some of them. Even if these are getting harder to find :)

aidandj 02-25-2016 11:53 AM

As far as I know they don't claim to be open source in the traditional manner. They provide the source to people who purchase their products.

stefanst 02-25-2016 12:00 PM

At that point we were actually talking about the TinyIOX module, which is made by Jbperf. I don't think they are officially part of B&G which I understand to be the owner of Megasquirt intellectual property. But in any case, I don't think their FW is PD or open source either.

gooflophaze 02-25-2016 07:06 PM

I looked it up and turns out the attach isn't deprecated, it's just got a handy new helper macro to align pin numbers to interrupts.

I went back and read what you're trying to do with the packet - All you need to do to send that (with my code) is modify the MSRequest function.

81 81 29 01 00 00 03 (assuming these are all data bytes?). offset is pretty much the same as CanID, just need to disable setting the EID bit.

SIDL = (lowByte((offset << 5)) | B0001000); //set IDE bit change to
SIDL = lowByte((offset << 5));

and then

DLC = B00000011; < change to B00001000 since we're sending 8 bytes

and then start the data packets after DLC is transmitted
digitalWrite(CS_PIN,LOW);
SPI.transfer(0x40); // Push bits starting at 0x31 (TXB0SIDH)
SPI.transfer(SIDH); //0x31
SPI.transfer(SIDL); //0x32
SPI.transfer(EID8); //0x33
SPI.transfer(EID0); //0x34
SPI.transfer(DLC); //0x35
SPI.transfer(0x81);
SPI.transfer(0x81);
SPI.transfer(0x29);
SPI.transfer(0x01);
SPI.transfer(0x00);
SPI.transfer(0x00);
SPI.transfer(0x03);
digitalWrite(CS_PIN,HIGH); // end write

that should write the packet you're looking for assuming I'm parsing the details correctly.

Edit: DLC should be B00000111 since we're sending 7 bytes. And if I wasn't clear before - MS's offset var is the same byte manipulation required to create an 11 bit can id. It's been a long day and my brain is fried.

stefanst 02-25-2016 08:04 PM

Well, I just tried sending the data package from the Seeed CAN library, using

unsigned char stmp[8] = {0x81, 0x81, 0x29, 0x01, 0x00, 0x00, 0x00, 0x03};
u32 address = 0x1FFFFFFF;
CAN0.sendMsgBuf(address, 1, 8, stmp);

And it worked, since I can see it showing up on the monitor in between the data from the WB, but it didn't actually reprogram the WB....

I will try your addition/change to your code next.

Edit: This is the output I get with the monitor:

3 0FF00 01 33 5B FC FF 85 9A 0A 00
6 0F00E 01 FF FF 33 5B BA EA FF FF
7 1FFFF FF 81 81 29 01 00 00 00 03
3 0FF00 01 33 5B FC FF 85 9A 0A 00
3 0FF00 01 33 5B FC FF 85 9A 0A 00
7 1FFFF FF 81 81 29 01 00 00 00 03
3 0FF00 01 33 5B FC FF 85 9A 0A 00
3 0FF00 01 33 5B FC FF 85 9A 0A 00
7 1FFFF FF 81 81 29 01 00 00 00 03
3 0FF00 01 33 5B FC FF 85 9A 0A 00
6 0F00E 01 FF FF 33 5B BA EA FF FF
3 0FF00 01 33 5B FC FF 85 9A 0A 00
7 1FFFF FF 81 81 29 01 00 00 00 03
3 0FF00 01 33 5B FC FF 85 9A 0A 00
3 0FF00 01 33 5B FC FF 85 9A 0A 00
7 1FFFF FF 81 81 29 01 00 00 00 03

The "7 1FFFF FF" packets are my attempt at reprogramming.

stefanst 02-25-2016 08:31 PM

So I have rewritten your MSrequest routine like this:
Code:

void MSwrite(byte block, unsigned int offset, byte req_bytes) {

  byte SIDH, SIDL, EID8, EID0, DLC, D0, D1, D2;

  SIDL = (lowByte((offset << 5)) | B0001000); //set IDE bit change to
  SIDL = lowByte((offset << 5));
   
  EID8 = B10011000; //:7 msg_req, from id 3 (4:3)

  //      TBBBBBSS To, Block, Spare
  EID0 = ( ( block & B00001111) << 3); // last 4 bits, move them to 6:3
  EID0 = ((( block & B00010000) >> 2) | EID0); // bit 5 goes to :2

  DLC = B00001000;
  D0=(block);
  D1=(offset >> 3);
  D2=(((offset & B00000111) << 5) | req_bytes); // shift offset

  digitalWrite(CS_PIN,LOW);
  SPI.transfer(0x40); // Push bits starting at 0x31 (RXB0SIDH)
  SPI.transfer(SIDH); //0x31
  SPI.transfer(SIDL); //0x32
  SPI.transfer(EID8); //0x33
  SPI.transfer(EID0); //0x34
  SPI.transfer(DLC);  //0x35
  SPI.transfer(0x81);
  SPI.transfer(0x81);
  SPI.transfer(0x29);
  SPI.transfer(0x01);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  SPI.transfer(0x03);
  digitalWrite(CS_PIN,HIGH); // end write

  CANWrite(CANINTF,0x00);

but what parameters to use for block, offset and reqbytes?

gooflophaze 02-25-2016 08:40 PM

That's a function I ripped out of another program - so you can pass offset(can id), and ignore block and req_bytes (well, not ignore - you'll have to pass data but it won't do anything since EID* bits are ignored in a standard frame).

SIDH declaration is missing.

SIDH = lowByte(offset >> 3);


And we're sending 7 bytes, not 8 - so DLC = 0x07

gooflophaze 02-25-2016 08:50 PM

quickcheck - no, i'm counting wrong.. it needs 8 bytes. DLC = 0x08, and you need another SPI.transfer.

stefanst 02-25-2016 09:13 PM

Code is now changed to
Code:

void MSwrite(byte block, unsigned int offset, byte req_bytes) {
 
  byte SIDH, SIDL, EID8, EID0, DLC, D0, D1, D2;

  SIDL = (lowByte((offset << 5)) | B0001000); //set IDE bit change to
  SIDL = lowByte((offset << 5));
  SIDH = lowByte(offset >> 3);
   
  EID8 = B10011000; //:7 msg_req, from id 3 (4:3)

  //      TBBBBBSS To, Block, Spare
  EID0 = ( ( block & B00001111) << 3); // last 4 bits, move them to 6:3
  EID0 = ((( block & B00010000) >> 2) | EID0); // bit 5 goes to :2

  DLC = 0x08;
  D0=(block);
  D1=(offset >> 3);
  D2=(((offset & B00000111) << 5) | req_bytes); // shift offset

  digitalWrite(CS_PIN,LOW);
  SPI.transfer(0x40); // Push bits starting at 0x31 (RXB0SIDH)
  SPI.transfer(SIDH); //0x31
  SPI.transfer(SIDL); //0x32
  SPI.transfer(EID8); //0x33
  SPI.transfer(EID0); //0x34
  SPI.transfer(DLC);  //0x35
  SPI.transfer(0x81);
  SPI.transfer(0x81);
  SPI.transfer(0x29);
  SPI.transfer(0x01);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  SPI.transfer(0x03);
  digitalWrite(CS_PIN,HIGH); // end write

  CANWrite(CANINTF,0x00);
}

called with
MSwrite(0x7ff,0x00,0x00);

Still can't see anything showing up on the bus....

gooflophaze 02-25-2016 09:18 PM

You've filled the buffer, but you still need to trigger it. RTS == request to send.

// RTS - Send this buffer down the wire
digitalWrite(CS_PIN,LOW);
SPI.transfer(B10000001);
digitalWrite(CS_PIN,HIGH);

CANWrite(CANINTF,0x00);

stefanst 02-25-2016 09:28 PM

Still no data on the bus -sorry to be such a pain...

gooflophaze 02-25-2016 09:38 PM

Salright, I've been awake for 24 hours now so I'm starting to see crosseyed. MSWrite needs some of the values transposed, I think..

MSwrite(0x7ff,0x00,0x00);

should be MSwrite(0x00, 0x7ff, 0x00);

and the RTS is at the end of MSwrite right?

stefanst 02-25-2016 09:48 PM

Progress!

data is showing up on the bus, but it looks like standard frames- not extended....
dump from sniffer:
Code:

7FF 81 81 29 01 00 00 00 03 <DATA ERROR
7FF 81 81 29 01 00 00 00 03 <DATA ERROR
7FF 81 81 29 01 00 00 00 03 <DATA ERROR
7FF 81 81 29 01 00 00 00 03 <DATA ERROR
7FF 81 81 29 01 00 00 00 03 <DATA ERROR
7FF 81 81 29 01 00 00 00 03 <DATA ERROR
7FF 81 81 29 01 00 00 00
BUFFER FULL



All times are GMT -4. The time now is 10:16 AM.


© 2024 MH Sub I, LLC dba Internet Brands