L9780 SPI help - inconsistent output

Figure 10 is a bit of a mystery to me… I have looked at it multiple times, upside down and back to front and it doesnt float my boat. But i think we are on the same page with as soon as you assert that chip select, you are going to read what ever is coming back to the micro from the last device and it will be either a status or a “echo” dependent on what was sent to it last.

As for reset, im glad someone else can clairfy this too. Yes, no reset pin, so hard reset can only be done via full power down, or perhaps some state transitions internally but im yet to understand the internal states.

I agree, its hard to define my current understanding of the “Echo” as it would contradict the datasheet. But If I can hold the chip select line low and see the exact control word I pumped in then I know that it made it to the SPI device. So if it has chosen to echo something different to me, then it means something larger is at play. A line in the documentation that keeps resonating with me but is not clear is “If CSN is negated, SO pin is in tri state condition and the fault register is reloaded (latched) with current filtered status bits.”

I really appreciate being able to bounce this of someone else. So keep up the great work!

1 Like

Figure 10 is a bit of a mystery to me… I have looked at it multiple times, upside down and back to front and it doesnt float my boat. But i think we are on the same page with as soon as you assert that chip select, you are going to read what ever is coming back to the micro from the last device and it will be either a status or a “echo” dependent on what was sent to it last.

It’s showing how if the CS pin is held low, it will continue to shift out whatever was received over MOSI. Like i mentioned previously, some peripheral chips will require the CS to be held low while the controller continues to clock (another word or words worth of signal) to get the response back. I had originally thought the L9870 was the same but continuing to look at this, it appears its just a straight shift-out.

For example, on the first word that’s being sent, “command 3” is sent out from the controller to the first peripheral, in this case “L9780_1”. Simultaneously, since all three peripherals are tied to the same CS pin, they’re going to provide whatever “output” they have on the previous RX’d word. Whether thats a status reg, or the input reg is just based on whatever the previous instruction was.

In the diagram, they’re saying “command 3” because that’s the “command word” they want to get to "L9780_3”. It has to be sent first in the series, because then it’ll take 3 “command words” to be sent for everything to chain its way through. With each word that’s being sent then, because the CS pin is still held low, the peripheral will just shift whatever it (previously) received on MOSI, out on its MISO pin. The end result is that after 3 “command words” worth of clock cycles (which is the right-most column in figure 10), the MOSI pin on L9780_1 finally gets “command 1”. The MOSI pin on L9780_2 finally gets “command 2” after being sent out of L9780_1, and so-on. This is how I visualize it:

A line in the documentation that keeps resonating with me but is not clear is “If CSN is negated, SO pin is in tri state condition and the fault register is reloaded (latched) with current filtered status bits.”

With the above in mind then, I think what the intent of this is, is clarifying that the peripheral’s fault bits in the status register will NOT be allowed to be updated until the CS pin is de-asserted (released back to a “high” state again in this case). The leading part of section 6.1 also states “If CNS is asserted….(blahblahblah)….all status information is latched into SPI shift regiser”. Putting both of these together means that:

  1. once CS is asserted, whatever was prepared to be sent out, is shifted into the output register. If clocks/data are received, then that output register is sent over MISO
  2. If CS remains asserted, any more clock/data will just continue to be “throughput” by shifting the MOSI data out onto MISO. Regardless of what data is being sent, the peripheral doesn’t care.
  3. Once CS is de-asserted, then (and only then) will the peripheral say “okay, cool. the last command/data i have in my input register now is my next “command” i need to care about. In addition to that, once CS is de-asserted is what triggers the peripheral to re-evaluate it’s fault conditions (based on the current bits, that dictate which fault states to worry about) and then it puts that result in its internal fault register.

In the previous test, you effectively demonstrated #2 just shifting in/out the data RX’d. I’m still not sure what exactly was going on in your first test where CS was toggled but you seem to have resolved it since (your last screen shot only showed one transaction I’m not 100% sure but from the sounds of it, you’ve got it working).

Which then too it looks like your results are at least…something…in terms of there’s no fault bits or anything set:

Also, something to be careful of, one of the application notes said that “STGINRC” and “VCCSEN” shouldn’t be set on start-up due to possible false-trigger concerns. It looks like in your control word those are both set, that may have been causing issues with triggering faults before. I’m not sure “when” in a potential start-up sequence you’re sending those but from what I can remember once R,cell reaches an appropriate (not dead cold) value, then those can be enabled.

Seems my RCIMP values dont really change much. Even after leaving the heater running for over 5 minutes with about 500mA, they may move by 50 counts…from the base levels of about 830 and 250 respectively. This is just a screen shot early on in the piece, but RCIMP2 wont really move passed 300 counts. Is this expected or am I chasing another hardware issue?

Maybe? Without seeing your circuit there’s no way to check if something’s physically different/wrong. Sharing that would be a good start now that it’s communicating just to verify the sensor wiring, etc.

Also what’s the control word you’re using in the above screenshot? As well as the full status word response (not just the RCIMP1/2 values). Guessing from your previous transmits should be okay but just making sure.

Ok, so updates:

Made sure Count was actually counting and I can see that changing.

I do have ISPT set to 0 as per Bosch instructions but chat keeps telling me to set that to a non zero number. Find attached an example of a communication with the device. I used your nifty little excel sheet and as per my peak, it looks to be reflective of the values im seeing on my GUI.

Im going to double check this sensor in my car and see if my aftermarket can read it to rule out the sensor being an issue.

My loading is as per the datasheet:

So did some minor trouble shooting today:

Built an entire new board from scratch to ensure that I hadn’t accidentally loaded wrong values. Powered on and the same behaviour still exists. So leaning towards, its not a hardware issue, its more likely a value loading issue or a software issue.

Also ran my wideband sensor through my aftermarket unit to ensure that it was giving sensible results and that also checked out.

So now Im going to deep dive on my loading again and my register setup.

could you post an image or PDF of YOUR actual circuit? Hopefully there’s nothing wrong with it but this is a great point just to get a fresh set of eyes on it and make sure that it’s lining up with the application circuit.

Also, what color/signal lines are you wiring to where?

I’m curious about both because you’ve got a good sensor (as evident by the aftermarket verification). Even without enabling VCCS yet (esp since we don’t know the internal temp) I’d expect your RCIMP(1/2) values to be changing with temperature. Something doesn’t seem right there.

One thing I did note was that the PWM seems to be inverted out of the L9780, is that something you too have seen? Just wanted to voice that point in case you were feeding 100% PWM and ending up at 0% (which would be why the heater wasn’t changing!) have you verified the heater line OUT of the L9780 is doing what you’d expect it to?

So the L9780 does invert the PWM signal as stated in datasheet:

PW pin signal is then internally inverted by the logic and the consequent signal is then applied on HG pin, conditioning the activation/deactivation of the external heater FET (and so the power consumption necessary to heat the sensor).

I found out that chestnut the hard way too. But yes valid point and worth noting. The heater part of my circuit is seemingly to be working correctly. Even the diagnostics seems to work. Can def tell its up in temperature by the burn the finger test.

As for my actual circuit my circuit design program doesnt give a good means of showing the entire thing with clarity, so unfortunately it has to be piece meal… Design Spark PCB. I think im limited to how many images i can throw up. It wont let me put any more on as yet, but i suppose its the meat and potatoes of the chip:

As for sensor wiring:
Pin 1: Pump Current: SNS Pin 2
Pin 2: Virtual Ground : SR Pin 7
Pin 3: Heater - : HD Pin 10/
Pin 4: Heater +: 12V
Pin 5: Trim Resistor: TG1 and TG2 Pin 1 and 46

Pin 6: Nerst Voltage: INRC Pin 4

Huh, alright. I don’t see anything glaringly odd/off from what I’ve made either. The only difference I can see is the R,tg and R,out resistors but those shouldn’t be affecting the cell measurement (or at least i wouldn’t think they would). Just to re-confirm; you’re seeing no difference in the output RCIMP(1/2) values from dead cold to a noticeably hot sensor?

Also, out of curiosity. Have you waited for a noticeably hot sensor and then tried enabling VCCS, and then reading the output? I would think the cell resistance measurement could/should be independent from VCCS/sensor Ip control but….who knows? The datasheet talks about the “parking functionality” in a few spots which seems just to be related to current control but maybe there’s something else going on?

Also, I can’t remember if I uploaded these in the zip file earlier but everyone seems to use an ever-so-slightly different nomenclature for the sensor pin names so I have a PDF with some of the common diagrams, the sensor connector pinout with colors, and then also that information overlaid on the L9780 “sensor” they show as well. Probably past that point but just wanted to get it out there in case it would help. I’ve also attached my circuit as well just for reference.

WBO2_diagrams.pdf (214.0 KB)

L9780_dev.pdf (323.7 KB)

Nice documents…

I have promised myself that come the completion of a running system I want to write a document that allows others to get to the same point. Seems like such a wasted chip if others cannot get the benefit.

Where is your current prototype at? Would be good if you could join along the ride with your hardware too? You seem so across it, that its almost a shame that your not actively playing too. Time is always a factor I do understand.

No, i havent enabled VCCS. I should try that and see what happens.

Agree on the documentation. Initially I thought i was just missing /something/ in the datasheet that was obvious and/or just not understanding a core concept but now I feel like there’s quite a bit missing in it. I’ll for sure be up to help with documentation too, I do quite a bit of that for work and other projects. It would be nice since it’s really the only other available SOC that’s out there right now and the ONLY one that’s direct purchasable in north america.

Also, proof I actually have a prototype! :rofl:

I just been focused on other things recently. I made a big push initially with this chip because I was working on an updated sensor board for my track car that’s currently using a CJ125. There were a few other projects I had going on though and this one just didn’t win out on priority.

My current ire is split between two things. The first is a rPi based digital dash. Communicates over CANbus with everything, has pages you can cycle through, to display gauges, bunch of different features, etc. The hardware part was easy and I’ve had it running/testing in the car for the last year but I’m >this< close to wrapping up everything else to make it better. Everything runs on a CM4 and it’s got a stripped-down OS for a quicker boot that I compile. I’m currently re-writing parts of the core application to make things more modular, but my main focus has been the visual editor that builds the dash config.

The actual dash app and the editor I’m making are all python based which has been a learning curve but I’m getting there. Few things to wrap up on this so I’m making a big of a push now to get it to a “released” state. Few things in the kernel I need to update yet to make logging, user fonts, and a few other quality of life things a reality but those should go quick.

Which then….the second half of why I’m not working on this is that my track car (the blue mustang) spun a bearing last weekend, so I’m also currently mid-rebuild on the motor to see if I can sneak in the last few track days of the year yet. Just got everything out and off to the machine shop it goes.

FOR REAL THOUGH, the L9780 is pulling me back in since you’ve been making progress on it. I actually cleared a portion of my test bench off to poke at it when I get time again.

Wow! You really do have your hands full at the moment. But just imagine if the L9780 was working at just added to that portfolio of excellence :slight_smile: Hahahah!

Im away from the desk for the next few days, but hopefully will have another crack at trying to solve this jigsaw later in the week. Im stubborn but this one is testing my patience.

I wonder how **mtw48726 got on with there work and if he could give some direction regarding what the RCIMP values should look like.
**

Hi,
I have already finished the L9780 part of my project several months ago and have driven about 3,000 km’s with the board on my car, as daily commute and longer trips, finding the only issue with my narrowband simulation method that I’ve already resolved. I have collected lots of logs from CAN bus that prove the board is working fine, and I have successfully compared my board with MoTeC Lambda to CAN at the same time - the relative differences in logs were under 3%, which can result mostly from the method of comparison.

I have never encountered the issues you mentioned (regarding the POR condition of L9780 etc.), resets of MCU while debugging result in full reinit in my software (sending the initial control word, starting the ramp and the PID and so on). The L9780 as an SPI device performs absolutely fine, though initially when developing the SPI driver I messed up with the REG bit and read garbage initially, what was hard to debug.

I can guide you but won’t reveal any important information regarding my design as this will be a commercial product.

Your RCIMP values are OK, I had one value about ~250 and the other also about ~800 without heating, I can check it in a few days because the board is currently mounted in the car and the newer revision isn’t fully assembled yet.

Congratulations! That’s a fantastic achievement, especially with the amount of real-world mileage you’ve already logged.

I completely understand why most people working with this sensor are protective of their designs—it makes sense when there’s commercial value involved. My own interest is less about producing a commercial product and more about learning, tinkering, and sharing the process with others who enjoy experimenting. I’ll probably be much slower to reach a complete working setup, so you’ll have plenty of time to capitalize on your head start in the market.

For now, I’ll just keep grinding away — but if I do hit a brick wall, I’ll be sure to rattle your cage.

Well after being inspired by our friend who is already so advanced i put in some time today to nut through the numbers on the CIMP1 and CIMP2. I did slightly deviate from the Bosch equations and so far im pretty happy with the outcomes.

I have yet to do any PID control but im sure this graph will help others trying to work out what they are looking for. I think i turned off my logging at the the point where my impedance had stabilised at 313.7Ohms which is bang on where the LSU4.9 should reside.

Nice! Did you figure out why you weren’t seeing a change in RCIMP(1/2) previously?

Also, using the equation I have I and the two values in your above screenshot I get 313.6Ohms for R,cell. Also from seeing the values, confirms that “ADC,i” in the setup memo corresponds to RCIMP1. I had suspected as much but just hadn’t gotten there yet to confirm.

Just in case it got lost, what I’m using for an equation is:

Those various values on the application circuit correspond to:

R1 = RRCT21
R2 = RRCT22
Rt = RRCT1
R,ds_on = 9.5 ohm (can simplify to 9 ohm, see below)
ADC,i = RCIMP1
ADC,f = RCIMP2

For "Rds_on", it's defined as “on-resistance of test switch”. This appears on the “inboard” side of pin RCT1 and is related to a set of FETs that either tie RCT1 to VCD or ground. Per the datasheet, this is then either RCT1 connecting to ground through the “RCT1 switch” OR RCT1 connecting to the band-gap voltage through the “RCT1 band-gap switch”. Looking at the min/max values for these on the data sheet:
RCT1,sw is 4 to 16 ohms
RCT1,bg,sw is 2 to 16 ohm

The nominal (average) value for these would be 9 Ohms(RCT1,sw) and 10 ohms(RCT1,sw,bg). With that in mind, I did just an initial sensitivity before any "real" values were calculated. Using the R,cell equation above it looks like just an arbitrary value of ADC,i = 740 and ADC,f = 450 and R,t = 9.5 would result in a calculated R,cell of 300.9 (*about the target desired range).

Just as a guess, I wanted to see what the potential min/max rang on this could be, adjusting for the bg,sw values since that appears to be bounding (largest swing).
For R,ds_on = 2ohm, R,cell = 295.7
For R,ds_on = 16ohm, R,cell = 305.3

Based on the above then, there’s about a +/- 5 ohm range on R,cell from the min to max range from nominal. It also looks like just using 9ohm (instead of 9.5) would be sufficient, as it's only changing the calcualted R,cell by 800mOhm.

From my understanding, R,cell temperature is pretty critical in terms of how the sensor scales for lambda but I'm not sure how sensitive that necesarily is. There is the benefit though of around this particular area of the R,cell vs Temperature graph in the LSU4.9 datasheet, it looks like there shouldn’t be a whole lot of deviation in that range. There will be some, but I think since the R,cell measurement is really only needed to control the “ideal” operating temperature, using the 9.5 ohm “nominal” value averaged between the two R,ds_on values should be appropriate.

Deviation of RCell in small range e.g. 290 - 310 ohm does not change the sensor results, the resistance-temperature curve is nonlinear and in the desired resistance range a deviation of e.g. 50 ohms equals to about ~20 degrees of temperature difference. Totally negligible, so you can assume 9 ohms.

I was looking at parts of your code from #33 - remember to implement a proper anti-windup of the integrator part of your regulator, as without it, the output will quickly become saturated.

1 Like

That’s some great feedback, thanks. I assumed that it wasn’t going to be that sensitive around the operating range but it’s good to get confirmation.

Also funny you should mention the PID control; I haven’t re-visited that code from the initial stab but your comment is EXACTLY what I ran into with a second project with a motor-controller I worked on later.

Also as a follow-up to that (the heater PID control) one way to simplify things is that we really don’t care about the “actual” R,cell value. I mean, we do, but that can easily be inferred from RCIMP2. Setting the target RCIMP2 value would skip over all the repeated calculation that’s not really necessary.

EDIT:
The extended thought here was that even with different sensors and particularly different reference voltages, the impedance measurements should be relative. The only issue i can see though is that because they’re relative to each other, the measured RCIMP2 value may still change enough to not be a good target (IE, different sensor with a higher/lower system voltage may be a different value).

The initial thought was that the math is simpler, doesn’t need large variables, and would be quicker. For now, I think the way to go is still calculating the actual value and then using that for the target but maybe with some extended testing in the future simply using RCIMP2 may be valid.

Both RCIMP values change while heating the sensor, I suggest not to neglect any of them, as the physical property of the object (the cell) that needs to be regulated is the resistance, so the regulator should have resistance at its input. Without RCIMP1 you do not really have the proper impedance value - it can vary between sensors.

The calculations are simple. After all, L9780’s measurement period is 10 ms - that is loooots of time for a mcu, so probably not worth it at all as you will perform it inbetween measurements. If you encounter a bottleneck I would suggest not using floats but some sort of fixed point math or switching to modern microcontroller, but probably the calculation will perform totally OK. Inertia of a heater (control theory kicks in) is high enough that you will be fine with period of your PID control in the range of several dozen, or even several hundred milliseconds.

How is everyone?… i have been distracted by life and made no progress after our efforts recently.