View Single Post
Old 12-14-2016, 12:52 AM   #39 (permalink)
t vago
MPGuino Supporter
t vago's Avatar
Join Date: Oct 2010
Location: Cedar Rapids, IA
Posts: 1,766

The Karen-Mobile - '05 Dodge Magnum SXT
Team Dodge
90 day: 26.72 mpg (US)

Fiat Dakota - '00 Dodge Dakota SLT RWD Quad Cab
90 day: 16.67 mpg (US)

The Red Sled - '01 Dodge Durango SLT 4WD
90 day: 16.96 mpg (US)
Thanks: 799
Thanked 682 Times in 437 Posts
Originally Posted by skybolt View Post
Well, then there's no reason to change the loop time. I knew you took out the delay, but I assumed you used the timer to pause execution of the loop ... I never bothered to look. Based on your statement, the main loop is obviously able to repeat very quickly (some multiple of clock speed, of course).
You are correct, in a sense. The main loop is very much dependent on the system timer, but not in the usual sense.

This is what actually happens:
  1. The main loop senses that the loop time count has expired
  2. The main loop then tells the timer to start another loop time count
  3. The main loop then disables interrupts and performs a transfer of trip data from the raw trip index to the instant trip index. It will then re-enable interrupts in order to continue to read injector events and VSS events and keypresses.
  4. The main loop then processes all remaining trip indexes from the instant index. This is the index that has a period equal to the loop time. Change the loop to 4x a second, the loop time goes to 250 ms. It's normally at 500 ms.
  5. The main loop then performs any display screen updating. This is also when the outputJSON routine is called.
  6. Any other housekeeping is performed at this time.
  7. The main loop will then just sit there and wait for the loop time count to expire. The process then begins all over again.

If the main loop detects a keypress, it will immediately stop waiting for the loop time count to expire, and it will immediately execute the related keypress. This may cause the display screen to update instantaneously, but no trip indexes will be touched.

The instant trip index is somewhat misnamed. It is actually an average trip index, but averaged only over a period of the loop time. To our eyes, it's pretty much instantaneous.

The only time the instant trip index might have a period greater than the loop time, is when either the display output, JSON output, logging output, debugging output (if enabled), or housekeeping functions take longer than the loop time. There is no danger to recording the data itself, as the MPGuino code will still accurately gather injector event and VSS event data, and will still generate reliable current trip, tank trip, and other trip functionality. It just might display instant trip functions in a somewhat peculiar manner.

Originally Posted by skybolt View Post
Under the old code, the acceleration time was checked once per loop, during the doDisplay event which in turn called drag::Update. So, a user could hit 30 mph at, say 2.100 seconds, but checking for the condition could be delayed up to the length of looptime, in this case it could read 2.3499.
Yah, that was one of the first things I noticed with the existing 0.86 MPGuino code, and one of the first things I canned by having the system timer take care of doing timing and having the main loop just poll a status flag to see if the loop had completed. It also allowed instantaneous keypress response as described above.

The next thing I did was to have the main loop truly become the main loop. The 0.86 code shifted to a secondary "main" loop whenever a parameter was being cycled for editing, and then went to a third "main" loop whenever the parameter was actually being edited. Trip data was not gathered during the execution of these loops. This would also result in strange readings once the code execution returned to the main loop.

My code, in contrast, always transfers trip index data per loop, even if parameters are being edited. I am in fact thinking about making the parameter edit section a bit more user friendly by allowing the display and editing of numbers that should have a decimal point in them. They currently show up as "(whatever)*1000" in the parameter edit section.

Originally Posted by skybolt View Post
To improve accuracy I skipped the delay if drag_running or drag_waiting was true. This could drop the looptime to at most 110ms, or if I'd never called the LCD display routine, 7ms.

This caused its own problem!! Mainly, while waiting to start loop time is between 7 and 110ms. The engine is idling at 1200 rpm or 20 rps, or every 50ms. Our #1 injector fires once every other revolution, or once every 100ms. Also, our injector is open for a very short time, has a 500microsecond "settle" time -- long way of saying rpm flashes to 0 when we have a loop without an injector fire, and higher when we have two fires per loop. This also throws of calculation of instant mpg. It doesn't hurt current/tank mpg since those are based on total distance/fuel ticks, all of which remain accurate - but the displays jump around. Based on my empirical testing, anything below 2300 rpm would show this behavior -- so I started working on logic similar to Flip to EOC data when stopped - after 6 or so loops, basically saying "don't return 0 rpm unless 0 rpm has been reported N number of times.
That makes sense now.

Originally Posted by skybolt View Post
The RPM buffer is to solve a problem that no longer exists as long as acceleration times are accurate to within .001, or actually accurate to looptime, which I'm guessing is greater than .001 second.
For acceleration testing, I have created 4 separate trip variables, and they all operate independently of the main loop. The first trip variable records the 0-30 MPH portion, the second records the 0-60 MPH portion, the third trip variable records the 1/4 mile portion, and the fourth trip variable records the true instant speed when the vehicle has traveled 1/4 mile.

The first three trip variables can be treated exactly as the current or tank trip variables. You can get the total period, which corresponds to either 0-30 time, 0-60 time, or 1/4 mile time. You can get total fuel consumed for each of these trips, as well as average speed, distance traveled, average engine speed, fuel economy, fuel consumed, fuel consumption rate, and so on.

The fourth trip variable is special, as it actually does capture the instantaneous vehicle speed when the 1/4 mile marker is reached. This is defined as a single vehicle pulse, its corresponding VSS pulse period measurement corresponds to the number of timer2 ticks per pulse. For 75 MPH using 10000 pulses per mile, this VSS pulse period value would be 1200, and for about 128.6 MPH, this value would be 700. For 119.36 MPH, this would be 754.

Differing values of pulses/mile will change the VSS pulse period value, but you should not see any problem.

All of these acceleration test trip variables operate completely independent of the loop time. All the accel test data is gathered in the background, and as long as the main loop does not disable interrupts for too long (say, for 100 microseconds), then the accel test data will not be corrupted. That's to ensure that consecutive vehicle speed pulses and injector event pulses are correctly captured.
The Fiat Dakota

The Karen-mobile

The Red Sled
  Reply With Quote