Fuel Economy and Smoothness without Compromise

Yamaha FJR Motorcycle Forum

Help Support Yamaha FJR Motorcycle Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
The PCIII could also take advantage of this, but you need to purchase the expensive LCD screen add-on to be able to store and switch between 2 maps. The difference is that it would be an abrupt change to the cruising map.
Close but no cigar. The expensive LCD display is not needed .. but a hub and switch is. I think I paid about $120 for that.
That's much better than requiring that ugly LCD screen, but still very expensive compared to the option on the PCV to just hook up a switch.

The switching between maps is immediate, but I haven't noticed anything abrupt about it.
Good to know. There will technically be an abrupt change in fuel delivery when switching the maps, but it probably doesn't really matter if it doesn't cause anything noticeable to the rider. My concern with the automated switching is that it might cause an abrupt small change in power delivery that would cause the rider to (maybe even subconsciously) react with an abrupt small change in throttle position, which could trigger my device to switch back out of cruising mode. It's something I could definitely work around with software changes, but it would be much easier if it's not a problem to begin with.

 
The PCIII could also take advantage of this, but you need to purchase the expensive LCD screen add-on to be able to store and switch between 2 maps. The difference is that it would be an abrupt change to the cruising map.
Close but no cigar. The expensive LCD display is not needed .. but a hub and switch is. I think I paid about $120 for that.
That's much better than requiring that ugly LCD screen, but still very expensive compared to the option on the PCV to just hook up a switch.
Had the PC5 been available when I bought the PC3+switch+hub I would have gone that route too - with the autotune and wideband O2 sensor. But for now .. I'm come to accept 38-40mpg.

The switching between maps is immediate, but I haven't noticed anything abrupt about it.
Good to know. There will technically be an abrupt change in fuel delivery when switching the maps, but it probably doesn't really matter if it doesn't cause anything noticeable to the rider. My concern with the automated switching is that it might cause an abrupt small change in power delivery that would cause the rider to (maybe even subconsciously) react with an abrupt small change in throttle position, which could trigger my device to switch back out of cruising mode. It's something I could definitely work around with software changes, but it would be much easier if it's not a problem to begin with.
It's not like I'm switching in the middle of a corner ... it's rare that I actually switch maps. But I hear what you're saying ... if you are automating the switch then don't want it to switch when relaxing between corners or when decelerating into one.

Keep us posted ... this is quite an interesting project. I'm waiting to see if you can get good economy without a lean-surge.

 
Installation complete!

:yahoo:

installed_top.jpg


installed_side.jpg


I might be able to wrap a couple of the wires with something to make it look cleaner, but it's hard to do with such short runs of wire that aren't all going to exactly the same place.

I had plenty of issues to work through...

Stupid crimp-on quick-disconnect space connectors pulled off the wires. It's a shame, because they were pretty nice waterproof connectors with pre-installed shrink tube. I just can't seem to crimp them tight enough so that the connection between male/female connectors comes apart rather than the connectors coming off the wires.

With hardware issues out of the way, it was time to start some basic testing/debugging. Here's my bike on life support:

debugging_on_bike.jpg


My Motty AFR Tuner is hooked up to the laptop to monitor the map switching, and my circuit board is hooked up so I can update its software, run it, pause it, check out calculated values in memory, etc. At this point, the engine was not running and I was just testing the sensitivity of the throttle and verifying that it would switch the maps.

The in-circuit debugging on this particular chip seems buggy and was throwing red herrings all over the place. Most annoyingly is that it seems to cause a digital input pin on the chip to stop working after the first time that I pause the program. It could just be that I'm not aware of a certain "gotcha" about microcontrollers, so I'll try to look into it more.

Then there were plenty of bugs in my code that were easy to find and fix once I determined the debugger was buggy was able to work around that.

I had a couple errands to run today, so I took the opportunity to do some test rides with data logging, then review the data log and tweak the code in between errands. It's not perfect yet (nor will it ever be, but I'll try to improve it), but it does seem to be mostly working now.

Here's some examples of the most recent data log.

data_log_mixture.png


That's a nice mixture of activity over a 1 minute period of time. Match the colored lines up with the colored labels on the right to see what's what. The top most line is the digital input value that triggers map switching. If it's high, then the fuel-wasting smoothness map is being used. Low means the fuel economy map is being used.

The rest of these are 30-second portions of time...

Taking off normally (0-40mph in about 13 seconds):

data_log_takeoff.png


Taking off slowly (0-40mph in 21 seconds):

data_log_gentle_takeoff.png


Cruising steadily, then slowing:

data_log_cruise_then_slow.png


Slowing, then accelerating back up to speed (slow traffic at a light that recently turned green):

data_log_slow_and_accel.png


Slowing, then accelerating through a corner:

data_log_cornering.png


Coming to a stop:

data_log_stop.png


On that last one, you can see a false detection of non-steady cruising before I start slowing. Still need to find out what causes that occasionally.

Well, there it is! I won't call it a success yet, but it's definitely looking good. It still needs some tweaking, then I need to lean out my economy map and see how it affects gas mileage and driveability. I'll share some more details about what exactly that little black box is doing, and some of the interesting problems I've had to solve, after I iron out some details.

 
Last edited by a moderator:
Coming to a stop:

data_log_stop.png


On that last one, you can see a false detection of non-steady cruising before I start slowing. Still need to find out what causes that occasionally.
I just double checked that part of the log and that actually was behaving properly. I currently jump out of cruising mode if there's a difference of 75+ RPMs over the past half second, and it just barely exceeded that limit where I thought it was misbehaving.

Here's a better example of it misbehaving:

data_log_oops.png


That's zoomed in a lot. I looked at the individual data entries for the half second leading up to that switch out of cruising mode. There's only a variation of 26 RPM and 0.1% throttle (my current throttle threshold is 4% over a half second, which I think I can drop quite a bit lower).

I think I need to come up with a way to easily log/view the exact data that my device is working with so that I can find what's causing this. Fortunately, it never happens in the other direction. I've never seen it switch to cruising mode when it shouldn't.

 
Still tweaking, but things are looking good. The rest of this post is a lot of technical details to give those who are interested some idea of just how complicated it is to answer the simple question: "am I steadily cruising?"

Some of my expectations were quite wrong. I expected that my RPM readings would be quite smooth/consistent so that I wouldn't have to worry about noise filtering or averaging much, and I expected that throttle readings would be noisy due to bumps, sneezes, nervous twitches, etc. It's quite the opposite in reality.

When cruising steadily, throttle is very steady. It varies by less than 0.5% over the course of 1/2 a second on smooth roads, and up to about 3% when dodging potholes, changing lanes, hitting bumps, etc. It often even stays within about 0.2% for several seconds at a time if the road is flat.

RPM readings fluctuate quite a bit, by up to about 16 RPM over the course of 1/2 a second when cruising perfectly steadily on a flat, smooth road. Rough spots, bumps, slight changes in throttle, etc. create more variation even, though you maintain the same steady speed. These fluctuations don't show up in my data logs, because they are too small to be visibly represented in the line, but they are large enough to be a problem to my calculations. I had to log raw readings from my device to EEPROM memory on the microcontroller, then copy that data to my computer and manually analyze it to get this info (and by manually, I mean with the help of a nice text editor with regular expression enabled search/replace, then quickly wrote some code to process the re-formatted data and get results in terms of RPM fluctuations, etc.)

It makes sense after thinking about it. I'm calculating RPM by precisely measuring (down to 1 millionth of a second) the time between pulses from the camshaft position sensor (1 pulse per 2 revolutions of the engine). Any slight variation in the timing between pulses results in a significant different in the calculated RPMs. The difference between 3000 RPM and 3010 RPM corresponds to a difference of only 0.000133 seconds between pulse timing. At higher RPMs, the difference is even smaller: 0.000048 seconds for 5000 - 5010 RPM. There's also quite a bit of slack in the drivetrain. Put your bike in gear on the center stand (engine off) and see how far you can move the rear tire. The drivetrain is not heavily loaded when steadily cruising at less-than-highway speeds, so any slight bump, dip, rise, etc. can cause the drivetrain to unload. The engine will now spin quicker for the next couple revolutions while eating up that slack. Or a bump/dip/rice could momentarily put more load on the drivetrain, causing the engine to spin slightly slower. It all happens so quickly that you perceive that you are steadily cruising, but the engine speed is jumping all over the place within a small RPM range between each individual rotation. An average RPM over several rotations would give a more meaningful representation of the speed of the motor.

So here's my problem... I want a fairly small threshold on how much the RPMs are allowed to change within a short amount of time to be considered "steady". The shorter the time, the more responsive it will be to changes, but threshold has to smaller and more easily falsely exceeded by normal RPM variations. If I look at RPM variations over a longer time, my threshold can be larger for the same limit on rate of change in RPM, so it will be less likely exceeded by normal variations, but it will be less responsive to changes. For example, if I sampled 10 seconds of data, I would have to accelerate above the allowed rate for up to 10 seconds before my device could detect that I'm accelerating too fast to be cruising.

And here's the overall approach I'm taking to determining which fuel map to use:

  • Every time a pulse comes from the camshaft sensor...
    Calculate an RPM reading based on the time that passed over the 5 previous pulses. This gives me the average RPM over the past 10 revolutions of the engine, which will smooth out some of the "normal" variations.
  • Store the RPM reading, so that it can be sampled later. All RPM readings since the last sampling are stored.

[*]Every 1/16th of a second (this is when all the sampling and decision work happens)...

  • Sample the current RPM. To do this, I average all of the calculated RPM readings that have happened since the last sampling. At any RPM above 1920, pulses will be occurring more frequently than 16 times a second. Rather than just going with the most recent reading, I calculate the average RPM over the previous 1/16 of a second. This also helps smooth out normal variations.
  • Sample the current throttle position. Throttle is simply an analog input (0-5v), but 0% throttle is above 0v and 100% throttle is below 5v, so I do have to convert it to a range of 0-100% based on calibrated end points.
  • Maintain a list of the 8 most recent throttle and RPM samples (that's 1/2 second of data).
  • Consider the bike to be "steady" if...
    All recent throttle positions are below 0.5% AND all recent RPM are below 1300 RPM (idling).
  • OR All recent throttle positions are above 0.5% AND all recent RPM are above 1300 RPM (not idling) AND all recent throttle positions are within 3.5% of each other AND all recent RPMs are within 80 RPM of each other.

[*]Some explanation of the "steady" conditions above...

  • The RPM varies even more when idling, because the engine is under no load. This is why I don't care about variations being within the thresholds as long as all readings are within the idling range.
  • The requirement that all readings must be above idling AND within thresholds results in instant response when starting to accelerate from a stop. As soon as the throttle exceeds 0.5% or the RPM exceeds 1300, it is considered not "steady", even if everything was within the steady thresholds. It also results in instant non-steady response when closing the throttle completely while slowing for a corner, no matter how gently you close the throttle.
  • The 80 RPM per 1/2 second threshold theoretically enforces a maximum acceleration as follows:
    1st gear: ~1.06 mph per second
  • 2st gear: ~1.60 mph per second
  • 3st gear: ~2.13 mph per second
  • 4st gear: ~2.56 mph per second
  • 5st gear: ~3.02 mph per second

[*]In lower gears, the RPM threshold will be more easily exceeded that the throttle threshold, because the bike can accelerate/decelerate more quickly with smaller changes in throttle.

[*]Likewise, in higher gears, the throttle threshold will more likely be exceeded before the RPM threshold.



[*]If the bike has been "steady" for the past 64 samplings (that's 4 seconds), then select the cruising map. Otherwise, select the smoothness/power map. This creates a waiting period before going into cruising mode. Note that it only takes one non-steady sampling period to switch from cruising to smoothness/power.

[*]Worst case scenario, it will take 1/2 second to respond to a throttle/RPM change that is just barely above the threshold and switch out of cruising mode.

[*]If you whack the throttle open or closed, or shift gears, it will switch out of cruising mode within 1/16 of a second.







Well, there you have it. Anyone still with me?

All the specifics mentioned above (number of pulse timings averaged together, number of samples considered against thresholds, threshold values, etc) are what I am currently tweaking to find a good balance between reliably staying in cruising mode when I'm actually cruising, and quickly switching out of cruising mode ASAP when I want it to. I'm placing more importance on quickly getting out of cruising mode. I bet vehicle manufactures probably place more importance on staying in cruising mode (closed-loop mode) until it is absolutely certain that the driver is no longer cruising, thanks to the EPA :)

My goal is to improve fuel mileage significantly without ever noticing that my bike is running leaner when I'm accelerating, cornering, or doing anything else where I need/want smooth throttle control. I don't care about some minor lean surging while steadily cruising. So far, I can say that the bike has been smooth whenever I expect it to be. In a few more days, I'll be able to report mileage on my first full tank of gas since I installed this. I hope it's good...

 
Pickles,

Maybe the reason that you are having such trouble with handling the rpm signal is because you are looking at it as units rather than as a percentage. 16 rpm variation at 3000 rpm is only a a 0.5% variation.

Interesting that you were seeing a .5% max variation in speed and a .5% variation in the throttle position.

 
Last edited by a moderator:
Pickles,

Maybe the reason that you are having such trouble with handling the rpm signal is because you are looking at it as units rather than as a percentage. 16 rpm variation at 3000 rpm is only a a 0.5% variation.

Interesting that you were seeing a .5% max variation in speed and a .5% variation in the throttle position.
Interesting coincidence, but I'm not sure it helps me much. When I had the threshold setup at 70 RPM per 1/2 second (2.3% of 3000 RPM), I should have theoretically be able to accelerate up to 1.87mph per second in 3rd gear and still be considered "steady". However, the fluctuations in the RPM readings were fairly often enough to kick me out of cruising mode (probably caused by larger bumps in the road, etc), even though my data log showed I was perfectly steady at 40mph in 3d gear. This was before I added some of the averaging to smooth out the fluctuations.

One difference is that any fluctuation in the throttle reading comes from actual movement of the throttle. On a smooth road, the throttle often stays perfectly steady for seconds at a time. RPMs are never steady, even on the smoothest of roads. For the RPMs, what I'm really trying to measure is acceleration. Unlike the throttle readings directly reflecting physical throttle position, the RPM readings do not directly reflect the overall acceleration of the bike, because the engine speed can vary from one revolution to the next while the bike maintains a steady speed.

The bigger difference is the way in which the throttle changes. When you intend to slow down or accelerate, the result is throttle changes that are quite abrupt. Open up the throttle to move out of someone's blind spot on the freeway, and you probably increased throttle by 15-20% within a quarter of a second. RPMs just can't change that quickly (unless you're revving it in neutral). The RPM threshold must be quite low to only allow slight acceleration/deceleration to be considered cruising, even if you are gradually changing the throttle.

Throttle also doesn't jump up and down between every reading. It moves steadily/continuously. It may change abruptly at times, but it almost always forms a continuous curve in the data. It's not noisy. RPM readings are always all over the place within a small range. Every reading is different than the previous. It looks like a jagged saw. It's definitely noise in the signal that needs to be smoothed/filtered.

 
Last edited by a moderator:
Interesting that you were seeing a .5% max variation in speed and a .5% variation in the throttle position.
Also, the 0.5% variation in RPM was under the most perfectly smooth conditions. As my previous post indicates, it would often exceed 2.3% variation when as far as I could tell, I was cruising perfectly stead, and there were no accompanying fluctuations in throttle. So it was probably a bump or slight slip that was enough to allow the RPM to change by over 2.3% for at least one revolution, but not enough to physically jostle me into twitching the throttle. The 3% throttle twitches require very noticeable bumps. Unfortunately, I don't have any raw RPM data to show just how much it can vary when hitting bumps/dips/etc.

Sorry if my initial report was misleading with data. The amount of info I have been considering over the past several days and the number of factors I have been tweaking is a bit overwhelming and difficult to fully summarize.

BTW - I can't trust the RPM data from my AFR Tuner data logs, because they are most likely already smoothed/filtered. I had to write some extra code to store raw RPM readings in my chip's on-board EEPROM. There's only enough room for about 8 seconds of RPM data, so I can't get a full picture of how the raw RPM readings fluctuate during a wide range of conditions. This is the reason for the lack of details stats about RPM fluctuations. I have been able to monitor throttle readings on my device while hooked up to the laptop and the engine was not running, so I know that the throttle readings are very consistent and smooth. I think it's safe to assume that the throttle in my data logs very closely, if not exactly, matches what my device is reading.

 
It's definitely noise in the signal that needs to be smoothed/filtered.
Gotcha. So it's more of an SNR problem on the RPM signal than an accuracy one. Filtering it would be easy, but not without a loss of temporal resolution.
Exactly.

SNR = Signal to Noise Ratio, for those of you that are too lazy too google it :)

 
Thanks for the update.

If you're looking for advice (I'm not sure if you are), I would suggest forgetting about,looking for variations in RPM to make it enter/exit cruise mode. If it is above idle and below around 6000 RPMs then allow it to enter cruise mode based on the other inputs. Just wondering, can you add engine load as an input? If so, umaybe you can use TPS and MAP changes to make it drop in/out of closed loop.

Joe

 
Last edited by a moderator:
If you're looking for advice (I'm not sure if you are)
Suggestions are always welcome :)

I would suggest forgetting about,looking for variations in RPM to make it enter/exit cruise mode. If it is above idle and below around 6000 RPMs then allow it to enter cruise mode based on the other inputs. Just wondering, can you add engine load as an input? If so, umaybe you can use TPS and MAP changes to make it drop in/out of closed loop.
Engine load might be some nice secondary info to use, but it's very complex to calculate with lots of pre-calculated lookup tables for temperature and volumetric efficiency corrections. There's no way I'd be able to come up with a correct engine load calculation.

Also, engine load is not my primary concern. I simply want to know if I'm cruising at a steady speed. If throttle or RPM are changing more than an amount expected during steady cruising, then I don't want to be in cruising mode. My goal is not to reproduce stock-like closed-loop functionality to meet EPA requirements. My goal is to have very smooth throttle, but save some fuel when I'm just cruising down the road.

If I ignore RPMs between idle and 6000 RPM, then there's no way I can know if the speed is relatively steady. I could only know that engine load is relatively steady, which might mean steady acceleration or deceleration. Load is probably more important for factory systems deciding when to be in closed-loop mode, because closed-loop mode means 14.7:1 AFR, which is a lean mixture that can only be used for low loads. I don't want a lean mixture in all low-load conditions. I only want it in steady cruising conditions. I also don't need to worry about considering load when deciding to switch to/from cruising mode. I can simply only configure my cruising AFR map to use a lean mixture at throttle/RPM combinations that are known to be steady cruising combinations (and therefore not high load).

 
This is very interesting. And without a doubt, if I have some seriously complicated computer / electronic stuff to figure out, Jeff is definitely the first person I’d call.

Here is how I have addressed the performance / MPG balancing act on my bike.

I am running at PC-V on my ’09. I have installed a switch that allows switching between two maps. I did not purchase / use the Dynojet switch; I used a standard rocker switch from RadioShack and some light gage wire. There is no voltage, just a open / closed switch.

It opens up two map positions, viewed when you plug in a laptop to the PC-V. Switching is instant – you can watch it do it while it’s running and plugged in.

What I chose to do is put a zero map in one position, and the hybrid smoothness map in the other. On my last trip, I ran the zero map on the highway and pulled an average of 45.4mpg. Once off the slab and into the twisty stuff, I averaged 36.4mpg. Slab riding included mostly +10 over posted limit running 70-75mph. Twisty stuff is better measured in average RPM, which was mostly between 5-8k rpm’s

I’ve thought about playing with the mapping by gear option. Typically, I don’t use 5th gear much in the twisty stuff, so I could take and change the 5th gear map to an all zero map to mimic the OEM fuel map.

Maybe, once I drag Jeff to SE Ohio this summer, fuel mileage will be the last thing on his mind…

 
Extreme

That's is how I am running my bike. I initially did in gear mapping, but found it would be easier to have two maps one zeroed(factory lean setting) and the other, an autotune built map for optimum throttle response and fuelling. I fitted a tiny toggle switch(rubber booted for weather protection) into the indicator block.

Works very well in deed

Andy

 
And now I'm thinking that noise in the RPM readings has not actually been my problem. Even with the new averaging code and a higher threshold, it still bumped me out of cruising mode a few times while cruising very steadily. Then after a quick full-throttle run up through the RPMs in 1st gear, it never went back into cruising mode again for the rest of the ride.

Now the real fun begins: determining whether it's a hardware or software problem :)

 
Here's a cool example of how the air:fuel ratio adjusts when switching in/out of cruising mode:

data_log_cruise_accel_with_afr.png


 
I'm pretty sure I found the cause of the occasional incorrect behavior. Two possible causes, actually.

First was a hardware problem: the connector I added into the wire that goes from my device to a button was not well-insulated and was within reach of part of the frame. That button simply makes a connection to ground, which signals my device to never go into cruising mode (as long as it is connected to ground). Occasional contact between that connector and the frame could explain the occasional dropping out of cruising mode while I'm very steadily cruising.

Second was a software problem that caused a used portion of memory to be overwritten every 11th rotation of the motor with data that shouldn't be there. Here's an abbreviated version of the offending code:

Code:
#define RPM_TIMER_SAMPLE_COUNT 5
uint32 rpm_timer_samples[RPM_TIMER_SAMPLE_COUNT];
uint8 rpm_timer_sample_index;
uint16 rpm_timer_sample_high_word;
uint8 rpm_samples_full; // not related to the "rpm_timer_samples", BTW
...

void record_rpm_timer_sample(uint32 sample) {
 rpm_timer_samples[rpm_timer_sample_index] = sample;

 if (++rpm_timer_sample_index > RPM_TIMER_SAMPLE_COUNT) {
   rpm_timer_sample_index = 0;
 } 

 ...
}
That "if (++rpm_timer_sample_index > RPM_TIMER_SAMPLE_COUNT)" needs to be "if (++rpm_timer_sample_index >= RPM_TIMER_SAMPLE_COUNT)" to work as expected. The bad code causes "rpm_timer_sample_index", "rpm_timer_sample_high_word" and "rpm_samples_full" to be overwritten with the "sample" value, which randomly potentially wreaks havok on other parts of my code, depending on exactly what values ended up in those variables. This happens because indexes into arrays are zero-based. In this case, the array has a size of 5, so its indexes are 0 through 4. The code above will write a value to index 5, which is the next 32 bits of memory AFTER the array, which happens to be those 3 variables.

It's amazing that this worked properly for most of the time!

 
Have to say you Da Man!

I have followed sorta what you are doing and the code aspect is above my head but interesting. I started in IT 20 odd years ago and my first job was a Unix based system QNX4. No GUI but I think they did go on to one in later versions? I had to learn KORN and BORN scripting and also leaned how powerful GREP is at a command line.

Syntax will bite your ass I know for sure, and variables in code is just daunting to me.

Looks to me as if you have made a significant find and may find others, who knows. I am rooting for you though, and I really enjoy stretching the brain reading your posts. The great thing is that the Forum and I will benefit even on our PC V as your fact findings will translate to a basic way the bike is behaving and have a cruise map and a power map.

I am very lax in my PC V tweaks because the bike seems to run fine on Dyno Jets TB pipe map, and being a new bike I am getting 40 MPG and I have to say the wrist has it own mind with only 2000 miles on the bike :)

Thank you for sharing.

 
Top