1 2 3 4
Keith Tanner
Keith Tanner MegaDork
7/30/21 12:54 p.m.

You guys are thinking that surprise WOT will be a dramatic thing in this vehicle :) It will be mostly noticeable by increased noise at first.

The linear mapping I'm working off is angle of butterfly to voltage output. The butterfly moves through 90* (ish), so 45* would be 50% throttle. From an airflow perspective, that's not true. But it's how most cable operated throttles work so it's familiar - move the pedal halfway, open the butterfly 45*. I'm okay with my system working that way. I'm familiar with the "torque request" concept but this throttle is attached to an engine being run by a 1996 computer so it doesn't have a lot of options at its disposal for affecting torque!

I'll put a little bit of fudgeability into the system - as long as the two TPS signals are within a small error range of each other, continue as planned. If there's a big discrepancy, cut the power to the servo motor and the butterfly closes. Same with the pedal, if those two sensors are giving inconsistent numbers go into an error mode. I'll also need some sort of error correction to make sure the requested throttle position matches the TPS, I'm thinking some sort of short term trim might be worthwhile.

Hopefully this weekend I'll have it working on the bench so I can play. Currently the biggest hassle is the strength of the spring on the pedal, I'm going to have to bolt it to the bench or something.

Keith Tanner
Keith Tanner MegaDork
7/30/21 12:55 p.m.

The really fun easter egg would be to invert the pedal behavior on boot once in a while. What would it be like driving a car where depressing the throttle pedal actually throttled the engine instead of unthrottling?

Keith Tanner
Keith Tanner MegaDork
8/11/21 10:31 p.m.

So, had to set this aside for a while so I could go to Deal's Gap for some Miata thing and other general life stuff.

But I did get it on the bench to check out the throttle body. I was going to control that via a motor control hat for the Feather, but realized all I really needed was a MOSFET (aka metal–oxide–semiconductor field-effect transistor, basically, a super-fast solid state relay) and a PWM control. The PWM lets me pulse the 3.3v signal as fast as I want - I'm using a fairly slow 500 Hz as noted in the factory manual - and it pulses the 12v power to the servo for me. My oscilloscope says it's not perfectly clean but hey, it'll work.

I set it up so I could control the PWM duty cycle by typing in commands, then added a rotary encoder (knob that spins) so I could just dial it up and down.

Wherein I discovered some weirdness. It takes more power (aka a higher duty cycle) to open the butterfly than it does to hold it. So instead of (say) 50% duty cycle meaning it opens to 50%, it has three basic states: enough power to open more, about right to hold the current position, and lower power to let the spring suck it closed. In other words, it works more like a car where you add power to accelerate and find the right power to maintain speed :)

So, new plan. We're going closed loop. Here's some pseudo-code:

  • check the current TPS reading (averaging the two signals)
  • check for commanded throttle position 
  • if they are the same, use the "neutral" duty cycle so the butterfly doesn't move
  • if commanded is bigger than TPS, use a higher duty cycle. The bigger the difference, the higher the duty cycle to make it move faster
  • same for lower
  • goto 10

The actual calculation is pretty simple, it's only 5 lines of code and 40% of that is limiting the duty cycle to run between 0 and 100% so I don't accidentally request an invalid number.

Now I can twist the knob and watch the butterfly open and close. Success! I do have to add some error checking to make sure the two TPS readouts are close, right now if one drops out the calculated average will be half of the real TPS so the car will go WOT to trying to bring it up. Not a good failure mode.

Next step is to add the real throttle pedal. This shouldn't be too difficult. In that case, a failed position sensor will read as half the actual throttle request so that's pretty workable.

...and then I was playing with how it behaved at or above 100% requested throttle (an artifact of the way I was controlling it) and I torched a MOSFET. The TB pulls about 1A most of the time but when I've got it pinned, it'll start to suck down 5 and I can hear my power supply start to work hard. I need to work around that. The MOSFET is supposed to be good up to 30A but I think I might have overheated it. They're cheap so I'll keep playing.

Addicted New Reader
8/12/21 6:55 a.m.

Not sure if its of interest, but I use a stepper controlled butterfly valve from a Supercharged Toyota MR2 as boost controller on my VW G60 engine. I take a signal from the throttle body mounted TPS and read it with an Arduino, a simple piece of code then converts that to a step count (position) for the Toyota stepper motor, output from the Arduino then feeds into a Stepper Motor Controller that then tells the Toyota Stepper motor where the valve needs to be. It was subsequently updated as I added a second potentiometer to the Toyota valve to give real time feedback on the valves 'actual' location. That Toyota valve is effectively just a small DBW throttle body...

It would be very cheap to bench test as an Arduino and Stepper Motor Controller are going to be less than $50


Edit: somehow missed your last post... its pretty much what you've already done/doing...

APEowner SuperDork
8/12/21 8:02 a.m.

Great progress Keith.  You probably know this but the max current rating of most MOSFETS is with the junction temperature held at 25 degrees C which can require a pretty significant heat sink.

Keith Tanner
Keith Tanner MegaDork
8/12/21 8:22 a.m.

I did not know that but it makes perfect sense. I was well within the rating of the MOSFET but it was definitely well over 25C. Heck, it was over 25C in the garage. I'll put an infrared camera on it and see if the heat rise is due to that 100% duty cycle with the butterfly pinned open - that's when the current draw spiked up - or if it's just from use over time. That may become a critical factor, as it's going to have to operate for hours at a time in a non-air-conditioned vehicle in the desert.

Keith Tanner
Keith Tanner MegaDork
1/9/22 2:47 a.m.

Hey, remember this? I got around to working on it again.

After talking to a friend who is smrter than I in this sort of thing (and who happens to have an LS3 Miata and my old Locost, so he is One Of Us), we decided that the heat sinks on my little MOSFET were way too small. Actually, there weren't any. I played around for a while and was worried about how quickly they were heating. He says they should run forever at 85C but given the speed of the temperature rise that seemed an unlikely goal. Even after I fixed the quirk of the programming that pinned the throttle body motor and pulled down big current numbers, I wasn't comfortable with what this meant for the long term.

I decided on his suggestion to change out my MOSFET for an H bridge. Basically, a DC motor controller. I happened to have an L298N sitting around. It's rated for 2A of continuous draw and the highest I've seen on my power supply has been a spike to about 1.1A with normal operation at less than half that. It's also got a big fat heat sink on it. Sure, it costs nearly $3 instead of $1.50, but darn the expense. I'm worth it.

Wired it in, it worked nicely right away. I spent some time just blipping the throttle and nothing awry seemed to happen. The heat sink warmed up but not much.

So then it was time to adapt the pedal. The fact that the TPS and the throttle pedal sensors work exactly the same way made this a really fast integration. I'd been controlling the throttle with a little knob up to this point and it had been a little jerky, but once I was using an actual spring-loaded pedal things smoothed out. Probably because I couldn't spike the requested throttle position quite so quickly.

Polished up the code a little more and added in some error correction. Here's how it all works now:

  • controller checks the primary position sensor on the throttle pedal (I'm measuring it as 0-100)
  • controller checks the secondary position sensor on the throttle pedal
  • if the two readings are more than 5 points apart, it declares a state of emergency and closes the throttle. This number is not set in stone yet but I haven't seen variance of more than 2-3 points in brief logging. Really, the most likely error will be for one sensor to read 0 while the other one is in a normal position so I can probably open that up a bit.
  • if the sensors agree (within the allowed variance), it takes the average of the two of them and this is now our commanded throttle position
  • it checks the position of the throttle plate using the same two-sensor technique and with the same error check
  • it then changes the PWM duty cycle to move the throttle plate. The further it is from the commanded position, the bigger the change it makes. 
  • do it all over again

I can adjust the aggressiveness of how hard it accelerates the throttle plate, it basically works out like a damper. If the damping is too high, the plate lags. If it's too low, it can overshoot and it's jittery. Playing around has let me dial in a setting that looks good on the bench, with the throttle plate moving snappily but accurately in response to the pedal. It turns out that getting this right also minimizes the power usage. 

I've tested the error checking by pulling sensor wires when "driving" and it immediately goes to a closed throttle situation. So that's good. 

One thing I noticed is that the throttle body can open the plate more than 90 degrees. I'm not sure why, but I have it set up so that 100% commanded throttle is with the plate perpendicular to airflow. This seems like a good idea.

So yay! It's working. I think the next step is to build a version that's a little more robustly assembled and come up with a test rig so I can have it run overnight. I also have to start thinking about the idle control question as well - my preferred option there is still to integrate the factory IAC signals into my throttle plate commanded opening. There will be some on-vehicle experimentation to dial that in, but this van has always had occasional idle problems and so it's quite probable it will come out of this much happier.

No video, but here's the current functioning setup.

Pete. (l33t FS)
Pete. (l33t FS) MegaDork
1/9/22 8:37 a.m.

Is it too late to point out that GM is one of the lone companies that does not have an accelerator position scheme where the two sensor outputs always add up to 5v?  Noooo, they have to have two different scales for whatever weird GM reason.

cyow5 Reader
1/9/22 11:01 a.m.

Just now saw this thread, and I did DBW software for a few years professionally. Did you mean to say you are varying the *duty cycle* when you said PWM frequency? If you really are using using frequency to control position, that's not good. Just set it at 1kHz and then vary duty cycle to change torque. It also doesn't sound like you are using a PID controller; am I reading that right? For the "damper effect", a low-pass filter is usually used, although that is not necessary at all. I prefer it to simply do what I asked. If I want a smoother response, I just give a smoother input. This way you don't have more electrons thinking for you than you have to. 


And yes, they tend to open beyond 100%. For calibration, guys would make machined blocks that limit the throttle to some position (100% is rarely actually makes best power since some 'turning vane' effect is usually helpful). Then you trigger a calibration mode where the TB goes full stop in both directions and records those voltages as 0% and 100% and interpolates between them. Then remove the block, and voilla, it goes to whatever max you set it as. Of course you can also let it go beyond 100% each time and then just map to whatever max you want, too. 

Keith Tanner
Keith Tanner MegaDork
1/9/22 12:08 p.m.

Thanks for chiming in! You're right, I'm changing the duty cycle. Frequency is set at the 500 Hz specified in the manual. Serves me right for doing write ups after midnight, so I'll correct the post :) I'm not using a PID controller but I suspect I might be trying to achieve the same things. That's not an area with which I am familiar.

The damper is basically an offshoot of the fact I need to put a scaling factor into the equation to get the duty cycle numbers into the right range. I found that this scaling factor had some effect on how the throttle behaved on fast movement - too much and the butterfly would overshoot, too little and it lags.

I did the calibration manually for 0 and 100. I'm wondering about a startup self-calibration routine like the ND Miata does. You can hear those sweep through the range on boot. I'm not sure if they're using a stepper or not, but it might be worthwhile for my setup. Still, being a stand alone throttle control, absolute accuracy isn't critical. I'm not trying to integrate cam timing and all the folderol that modern ICE power plants need to meet emissions targets. 

At the moment, I'm defining my maximum throttle plate position in code and then scaling the movement. I think it's set to 85% to be perpendicular. I can easily play with that, and I'll look at the angle of the old cable throttle on the stop. That's probably a good guide for where I want to be. 

Keith Tanner
Keith Tanner MegaDork
1/9/22 12:09 p.m.
Pete. (l33t FS) said:

Is it too late to point out that GM is one of the lone companies that does not have an accelerator position scheme where the two sensor outputs always add up to 5v?  Noooo, they have to have two different scales for whatever weird GM reason.

The Subraru sensors are duplicates. Same range, same direction. I know you can use a repinned Mazda pedal with a GM controller, so those two apparently use the same strategy to each other as well.

Keith Tanner
Keith Tanner MegaDork
1/9/22 2:06 p.m.

Veedeo! Here's some basic operation. Note that while I am happy talking in front of a camera, it's really weird talking behind it. So you get the uncomfortable silence.


A check of the fault sensing. I hold the pedal partway open with a clamp and then "break" a wire.


clshore Reader
1/9/22 2:13 p.m.

In reply to Keith Tanner :

Never realized that you were a fellow electron jockey/bit twiddler.
Nice Work!

Years ago I was tasked with designing a Crystal Controlled Variable Frequency Synthesizer containing a Phase Locked Loop for ground based aircraft navigation DME units.
The Reference and Output phase difference ran a Voltage controlled oscillator and locked it.
Had to apply a damping filter to prevent overshoot when switching frequencies, and damping factor was critical to prevent overshoot, while meeting FAA frequency stability specs.

Was all hardware back then, I'd do it in software today.

cyow5 Reader
1/9/22 2:46 p.m.

I'm not aware of any production DBW that use a stepper motor, so the Miata is probably just like what you have here. Autocal routines are fun though; I had one that could detect if you wired in the motor and/or the sensor power wires backwards, correct the error with software, adn then run with it. That was a fun project. 

You're probably more familiar with PID controllers than you realize. The short-term fuel trim in closed-loop control is just the P, and the long-term trim is the I. The D is the wall-wetting model if you have one. The base table is just pre-control. The analogy I like for non-car people is setting your temperature for a shower. You already know roughly where you want the handle, so that's your pre-control. "P" is when you move the handle proportionate to how far off the temperature is. If it is way too cold, you move it far. If it is barely too cold, you barely move it. I is the sum(error), so after awhile you start nudging the temperature because you noticed it was close but not close enough. D is when you hold back a little from cranking the temperature full hot because you know there's thermal inertia, so you start moving towards "cold" as you feel it warm up if it is warming up too quickly. 

I'd set it up with a true PID control without any complexities, and set the damper so it is least-invasive. Re-reading your posts, it sounds like you *are* using a P term already.  Oh, and add a failsafe that sees if it fails to reach the desired angle. If something has failed or blocked the throttle, you want to stop the party right away, so kill it if some error exists for more than some time. 

That all being said, it looks like it is running great as it is! I'm even surprised how quietly it is running at 500Hz. Normally, that's pretty noisy. 


Keith Tanner
Keith Tanner MegaDork
1/9/22 3:12 p.m.

The damper is the P factor, from the sounds of it. I'm just (as usual) using the wrong terms for things as I figure them out for myself.

It's become quieter as I fine-tune the code. I'm taking that as a good sign, as it means it's hitting the target more accurately.

Good point on the time error. That will be interesting to try to figure out with the bit of noise in the inputs. 

cyow5 Reader
1/9/22 3:27 p.m.

No, the damper is just a filter for changing the duty cycle. The P term is when you mentioned earlier that you change the duty cycle proportional to the error (hence the P name). Since you have good response already with just the P term, you probably don't need a D, or at least it won't be strong if you set one up. The I though will come in handy. As the grease in the gears warms up, it will settle at a different position than it does when cold, and even a weak I will help get you to the target each time. 

also, make sure the fueling is based off of the throttle position and not the pedal. Not sure which you were planning. 

Keith Tanner
Keith Tanner MegaDork
1/9/22 3:42 p.m.

My "damper" is the scaling factor of P. If that value is too large, it reacts too aggressively to error. The calculation is (pseudo code)

new duty cycle = base duty cycle + (difference between commanded and actual TPS reading) x damper

where the base duty cycle is the "neutral" number where the motor torque is balancing the return spring.

I suspect fueling is completely via MAF without TPS input, but I do have to check that. It's a 1996 era ECM. If I have to feed TPS back into the ECM I'll do that. The idea is to keep the ECM as ignorant of this thing as possible, I'm really just trying to replace a throttle cable with wiring and not actually affect the engine management.

Keith Tanner
Keith Tanner MegaDork
1/9/22 3:49 p.m.

Oooo, good thing you asked. Looks like there is a single 0-5v (ish) TPS signal going to the PCM. I'll have to supply that. Easy enough.

cyow5 Reader
1/9/22 3:50 p.m.

There's no way it is MAF only since that measurement is terribly dirty and laggy.  so you'll want to emulate the stock TPS signal if it is different from either of your current TPS. 

gotcha, I misunderstood what the damper was doing then. The thing to remember when doing just a P controller with no I is that there is no output duty cycle without *some* error. Since there is a spring driving against the throttle blade, the only way to hold a position is with some error. Given the age of the vehicle and the tech, this is probably going to be fine, but something to consider. 

Keith Tanner
Keith Tanner MegaDork
1/9/22 3:55 p.m.

I spend a lot of time with early Miatas that don't have a TPS, so that's why I assume that it could be just the air measurement. But they use an air flow meter instead of a MAF and they're the cream of late 80's programming. Regardless, it does use it so thanks for making me look.

pseudo code for the duty cycle calculation added to my previous post.

I have done some testing where the controller reports that commanded TPS = target TPS and it's surprisingly frequent. So the error doesn't seem to be bad. There's no visible flutter in the plate at a constant pedal position so that looks promising.

cyow5 Reader
1/9/22 4:23 p.m.

Yeah, a flow meter makes for a straightforward analogy to a carburetor, so early fuel injection was basically trying to just emulate a carb. I don't have much experience with older stuff, so what I expect on modern cars may very well be way different from old stuff, so some of my assumptions might suck. 

since you are using a rate limit (damper), you are getting away with a much stronger P gain. This will certainly reduce your steady state error at the expense of outright speed. There still must be some error, it's just too small to care about. That's why I said to just keep that in mind when it gets into the real world since the bench parameters might need to be tweaked. 

Keith Tanner
Keith Tanner MegaDork
1/9/22 4:45 p.m.

Given the nature of this engine, response is not the most critical factor here :)

Thanks for all the questions and explanation and help. I appreciate it. 

Keith Tanner
Keith Tanner MegaDork
1/9/22 5:33 p.m.

Oh boy, I just won't shut up :)

I checked on my surplus cable-operated throttle body from a 1998 Subaru, and at the hard stop the throttle plate is completely perpendicular to the airflow.

The idle air control valve is disappointingly poorly documented in the factory manual. For a 1997, it has two wires identifed as OPEN end and CLOSE end, and they see a 1-13v signal that's just identified as "waveform". Gotta be PWM. Some probing is ahead.

cyow5 Reader
1/9/22 6:32 p.m.

Idle control with DBW is a whole other beast. Air flow is controlled by the throttle, but this is slow. Fast response is done by spark angle basically the pre control and p term) and slow response (I term) is by throttle angle. To emulate that, you'll need rpm as an input at the very least. Finding a way to bypass the throttle with the original IAV will probably be the best bet. You could probably do this by just hooking up a couple vacuum lines to stock IAV and putting one line ahead of the throttle and the other after it. 

Keith Tanner
Keith Tanner MegaDork
1/9/22 6:38 p.m.

Yes, that's an alternative I've considered. I did that with a four-throttle Miata in the past. It would certainly be simpler as long as the plumbing works. I'll have to take a look. As I may have mentioned, the vehicle has enough idle oddities that it's possible the IAV is gummed up or otherwise inop - which also means that any idle air control would be an improvement :)

1 2 3 4
Our Preferred Partners