EcoModder.com

EcoModder.com (https://ecomodder.com/forum/)
-   OpenGauge / MPGuino FE computer (https://ecomodder.com/forum/opengauge-mpguino-fe-computer.html)
-   -   FalconFour's MPGuino mods (https://ecomodder.com/forum/showthread.php/falconfours-mpguino-mods-14752.html)

FalconFour 10-03-2010 06:51 AM

FalconFour's MPGuino mods
 
I think they deserve their own thread, although I think the bigger ones (like the ALDL one I plan once I get comfortable with Arduino coding) probably deserve their own thread...

Here's what I've been up to tonight, after getting my Arduino back from a friend ;)

Current list of "gee, wouldn't that be nice to have?" features on my todo list:
- Tank remaining gallons calculated by (tank size - tank gallons) * tank MPG (completed)
- Editor for tank values in memory, for restoring from a power outage from values recorded prior to unplugging (e.g. to recover from the setup menu CPU% timing bug) (still planning that one, LCD manipulation is tough)
- Smartass message/indicator for ultra low instant MPG, high instant MPH delta (flooring it)
- Real-time clock based on cycles, computed from memory value of "current time", set using "tank" method above (implemented, but unable to set the time at the moment due to lack of editor, so it always starts at 12am)

And more posts to follow for each mod, and the associated code.

FalconFour 10-03-2010 07:02 AM

Tank MPG is the easiest. Right now, for testing, it starts with a fixed value of 17.9999999 MPG to test rounding functions (I wasn't quite sure how the code worked yet, but I'm getting the hang of it now), but that value is discarded as soon as tank MPG moves away from 0.00. It calculates against the configured (but currently unused) tank capacity setting.

It uses its own "screen" which I currently call "F4 edit" due to all the comments I made in the code indicating where I patched it ("// ** F4 edit: blah blah"). The screen has both RemMiles and Time (clock).

Here's the code:
Put this somewhere around the screen routines. I put mine after doDisplaySystemInfo.
Code:

void doDisplayRem(void) {
  LCD::gotoXY(0,0);
  unsigned long remMPG = tank.mpg(); // may need to change this below
  unsigned long remMiles = parms[tankSizeIdx]; // final value
  if (remMPG < 50) remMPG = 17999; // if unreasonably low, make more reasonable
  LCD::print("Rem miles:");
  remMiles -= tank.gallons(); // subtract used gallons from total tank gallons
  remMiles *= remMPG; // multiply available gallons by tank mpg
  remMiles /= 1000; // since we multiplied two *1000 vals, knock down a notch
  LCD::print(format(remMiles));
  LCD::gotoXY(0,1);
  LCD::print("                ");
}

Add a new displayFuncName:
Code:

        displayFuncNames[x++] = PSTR("Rem tank miles ");
And add a new displayFuncs to the position where you added the displayFuncName (if at the top of the stack, add it to beginning of list; if at bottom, add to end):
Code:

doDisplayRem,
And that should pretty much be that. You can also use the computation above to add it to any other screen you want (custom is nice), but real estate there is limited. So if you want to replace Current MPG on the Custom screen, you could do this:
Code:

void doDisplayCustom() {
  unsigned long remMPG = tank.mpg(); // may need to change this below
  unsigned long remMiles = parms[tankSizeIdx]; // final value
  if (remMPG < 50) remMPG = 17999; // if unreasonably low, make more reasonable
  remMiles -= tank.gallons(); // subtract used gallons from total tank gallons
  remMiles *= remMPG; // multiply available gallons by tank mpg
  remMiles /= 1000; // since we multiplied two *1000 vals, knock down a notch
        displayTripCombo("MG","LK", instantmpg(), " S"," S",  instantmph(), "GH","LH",
                        instantgph(), "RM",  remMiles);
}

(I think. I haven't tried that... and I removed the metric functionality from mine, so I had to add that back above too.)

As they say... enjoy! ;)

FalconFour 10-03-2010 07:12 AM

1 Attachment(s)
And a fun one, if at least to see how far the MPGuino's interrupt-generated clock differs from reality (if "1.024 milliseconds, we will call that a millisecond for our purposes" is any indicator ;))... a clock.

It's not complete. The "values editor" has to first be created here in order to set the time on the clock. But it does count time, and it seems to be working, so I'll provide that here as a starting point, and to get some feedback (particularly on if there's anything I can do to clean up all the mBuff parameters)...

First, a new function, char * clock():
Code:

char * clock() {
  unsigned int clockDelta = tank.loopCount / loopsPerSecond;
  // if over 24 hours, remove 1 day. will occur after running for more than 24 hours.
  while (clockDelta > 86400) clockDelta -= 86400;
  unsigned int clock = (clockBase + clockDelta);
  // if we then add the clock base and it's over 11:59pm, wrap around to midnight.
  // will occur once a day and will reset when the clockDelta check above catches it.
  if (clock > 86400) clock -= 86400;
  unsigned int clockSeconds = (clock % 60);
  // will still be seconds so divide later
  unsigned int clockMinutes = (clock - clockSeconds) % 3600;
  unsigned int clockHours = (clock - clockMinutes - clockSeconds) / 3600;
  // divide to get minutes from mod seconds
  clockMinutes /= 60;
  boolean clockAmPm = false;
  if (clockHours > 12) {
    clockHours -= 12;
    clockAmPm = true;
  }
  if (clockHours == 0) clockHours = 12;
  mBuff[0]='0'+clockHours/10;
  mBuff[1]='0'+clockHours%10;
  mBuff[2]=':';
  mBuff[3]='0'+clockMinutes/10;
  mBuff[4]='0'+clockMinutes%10;
  mBuff[5]=':';
  mBuff[6]='0'+clockSeconds/10;
  mBuff[7]='0'+clockSeconds%10;
  mBuff[8]=clockAmPm?'p':'a';
  mBuff[9]='m';
  return mBuff;
}

So, add that code above somewhere, I added it below instantgph() and above the Trip functions.

Then, a way to display it. Basically just call LCD::print(clock()) anywhere. I added a new menu for it. Take the construct above and replace the blank line print with:
Code:

  LCD::print("Time: ");
  LCD::print(clock());

Then bam, you get a clock starting at 12am. Happiness!

Attached is a photo of my work thus far :)

FalconFour 10-03-2010 07:28 AM

Bleh, just found out that tank miles isn't working right either. For some reason it flips out once tank MPG != 0.00. I can't figure out how the math is done in this thing. For example, tank capacity is stored as an integer like "10500" by default, but when I throw "format()" at it, it comes out as 10.5, as it should. But values like VSS pulses/mile also come out from format() as "4.00". I can't figure out where the decimal is coming from... or going to. I created a small test function to cycle through every stored parameter during every update, and it gave me some fast-paced but useful insight, such as that I should remove the "/1000" on the tank capacity parameter. But now it explodes in my face after I try to use it.

Needless to say I'm a little confused as to how to handle variables in the MPGuino code. Any tips? :/

FalconFour 10-04-2010 09:20 AM

1 Attachment(s)
Updated both mods... tank remaining MPG now actually works (yay! d'oh), learned a little too late about the 64-bit, integer-based *1000 math that was used in MPGuino... so all the calculations were screwed up. All fixed now with sane math and a better understanding of how to follow MPGuino as it runs around the room...

Also updated clock to fix the bug I noticed as I was posting it. Still not functional; tomorrow I'll work on a menu that allows you to set the time. Already added a menu as in the photo. Will work on adding clock- and tank-setting menus tomorrow!

BTW, here's as small as I could get the menu code: (sorry, haven't gotten around to commenting it - but check out that pos-pointer statement! Hint: press L/R to go to the 4 corners.)
Code:

void setupGuino() { // setup menu
  LCD::gotoXY(0,0);
//LCD::print("                ");
  LCD::print("Params  |  Clock");
  LCD::gotoXY(0,1);
  LCD::print("Tank    |  Exit");
  LCD::LcdCommandWrite(0b00001110);
  byte p=3;
  byte keyLock=1;
  while (true) {
    if (p < 4)
      LCD::gotoXY((bitRead(p,0)*15), bitRead(p,1));
    if (keyLock == 0) {
      if (!(buttonState & lbuttonBit)) {// left
        p--;
        if (p == 255) p = 3;
      }
      else if (!(buttonState & rbuttonBit)) {// right
        p++;
        if (p == 4) p = 0;
      }
      else if (!(buttonState & mbuttonBit)) {// middle
        LCD::LcdCommandWrite(0b00001100);
        if (p == 0) { // params
          initGuino();
          return;
        }
        else if (p == 1) { // clock
          // tbd
          return;
        }
        else if (p == 2) { // tank
          // tbd
          return;
        }
        else if (p == 3) { // exit
          return;
        }
      }
      if (buttonState != buttonsUp) keyLock = 1;
    } else {
      keyLock = 0;
    }
    buttonState = buttonsUp;
    delay2(125);
  }
}


FalconFour 10-05-2010 02:24 AM

Next up... Duck.

http://www.youtube.com/watch?v=01kLTKLSEXI

Yes, all it is, is a duck. Just a duck.

Add to LCD prototype (begins at "// LCD prototype" near the top):
Code:

  void initDuck();
  void printDuck(byte pos);

Add "doDisplayDuck" to the list of "displayFuncs[]" containing all the other doDisplay's.
Add the line "displayFuncNames[x++] = PSTR("Duck.");" to the menu selections (big block of displayFuncNames[x++]).

Add the following function, I put it around all the other display functions (below doDisplaySystemInfo):
Code:

void doDisplayDuck(void) {
  while (tmp1[0] > 6) {
    tmp1[0]--;
    tmp1[1] = 1;
  }
  LCD::printDuck(tmp1[0]);
  if (tmp1[1]) tmp1[0]--;
  else tmp1[0]++;
  if (tmp1[0] == 0) {
    tmp1[1] = 0;
  }
}

Now, look for "displayFuncs[screen](); //call the appropriate display routine". Look for the comment "//left is rotate through screeens to the left", and the misnomer "//right is rotate through screeens to the left", and just below each of those, add the line "if (screen == displayFuncSize - 1) LCD::init();". At the bottom of each, under the "LCD::print" statement, add the line "if (screen == displayFuncSize - 1) LCD::initDuck();". This ensures that the LCD is in the right state when both coming-from and going-to the Duck mode.

Finally, two LCD functions need to be added - initDuck and printDuck.
In the LCD section near the middle, add:
Code:

void LCD::initDuck() {
  //creating the duck:
  LcdCommandWrite(0b00001100); // display control:
  LcdCommandWrite(0b00000110); // entry mode set: increment automatically, no display shift

  LcdCommandWrite(0b01001000); // set cgram
  static byte chars[] PROGMEM = {
    B00001,B10000,B00000,B00000, B00000,B11111,B11111,B00110,
    B00011,B11000,B00000,B00000, B00001,B11111,B11111,B11110,
    B00010,B11100,B00000,B00000, B00011,B11111,B11111,B11100,
    B01111,B11100,B00000,B00000, B00011,B11111,B11111,B11111,
    B11111,B11100,B00000,B00000, B00011,B11111,B11111,B11110,
    B00001,B11100,B00000,B00000, B00011,B11111,B11111,B11100,
    B00000,B11000,B00000,B00000, B00001,B11111,B11111,B11000,
    B00000,B11100,B01100,B00000, B00000,B11111,B11111,B10000};

  for(byte x=0;x<LcdNewChars;x++)
    for(byte y=0;y<LcdCharHeightPix;y++)
      LcdDataWrite(pgm_read_byte(&chars[y*LcdNewChars+x]));

  LcdCommandWrite(0b00000001); // clear display, set cursor position to zero
  LcdCommandWrite(0b10000000); // set dram to zero
}

void LCD::printDuck(byte pos) {
  char duckchars[]={ 1,2,3,4,4,0,5,6,7,8,4,0 };
  LCD::gotoXY(0,0);
  byte x=0;
  for (x=0;x<pos;x++) {
    LCD::print(" ");
  }
  LCD::print(duckchars);
  LCD::gotoXY(0,1);
  for (x=0;x<pos;x++) {
    LCD::print(" ");
  }
  LCD::print(duckchars+6);
  LCD::gotoXY(11,1);
  LCD::print("Duck.");
}

Then, upload, rechip, and voila... you have a duck screen.

dcb 10-05-2010 03:50 AM

LOL! I did some playing around too, here is conways game of life:
http://ecomodder.com/forum/showthrea...html#post39458

Cooluser23 11-10-2010 03:42 AM

Feature suggestions:

How about "tank miles remaining" before tank is empty
VSS pass through, (so I can change the VSS signal to the speedometer to read correct speed when changing tire sizes) So modify the input VSS, and output a "corrected" value to take into account changes
Allowance for a bigger/better screen to see more information at once

FalconFour 11-10-2010 03:59 AM

Miles remaining? I've got that now, and it's pretty much dead accurate, based on tank MPG, tank gallons used, and the configured tank size. Also got a working clock that's 100% completely and totally spot-on accurate 24 hours a day, 7 days a week... haven't reset the MPGuino in some 3... almost 4 weeks now, and it's still got the perfect time. Also made a huge number of modifications to the screens, to provide more intuitive flow of screens:
BIG MPG (instant)
BIG MPH (instant)
Instant
Current
Tank
EOC/Idle
CPU usage (current/peak; free mem)
Remaining miles / clock
Duck

And the Instant/Current/Tank screens have been rearranged to provide more intuitive figures:
MPG | MPH
Gallons | Distance (on Instant screen, distance is replaced with current MPG for reference)

Also added a menu that allows me to edit different parameters instead of just jumping in and locking me into editing all system parameters with no way out... when I press L+R buttons, I'm presented with a menu of "Params, Clock, Tank, Exit" (image above). Params launches the usual all-parameter edit screen, but selecting "XX" backs out of all editing back to the main screen. Clock allows me to enter the clock time in 24-hour format. Tank lets me edit the tank gallons and tank miles, in case of an accidental reset or power cycle, using figures I recorded previously (say I need to take the MPGuino inside to reprogram or something). It takes those figures in value*1000, then converts them into VSS pulses and injector S/MS that the MPGuino works with internally, based on the configured values.

I think I've made waaaaay too many edits to this code now... lol.

But... what do you mean by VSS pass through? You mean, reproduce a VSS signal on a signal pin to drive the speedometer? Hm... I don't really have a use for that, so I dunno if I could really develop and test that... :/

And a bigger screen? Not sure about that one either... if I get my hands on a bigger LCD I might play around with it, but the 16x2 LCD format comes in a wide variety of physical dimensions... doesn't help to put more info on the screen at once, but I think the instant/current/trip screen setup is already an information overload as it is while driving! ;)

Cooluser23 11-10-2010 04:04 AM

FalconFour, Wow! Thanks for that crazy quick response. :)

FalconFour 11-10-2010 04:05 AM

Eh, I've got this thread on email notification, and my email is IMAP, so you reply and *BING*, my email pops up, I click the link, come here and reply ;)

Cooluser23 11-10-2010 04:11 AM

Quote:

Originally Posted by FalconFour (Post 203336)

But... what do you mean by VSS pass through? You mean, reproduce a VSS signal on a signal pin to drive the speedometer? Hm... I don't really have a use for that, so I dunno if I could really develop and test that... :/

Yep, that's exactly it. My car currently needs 4000 pulses for the VSS, but once I change the tires to a larger size (for less rotations per mile) my speedo will read slower than the actual car speed. (and the odometer will read incorrectly, etc.)

So I wish there were a way to adjust for that deviation. A) for the MPGDuino to read correctly, and B ) to replace the input wire to the Gauge cluster, so it can read correctly.

Quote:

Originally Posted by FalconFour (Post 203336)

And a bigger screen? Not sure about that one either... if I get my hands on a bigger LCD I might play around with it, but the 16x2 LCD format comes in a wide variety of physical dimensions... doesn't help to put more info on the screen at once, but I think the instant/current/trip screen setup is already an information overload as it is while driving! ;)

I wasn't thinking to add more information onto a screen, but to highlight certain information with a larger font, while other less important information is still displayed, but doesn't catch my eye as quickly, unless I look for it.

I think increasing/decreasing the importance of some of the information would make it easier/faster to scan the screen at a quick glance.

Hope my explanations make sense.

FalconFour 11-10-2010 04:20 AM

Ah, I see what you mean, then. Hmm. I wouldn't really know how to go about tweaking VSS pulses, though... I mean, consider this:
|______|______|______|______|______ = your VSS at some speed
|_____|_____|_____|_____|_____|_____ = modified VSS by just removing 1 time mark (underscore)
Notice how the second (modified) line doesn't really... doesn't really line up with the first at all? That makes it really difficult to make any sort of "pass-through", as the "effect" would have to be triggered by the "cause" directly (the original VSS pulse). Without a direct cause-effect, the MPGuino would have to basically re-create the VSS signal, perhaps with a delay, or maybe by re-calculating the difference between VSS-input-rate and VSS-output-rate on each VSS pulse, however "Instant" does it... baaaaah, the math is making my head hurt. >.< Yeah, see the problem, though? ;)

As for information on the screen, well... there's really no way to "format" information on the screen (bigger, bold, highlight, etc). All screens that aren't prohibitively difficult to program, are simple character-based devices... I can imagine a 20-character-wide screen (as opposed to the current 16) would help put some space between the cramped-together figures. That would be pretty easy, and pretty useful, I think...?

Cooluser23 11-11-2010 11:54 PM

Cool LCD displays
 
https://www.makershed.com/v/vspfiles/photos/MKLW1-2.jpg
https://www.makershed.com/v/vspfiles/photos/MKLW1-2.jpg
Quote:

Add touch-screen control to your Arduino project! The TouchShield is an Arduino-ready 128×128 pixel OLED screen on a PCB shield that brings advanced I/O capabilities to the Arduino platform. This is the new Stealth Edition, which has an all-blacked out board that looks pretty slick on top of the dark blue Arduino.
$99.95 :eek:

Amazon.com: LCD Module for Arduino 20 x 4, White on Blue: Everything Else: Reviews, Prices & more

http://ecx.images-amazon.com/images/...yL._SS500_.jpg
http://ecx.images-amazon.com/images/I/61CxasuBDbL.jpg
Quote:

20 x 4 LCD, 5 volt, based on the popular HD44780. White characters on blue background, with back light. 4 rows, 20 characters per row.
We include instructions and Arduino software for using this LCD with Arduino.
We even include the header pins and a resistor for the contrast pin. We're good like that.
$15.95

What do you think?

Cooluser23 12-01-2010 01:52 PM

Hi FalconFour,

what have you been up to over the last month? Any cool new updates?

msc 12-13-2010 08:17 PM

What version of code are you working from for these mods?

What development environment are you working with, Arduino or other?

Mike

FalconFour 12-13-2010 08:19 PM

MPGuino version 0.86, Arduino IDE version 0021. If there's a newer MPGuino version, it'll be a bit of a huge PITA to migrate all the changes now, lol... but I'm sure the first time I do it, I'll be sure to find a cleaner way to do it ;)

FalconFour 12-13-2010 08:48 PM

1 Attachment(s)
Come to think of it, I think it's due time to just post my full modified version.

Currently set up for 20MHz board (MPGuino). Select the block of 16MHz parameters (top of the code) and Ctrl+/, then select 20MHZ and Ctrl+/ to toggle between the two (uncomment one, comment the other).

krizt 12-15-2010 01:59 PM

Hej Falcon that's great work!! Almost exactly what I wanted. Could you please do the METRIC version to?? Pleeease :D

FalconFour 12-15-2010 02:24 PM

Bleh, I put a bit of work taking metric out of the code, lol... I guess when the next version ever comes out, I'll have to redo it, and leave the metric stuff in there ... maybe! ;)

Cooluser23 12-27-2010 01:17 AM

Wow, I just noticed you had a Fiero. :D
 
I do as well. An '86 SE V6.

I wonder if we ever ran into each other at Coast runs, or Fiero club meets? - The internet is surely a small place :p

Did you do any cool Arduino (not just limited to MPGuino) projects over the holidays?

-Max

steffen707 04-20-2011 11:52 PM

I uploaded this code to my new arduino that i bought off ebay. Then plugged the chip into my mpguino, and voila! Sweet new UI for an already awesome gauge. Not to mention some sweet additional features.

volkov 04-08-2013 02:09 PM

Hi!

Is there any update? Maybe a metric version? :D

Thanks!

(I've tried to understand the code, and put back the metric things, but is't mission imposible for me :((( )

AndrzejM 04-08-2013 05:24 PM

Volkov, first of all welcome to the forum.
If you want to use MPGuino you can use official v0.86 version (sometimes there's a bug in the metric readings), or you can use metric "canadian" version (I'm using it for Berta right now with some custom mods to the code).
So you have at least two options that don't require any mods to the code.

If you have any questions regarding MPGuino installation or code you'll surely find help here.

What kind of car are you driving? Register it into your Garage with a fuel log.

P.S. I was in Budapest three weeks ago :) My company headquarter is located there.

volkov 04-09-2013 03:16 AM

Quote:

Originally Posted by AndrzejM (Post 365736)
Volkov, first of all welcome to the forum.
If you want to use MPGuino you can use official v0.86 version (sometimes there's a bug in the metric readings), or you can use metric "canadian" version (I'm using it for Berta right now with some custom mods to the code).
So you have at least two options that don't require any mods to the code.

If you have any questions regarding MPGuino installation or code you'll surely find help here.

What kind of car are you driving?

P.S. I was in Budapest three weeks ago :) My company headquarter is located there.

Thanks!
I've been a member for a while, but this was my first post :)

I have an 1986 Ford Escort RS Turbo S2. (1.6 CVH turbo)

What is the latest "canadian" version? 0.82?

I've tried the "official" 0.86, but it's a little strange and hard to read at metric readouts.
I wanted to change the screens: remove the first zeros, add a remaining km, etc.

I looked for the forum for mods, and find this topic by Falcon, and I like his version :)
(but it's a little old and no metric version in it :( )


P.S.: this was the ugliest winter(spring?!) ever, I cant remember any March with snow in Hungary... But I hope you had a good time :)

AndrzejM 04-09-2013 04:14 AM

Quote:

Originally Posted by volkov (Post 365800)
Thanks!
I've been a member for a while, but this was my first post :)

I have an 1986 Ford Escort RS Turbo S2. (1.6 CVH turbo)

What is the latest "canadian" version? 0.82?

I've tried the "official" 0.86, but it's a little strange and hard to read at metric readouts.
I wanted to change the screens: remove the first zeros, add a remaining km, etc.

I looked for the forum for mods, and find this topic by Falcon, and I like his version :)
(but it's a little old and no metric version in it :( )


P.S.: this was the ugliest winter(spring?!) ever, I cant remember any March with snow in Hungary... But I hope you had a good time :)

Nice ride!

Yes you're right last "canadian" version is 0.82 but I'm using 0.81 right now with few mods. As soon as I'll finish all mods I want to publish my code here.

It was sunny and warm when I was in BP... But all the way from Poland it was like middle of January with lots of snow :)

ECONORAM 05-20-2013 10:32 PM

Any updates Falcon??


All times are GMT -4. The time now is 05:55 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Content Relevant URLs by vBSEO 3.5.2
All content copyright EcoModder.com