SLC OEM general I2C interface and possible wireless display

Official FreeEMS vanilla firmware development, the heart and soul of the system!
joey120373
QFP80 - Contributor
Posts: 39
Joined: Wed Oct 01, 2014 7:06 am

SLC OEM general I2C interface and possible wireless display

Post by joey120373 »

Hi all, hope this is the right place for this.

I am working on a WB02 solution for my motorcycle, its a 2 cyl with very little room to mount even small boxes.

I am waiting on some boards to arrive for an arduino based design that was floated elsewhere on this forum, however there does not seem to be a lot of info on that particular design and how well vetted it is, but i am excited to tinker with it none the less.

I did manage to find an old SLC_OEM ( date code is 2010.. old) board that i had hiding in a box this morning and thought it was about time i wired it up and tested it.

So today i did just that, wired it to a new 4.2 sensor, supplied 5v & ground and it works a treat on the liner out.

Next i tried to get the I2C comms working... not much luck there. I am using an arduino PRO-MINI (5v 16Mhz) with the hardware I2C port (A4&A5, same as a standard UNO) and i cant seem to get any reliable data from it. I can post the code variants if needed, but I have tried seemingly dozens of iterations and all seem to indicate that i am not reading the register(s) correctly. Using the Arduino wire library i do a:

Wire.beginTransmission(0x00); // SLC address is 0
Wire.write(0x03)// point SLC to 32bit Lambda register
Wire.endTransmission()// i poll this to verify the SLC adress and get a positive return
then i do a
Wire.requestFrom(0x00,4) // request 4 bites of data from register

I have get a good ACK return from the endTransmission command, and i verified it by trying to write to the wrong address, however once i start trying to read the data register i get a constant value regardless of what the O2 is doing. Generally it is a FFs but i have gotten other values, but they all tend to stay the same.
I have tried several ways of bringing the data in, bringing the bytes in one after the next and adding them, or simply displaying each byte on its own.

I did try setting it t read the ID register (an 8 bit value) and that seems to always return a "4", however i don't know what this means as there is no mention of what it should be other than a firmware revision.

I noticed in another thread here on the SLC that Toalen may have made a change to the registers to allow 16 and 8 bit values to be read.. im wondering if mine is so old that it has different register pointers?

I also just found that the wire library has been updated to allow a "wire.endTransmission(stop)" command, ill have to try that in the morning, as i was wondering if the "stop"command was actually being transmitted ( as per the graphic of the I2C communication in the SLC_OEM data sheet)
In any case i will keep playing with it but any advice is most welcome.

The end result of this will hopefully be 2 independent O2 sensors that transmit data wireless to a handlebar mounted display, Of course i can make it work as is using the liner output of the SLC, but I think it would be far more usable and flexible accessing the data directly.
joey120373
QFP80 - Contributor
Posts: 39
Joined: Wed Oct 01, 2014 7:06 am

Re: SLC OEM general I2C interface and possible wireless disp

Post by joey120373 »

Update.

I played with it more today and i am making progress.

I decided that since i had no reference for what register "0" (ID) should be, and polling register 03 (Lambda32) was not giving me data i could easily verify, it would be better to poll a register(s) that i could get verifiable data from...( DUH)....

The likely candidate was the "RiMAX" and "RiMIN" registers (11 and 13 respectively), these are used to calculate sensor temp ( temp is proportional to the Delta RiMAX-RiMIN ) and therefore i could expect to get a return from the SLC that should match up with the numbers on the SLC_OEM tech sheet.
It also helps matters immensely that these two registers are both transmitted as a 16 bit unsigned int ( meaning easily read and handled by arduino, more on this later).
I did not have success on the first try however, and my love/hate relationship with arduino was tested on both fronts. It appears that in arduino, using a binary (0b00000000) or HEX (0x00) or decimal (0) format for the SLC_OEM I2C address is perfectly fine, as they all mean ( and are supposed to be translated to the same ) 0b00000000 binary by the compiler,
HOWEVER>>>>> using anything but the binary representation for the register address met with failure, even though the myriad of I2C example sketches all seemed to use HEX format for the register write operations.

So "Wire.write(0x11)", or "Wire.write(byte(0x11))" or "Wire.write(11)" would not work, but "Wire.write(0b00001011)" works just fine, even though technically they are all exactly the same damn thing, at least according to Arduino. - note to self, just use binary.....-

So, once i figured that out , i was able to get both the RiMAX and RiMIN and calculate the sensor temp! woo-hoo. So getting the Lambda value should be a snap, right, just read any one of 3 registers..... not so.

I think my initial assumption that my old SLC_OEM unit does not support the lambda16 and lambda8 registers was correct, I cannot get any reliable data when i try to poll those registers.
I can get data from the Lamda32 register, however it is not formatted in a way that arduino can easily recognize it. Or possibly its better to say that it's not formatted in a way that i can easily make arduino recognize it.

The 32bit number i get is in a standard format called "IEEE 754 32 bit floating point" ( think i got that right...) and is not easily converted to a standard arduino value.

I can type the 32 bit number i get into an online converter and verify the data i am getting from the SLC_OEM is legit, however i will need to come up with a way to parse the number inside the arduino ( or just send it as is and parse it in the display controller, witch may or may not be a standard arduino) . this is not a simple task for a novice programmer like me but i know its possible, just not easy.....have to parse out the sign, exponent and Mantissa(?) bits, then apply math(s) and calculate decimal position, subtract 127 and add a "hidden" "1" then subtract 42, carry the dingus, multiply that by yellow, invert the remainder with n/Paris Hilton and divide by blah blah blah.....ok so math isn't my thing....

The new SLC_OEM i ordered should remedy this however, if My assumptions are correct (i hope they are) that the new unit will provide a more friendly 16 bit "standard" value just like the RiMAX and RiMIN then i need not worry about the complicated (to me anyway) math involved in converting the 32bit IEEE 754 number, but wee will see.

One thing i did note about the temp though is the PID loop does tend to overshoot a bit on a sensor that is already warm/hot, not a big deal i think and it doesn't overshoot a lot, but it does happen.
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: SLC OEM general I2C interface and possible wireless disp

Post by Fred »

joey120373 wrote:So "Wire.write(0x11)", or "Wire.write(byte(0x11))" or "Wire.write(11)" would not work, but "Wire.write(0b00001011)" works just fine, even though technically they are all exactly the same damn thing, at least according to Arduino. - note to self, just use binary.....-
0x11 = 17 = 0b00010001
0x0B = 11 = 0b00001011
Not sure if you made a typo there, or were doing it wrongly. C doesn't have 0bXXXXXXX except through marcos, however when it does have them, if they're correct they all end up as an integer type to the compiler or machine code anyway. So unless you hit an IDE bug in duinoland... something else was going wrong for the ones that matched (11 and 0b1011).
joey120373 wrote:I think my initial assumption that my old SLC_OEM unit does not support the lambda16 and lambda8 registers was correct, I cannot get any reliable data when i try to poll those registers.
Yep, that's my understanding, too. Likely from this thread, though I didn't read back up.
joey120373 wrote:I can get data from the Lamda32 register, however it is not formatted in a way that arduino can easily recognize it. Or possibly its better to say that it's not formatted in a way that i can easily make arduino recognize it.

The 32bit number i get is in a standard format called "IEEE 754 32 bit floating point" ( think i got that right...) and is not easily converted to a standard arduino value.

There should be libs available to do this, however it'll take a lot of flash space and run slowly. If those limitations don't hurt you, then you should be OK. No good when you're trying to run the engine on the same CPU, though, unless it has an FPU.

Your new SLC should have the 16 bit stuff in it. Let me know how you get on with that. The ones I have are old ones, too. Though I never tried to talk to them.

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
joey120373
QFP80 - Contributor
Posts: 39
Joined: Wed Oct 01, 2014 7:06 am

Re: SLC OEM general I2C interface and possible wireless disp

Post by joey120373 »

Making trouble getting posts through, so please forgive me if this is a double post...

As to the HEX. Formatting, totally a face palm on my part, I was indeed wrong there, I haven't changed the code yet as the bianary worked so I left it as is.

I did a little more research and found that Arduino also uses the IEEE 754 format to represent float values, so why am I not able to get accurate data from my code I asked myself....

Well, myself asked this question on the Arduino forum last nite, and then this morning set about trying to write code to do the conversion. I was able to parse the 32 bit long into the 3 bit strings easily enough, but after that getting the bits oriented with respect to the decimal and then applying the exponent was a bit of a brick wall. So I checked the Arduino forum, and amongst myriad posts telling me how easy it was ( with no small amount of scorn )to join 4 bytes into a long( even though I provided a 32 bit long to begin with....) , and a few describing in detail how to do the calculations to the said 32 bit long converted on paper ( same math I had already been trying to implement in code all morning) was a simple suggestion, 2 short lines of code, that made everything just work. Big thanks to the Arduino forum, scorn and all, I now have a fully functional WBO2 using the SLC_OEM, a $9 mini and an OLED display. I attempted to post a video earlier, not sure if it came through. I can provide my cobbled together code if anyone is interested.
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: SLC OEM general I2C interface and possible wireless disp

Post by Fred »

Glad you got it working :-)

Slap it up on github, you will never know who is interested until you do.

LOL @ forum people, so nasty, so viscious. They'd make good cats.

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
ivan141
LQFP112 - Up with the play
Posts: 148
Joined: Sat Sep 29, 2012 9:16 pm
Location: Rotterdam, the Netherlands

Re: SLC OEM general I2C interface and possible wireless disp

Post by ivan141 »

join 4 bytes into a long
Please tell me the answer was a union.
FABRICA MI DIEM, PVNC!
joey120373
QFP80 - Contributor
Posts: 39
Joined: Wed Oct 01, 2014 7:06 am

Re: SLC OEM general I2C interface and possible wireless disp

Post by joey120373 »

Union works, as well as a few other means.

I prefer to either bit shift or multiply and add the bytes because, for me at least, it makes the code easier to follow.
ivan141
LQFP112 - Up with the play
Posts: 148
Joined: Sat Sep 29, 2012 9:16 pm
Location: Rotterdam, the Netherlands

Re: SLC OEM general I2C interface and possible wireless disp

Post by ivan141 »

I was once threatened with being fired if I didnt use them where appropriate (while being introduced mind you).
Something about them being the most efficient way of solving the problem as all parts of the union occupy the
same memoryspace.
Looking back 8 years later I'm kinda glad I actually did get fired from that place...what an asshole (wasnt the union
that triggered it though :D).
FABRICA MI DIEM, PVNC!
joey120373
QFP80 - Contributor
Posts: 39
Joined: Wed Oct 01, 2014 7:06 am

Re: SLC OEM general I2C interface and possible wireless disp

Post by joey120373 »

I will most likely end up using a union. Im not much of a programmer, so when i start a project i usually write some pretty nasty code to just get things working, then i try to clean up the mess later once its doing what i want....

But the font library i am using to drive the OLED takes a ton of programming space, so i will need to tidy the code up quite a bit if i want to add much more.
joey120373
QFP80 - Contributor
Posts: 39
Joined: Wed Oct 01, 2014 7:06 am

Re: SLC OEM general I2C interface and possible wireless disp

Post by joey120373 »

Got a pic of it off a video I took, haven't had time yet to start on the wireless part but the wireless boards arrived a few days ago. If work schedule permits I hope to get that done and start working on casing it all up.

So far I'm really impressed with the little SLC OEM boards, hard to justify the arduino project I'm working on when these are only $40.... But it's fun to play with.

If I could figure out a way to implement a wireless I2C link that might make for a cool combination, a single (optionaly) battery powered micro running a display and possibly data logging talking wirelessly to to one or more O2 sensors that are simply an SLC, voltage reg and a $2 transmitter......
Attachments
image.jpg
Post Reply