1. Attachments are working again! Check out this thread for more details and to report any other bugs.

HSI for Gen II with Arduino and CAN-BUS Shield

Discussion in 'Gen 2 Prius Accessories & Modifications' started by alexmol, Apr 15, 2011.

  1. usbseawolf2000

    usbseawolf2000 HSD PhD

    Joined:
    Sep 22, 2004
    14,487
    2,994
    0
    Location:
    Fort Lee, NJ
    Vehicle:
    2012 Prius Plug-in
    Model:
    Plug-in Base
    Alex,

    Those info are very useful. What color LCD screen do you have? It looks like white on black.

    Regarding the power consumption, what revision of the board do you have. The latest is rev C. I also noticed a clone version Seeeduino claims zero power consumption (starting from V2.12). Would it be a good alternative?
     
    1 person likes this.
  2. alexmol

    alexmol Junior Member

    Joined:
    Feb 24, 2011
    21
    22
    0
    Location:
    Portugal
    Vehicle:
    2005 Prius
    Model:
    N/A
    It's white on black. Green on black would also look nice.

    The problem with power consumption is not only about the Arduino board itself but also the CAN-BUS shield and LCD display.

    I'm having trouble putting the CAN-BUS controller chip into sleep mode by software and the CAN-BUS transciever needs a little hardware change to be put into sleep mode.
    The LCD backlight can be turned off by software but the lcd controller and serial chip will remain drawing power.
     
    1 person likes this.
  3. cwa

    cwa Member

    Joined:
    Mar 15, 2011
    41
    2
    0
    Location:
    Colombo
    Vehicle:
    2008 Prius
    Model:
    N/A
    Hi usbseawolf2000,
    Is canbus based on OBDII or an independent protocol?

    THe reason for this question is my Prius is a JDM (Papanese domestic) and does not support OBDII. They use JOBD. Most of OBD controllers does not work.

    CWA
     
  4. usbseawolf2000

    usbseawolf2000 HSD PhD

    Joined:
    Sep 22, 2004
    14,487
    2,994
    0
    Location:
    Fort Lee, NJ
    Vehicle:
    2012 Prius Plug-in
    Model:
    Plug-in Base
    CAN-BUS is from the OBDII port. I think it can exist on JOBD as well.

    See the Prius CAN Monitor and SuperMID running on Japanese Prius using the CAN-BUS.
     
  5. 2009Prius

    2009Prius A Wimpy DIYer

    Joined:
    Mar 25, 2009
    2,705
    510
    63
    Location:
    USA
    Vehicle:
    2009 Prius
    I suppose the horizontal "bar graph" is mimicking the gen 3 bar graph?
     
  6. alexmol

    alexmol Junior Member

    Joined:
    Feb 24, 2011
    21
    22
    0
    Location:
    Portugal
    Vehicle:
    2005 Prius
    Model:
    N/A
    CAN-Bus is an independent protocol from OBD. It's used not only in the automotive industry but also in industrial applications.

    I thinks all gen2 Prius use CAN-BUS.

    Check the DC resistance (with the car OFF) between pins 6 and 14 of the OBD connector, you should get between 54 and 69 ohms if it's the CAN-BUS port.


    The horizontal bar tries to mimick the 3G HSI but not exactly because I don't have a 3G to compare to.
     
    2 people like this.
  7. valerun

    valerun New Member

    Joined:
    Jun 24, 2011
    1
    0
    0
    Location:
    US
    Vehicle:
    2005 Prius
    Model:
    N/A
    Hi Alex -

    Awesome work! I was just searching for CANBUS + Arduino on Google and this came up. I have the same hardware setup as you have but am also trying to write to CANbus. Unfortunately, SKPang's code has only placeholder functions for that so I was wondering if you have modded his libraries in any way to add functionality.

    Would love to take a look at your source code - if you still can't post link here, please email to valery at rusbaevents dot com.

    Thanks!!
    Valery
     
  8. alexmol

    alexmol Junior Member

    Joined:
    Feb 24, 2011
    21
    22
    0
    Location:
    Portugal
    Vehicle:
    2005 Prius
    Model:
    N/A
    3 people like this.
  9. 2009Prius

    2009Prius A Wimpy DIYer

    Joined:
    Mar 25, 2009
    2,705
    510
    63
    Location:
    USA
    Vehicle:
    2009 Prius
    No code, just headers for library? :confused:
     
  10. ccdisce

    ccdisce Active Member

    Joined:
    Oct 10, 2010
    259
    187
    0
    Location:
    Stone Mtn GA USA
    Vehicle:
    2008 Prius
    Model:
    N/A

    Alex,
    Compiled it and downloaded into the Arduino Uno/Can Shield.
    Took the liberty to change a couple of the message strings.
    Ran a quick check in the car in the driveway,, works fine.
    I will run a test tomorrow during the morning's commute.
    Thanks,
    Winston.
     
    dave77 likes this.
  11. 2009Prius

    2009Prius A Wimpy DIYer

    Joined:
    Mar 25, 2009
    2,705
    510
    63
    Location:
    USA
    Vehicle:
    2009 Prius
    Could you give a step by step instruction for those of us uninitiated? Thanks!
     
  12. ccdisce

    ccdisce Active Member

    Joined:
    Oct 10, 2010
    259
    187
    0
    Location:
    Stone Mtn GA USA
    Vehicle:
    2008 Prius
    Model:
    N/A

    Ok Here is what I had to buy;
    1. Hardware a. Arduino Uno
    b. SparkFun CAN Shield
    c. Connectors to be able to plug in Shield into UNO
    d. OBDII to DB9 Cable
    c. USB A/B Cable
    d. 2x16 serial enabled LCD
    e. +9V Brick

    2. Software a. Arduino SW Suite V022..........Arduino Website
    b. CAN Shield SW Canbus V3 S K Pang website
    c. BarraHSI_v109 SW Package

    Install the Arduino SW Package and open the ecu_reader_logger source file extension 'sketch". The include statements says that it is looking for SdFat, SdFatUtil, NewSoftSerial, Canbus in hex to be in your library.
    Being Shareware they should be on the Web somewhere such as Adafruit, NewSoftSerial etc.
    Load them into your library Compile and Download and check it out on the car. The Joystick is used to select the items on the menu and can be used to check out the hardware.

    Download Alex's code and open the sketch whose include statement(s) is asking for NewSoftSerial, mcp2515 both of which you should have in your library., so compile aka verify and download.
    Portugese anyone?

    GoodLuck

    Winston.
     
  13. alexmol

    alexmol Junior Member

    Joined:
    Feb 24, 2011
    21
    22
    0
    Location:
    Portugal
    Vehicle:
    2005 Prius
    Model:
    N/A
    Thank you Winston!

    Just one important thing: My code only works with the SparkFun 2x16 Serial LCD

    If you use other brand be sure that it can hold 8 custom characters. You will also have to change the code to program the custom characters and other codes to program the LCD brightness and serial speed.

    About the code comments in portuguese you probably can make sense of them by translating with a web tool like google translate.

    I don't have time to explain the code here, but if you have any specific issue I might help you.
     
    1 person likes this.
  14. jdh2550

    jdh2550 Co-Founder, Current Motor Company

    Joined:
    Nov 16, 2010
    317
    249
    0
    Location:
    Ann Arbor
    Vehicle:
    2005 Prius
    Model:
    N/A
    alexmol - thank you very much for making this open source! I'm about to try and port this project using a DuinoMite eMega from Olimex.

    For anyone interested in doing this project I suggest they check out the DuinoMite Mega (not the eMega). It has CAN on the main board and costs $40 from Mouser in the US or 30 EUR direct from Olimex in Europe. DonTronics has 'em for the Aussie crowd.

    DUINOMITE BASIC COMPUTER

    So, you can cut your costs by about $40 - no need to buy an Arduino & a shield - DuinoMite has both (and a lot more) in one package. I'm a big Arduino fan - but, thanks to Bruce I'm turning into a bigger Olimex fan!

    I'll actually be outputting to a Lilliput VGA monitor (although it would also be easy to use the same Sparkfun display that alexmol's original uses). Also the DuinoMite Mega can do composite video so I think you may be able to hook up to the MFD (not sure about that though).

    For folk's interested in following along then there are two more recently active threads with a few of us playing with these boards:
    1) "De"-nginer | PriusChat - this is the thread where Bruce introduced the DuinoMite and his intended project
    2) YAPiP - recreating pEEf's approach | PriusChat - which is my project that's similar to Bruce's and based on work by pEEf.

    If I get a good HSI implementation working I'll also post back here.

    Thanks again alexmol - open source FTW!
     
    dave77 likes this.
  15. Chris Dragon

    Chris Dragon Junior Member

    Joined:
    Dec 16, 2012
    22
    6
    0
    Vehicle:
    2004 Prius
    Model:
    N/A
    Wow, this is an awesome project, Alex.

    ccdisce, what do you mean by "+9V Brick"? I assume you mean 9V to power the arduino (from the cig lighter, maybe?) but this video shows the device is powered by simply plugging the ODBII port into the CAN-BUS card. I'm not sure how that's done exactly either - I assume the card is already wired for it.

    I'm also curious which "Connectors to be able to plug in Shield into UNO" are best to connect them together as a stable unit like in the video. Maybe these?

    It looks like the total cost of everything together will be $110 before shipping, unless I do need a 9V brick. I was also wondering if I could just use my OBDII bluetooth adapter to transmit data to Torque on my smartphone and develop an HSI bar as a Torque plug-in? I can't find anyone that's made such a plug-in but it does seem like it would save a lot of money (at least if you already have the bluetooth hardware). I'm also worried it might be too slow compared to the direct CAN-BUS connection.
     
  16. alexmol

    alexmol Junior Member

    Joined:
    Feb 24, 2011
    21
    22
    0
    Location:
    Portugal
    Vehicle:
    2005 Prius
    Model:
    N/A
    Hi Chris,
    With the sparkfun CanBus shield you don't need a separate power supply for the Arduino as it takes the 12V from the ODBII connector and powers the Arduino through the power and ground pins.

    The connectors needed are the ones you mentioned on the link.
     
  17. Chris Dragon

    Chris Dragon Junior Member

    Joined:
    Dec 16, 2012
    22
    6
    0
    Vehicle:
    2004 Prius
    Model:
    N/A
    Thanks, Alex.

    I've got all the parts on order. Another way to save $15-$20 is to buy the Seeedcode CAN shield instead of the Sparkfun one. Seeedcode's is missing the LCD connector so you'd have to drive the LCD from the Arduino, and I don't think Seeedcode's can power the Arduino from the OBD cable, which might actually be better because you could run a wire from the cigarette lighter to power it and it would turn off with the car, solving the standby power problem. All that would probably require some code changes in your software to get working.

    I'll see about posting a tutorial about what parts I bought and how to put them together for people who've never worked with Arduino before (like me - but I have built TeensyUSB projects at least).
     
  18. Chris Dragon

    Chris Dragon Junior Member

    Joined:
    Dec 16, 2012
    22
    6
    0
    Vehicle:
    2004 Prius
    Model:
    N/A
    Hi all,

    I've got Alex's HSI bar working and updated with many new features. This post will explain how to build the device using the 16x2 LCD Alex used, and using a 64x128 screen I purchased later. I'm going to refer to my version of the software as "HSI+" at various points because I've added so many displays beyond the HSI bar, and I've actually replaced the HSI bar with a separate electric and gas engine bar that I find more useful.

    I've always wanted to drive my Prius more efficiently but trying to do it by feel wasn't working and looking way over to the MFD for its limited info felt too unsafe, so having the Arduino LCD right near the instrument panel is finally helping me improve efficiency.

    New features:
    • Changed single letter after RPM from 'R' to 'G' for Gas engine mode ('R' stands for something in Portuguese, I assume). Added 'C' for Combined when both gas and electric are running.
    • Replaced coolant temp with fuel injection timing and RPM with MPG, leaving that single letter to indicate Electric, Gas, or Combined.
    • Negative engine RPMs are now displayed as positive followed by B for engine brake. Hitting negative RPMs seems to only happen on an extended steep hill in engine brake mode.
    • Added ability to toggle between showing different information below the HSI bar using left and right d-pad on Sparkfun CAN-Bus.
    • Added debug modes to display various raw data instead of the HSI bar. Access these modes by pressing up or down on d-pad. These are mostly for development but may be interesting for the curious.
    • Press center d-pad to clear display and reset debug and display modes to default.
    • English translation of source code and user messages.
    • Modified to work in Arduino IDE 1.0.5.
    • Fixed gear shift position detection to work with more cars (including my own). The HSI bar never fills if gear shift position is not detected.
    • Limit redrawing amps display to once every 500ms to prevent fast flickering that makes the number unreadable.
    • (and much more to be released after additional testing)
    I've attached a zip file of my updated source code as well as a compiled .hex file which you can install to your Arduino Uno board with a tool like XLoader without installing the Arduino IDE and all the libraries.

    Before you decide to build this device, you might want to read through this wiki page which contains links to a number of alternative Arduino-based OBDII devices. At least one of them supports graphing if that's your thing, but I don't think any of them display as much useful information as this device if you build it with the 128x64 pixel screen.

    Based on instructions posted earlier by ccdisce, here is how I built the device:

    Hardware required
    • Arduino board
      • $30 from Sparkfun or Amazon but I got a used one on Amazon for $16 shipped
      • You'll need to buy an Arduino Mega if you want to do SD card logging or add a GPS. Alternately, read through this thread for some less expensive arduino competitors that have various levels of arduino compatibility. Be warned that buying a competitor will definitely require some amount of changing the HSI bar source code.
      • An ideal option to save money might be the $20 Teensy 3.1 board recently released. It actually includes much more memory than Arduino Uno and a CAN BUS chip so you don't need the CAN-BUS shield, saving $55 total. Of course you also give up things like SD card logging and I don't know how hard it would be to adapt the HSI+ code to run on the Teensy.
    • CAN-BUS Shield
      • $45 for Sparkfun version here. I couldn’t find it used on ebay or Amazon.
      • There are a few other CAN bus shields for Arduino floating around such as a $23 version by Seeedcode. It's tempting to save all that money, and it may actually be a good idea, but consider these points first:
        • You may need to change a bunch of source code to use whatever library the alternative CAN shield comes with. Although I think most or all would be based on the mcp2515 library so there might not need to be many changes, if any.
        • Only Sparkfun's board has a serial LCD connector. The connector is actually just 3 solder points consisting of +5V, Ground, and pin 6 from the arduino header, so it doesn't add any functionality to the shield, it's just a possibly more convenient connection point.
        • Only Sparkfun's board has 4 directional buttons which are useful for debugging and providing a bit of a user interface control. However, I was able to hook into the cruise control lever on the Prius when cruise is off to act as a 3-direction joystick for user interface control, so the d-pad is not really needed other than for convenient testing.
        • Only Sparkfun's board has a spot to plug in a GPS chip and an SD card. If you might want to do logging later (you'd need to add code to do so), you'll want the Sparkfun board. You'll also probably want to buy an Arduino Mega instead of Arduino Uno because the Uno runs out of memory even adding just the SD card handling code, much less GPS. SD cards are written in 512 byte blocks which means any SD card library needs to use 512 bytes of memory at minimum, and that's 25% of Arduino Uno's memory.
          • Update: I've hacked the 128x64 LCD display driver to cut its memory use from 1024 bytes to 256 by using only the top line for graphics and storing the rest as text. This barely made room for a FAT16 SD card library which I hacked to support a micro SDHC card formatted with a FAT16 file system (should also work on older micro SD cards formatted FAT16). FAT16 is limited to 2GB but adding FAT32 support increases the sketch size far too much. So I have logging working on Arduino Uno but I still recommend Arduino Mega if you need fancy logging, graphing, want GPS, or want to store over 2GB.
    • Connectors to be able to plug in CAN-bus shield into Uno
      • You need to buy “header pins” to connect the CAN shield to the Arduino. Stackable headers ($1.50 here and you’ll need to cut the 10 pin header down to 6 pins) are cheapest and allow you to add another shield on top of the CAN shield should you ever need to do so. Soldering them on can be a little tricky (tutorial here) but isn't too hard if you've got a little soldering experience and a good soldering iron (if your iron often has trouble melting solder, get a higher powered one like Hakko FX888D and you'll be quite happy).
      • For more money and less trouble you can go with solderless male headers ($1.50 here but you need to buy 4 of them and cut 3 of them down to 8, 8, 6, and 6 pin lengths). You might want to research first to make sure solderless headers are strong enough to survive the constant vibrations in a car without intermittently loosing connection.
    • A display
      • $25 for 2x16 Sparkfun serial enabled LCD. You can get a compact 3.3V version or a wider 5V version
        • Something about this type of LCD it almost impossible to read without the backlight. If you shine sunlight on it at just the right angle you can barely see the text without the backlight. This is different than the classic black on green LCD that becomes more visible under sunlight, and I think it makes these LCDs a bad choice for a dashboard display. At full backlight brightness I have trouble seeing the LCD with sunglasses when sun is hitting it at certain angles, even though I recessed it in a cardboard box 3-4 inches deep to keep it as shaded as possible.
        • Nobody mentions it in the comments but I wonder if the LCD running at 5V is brighter than the one running at 3.3V. Might be worth investigating.
        • It might also be worth investigating if the Positive version of this LCD is visible in sunlight. If you could find a version of this screen that's visible in sunlight I would highly recommend it for beginners because it's so much easier to wire than the larger screen discussed later.
        • Very annoyingly, the Negative LCDs are polarized such that the letters turn completely black when wearing polarized sunglasses. Tilting my head 90 degrees makes the letters visible but I obviously can't drive like that.
        • I bought the 3.3V version because it has much smaller edges which makes it take up less space on the dashboard. In fact, it could be fit to the left of the MPH display except it would cover the parking brake, seat belt, and door open lights. This LCD needs to be powered by the 3.3V pin on the arduino instead of the 5V pin on the CAN shield LCD connector. It also wants 3.3V TTL serial signal but the CAN shield puts out 5V TTL. The LCD actually seemed to work correctly with the 5V TTL but I worry it will cause long term damage, so I used 100 and 200 ohm resistors to reduce the 5V signal to 3.3V (it actually ended up being 2.5V for some reason but still worked). Make sure you own or buy those resistors if you get the 3.3V LCD (other resistors will work but using ones with too high a resistance will not allow enough current through for the circuit to perform correctly and too low resistance will act like shorting the 3.3V to the ground and make the resistors heat up and fail or melt something. Note that this LCD has 3 tiny screws on the back for connecting the wire that drives the LCD, so you don't have to solder or buy a special JST connector like on the 5V version.
      • If you're decent with programming, you might want to try a brighter OLED screen instead of LCD. Unfortunately there isn't a serial version of the screen available so you'll likely need to rework the source code to get the custom characters working. OLED also loses its brightness over time, and faster under high heat. Since cars can get so hot, I'm not sure how well it will last.
      • Rather than try to predict OLED's longevity on a sunny dashboard, I decided to order some old-school black on green LCD screens that many have said have good sunlight visibility: ST7565 Positive and Negative.
        • I got both so I could compare. As I feared, the Negative version is significantly harder to see under many lighting conditions:
          • Positive has much better contrast in direct sun:
            IMG_20140503_135445.jpg
          • Negative is nicer to look at and has possibly slightly better contrast in shadow, although that's probably because I had its backlight on and the Positive screen's backlight was off:
            IMG_20140503_152231.jpg
          • I didn't want to ask the Arduino to drive the backlight on both LCDs at once as I'm not sure what its power limits are on a single pin. I should have turned off the negative LCD backlight for a better comparison but didn't think of it at the time.
        • This makes sense because sunlight brightens most of the screen on the Positive version, increasing contrast, while only a little sunlight gets into the transparent pixels on the Negative screen, making them less bright, and depending on the sun's angle, you'll actually see shadows around the inside edges of the pixels, making them appear slightly smaller. On the Positive screen, shadows make the pixels appear bigger. Also, the Negative version turns completely black with polarized sunglasses but the Positive version does not (tilt your head 90 degrees and Negative is normally visible and Positive becomes black). This all sucks because the Negative is prettier and feels higher contrast if the light is right. Negative also doesn't create a huge block of backlight behind the text at night, which creates less glare on the windshield. Unfortunately I'm going to have to go with the Positive version for better day visibility when I do most of my driving.
        • After driving for many hours with the Positive version and polarized sunglasses I'm quite happy with it. In sunlight it's always visible and glare was never a problem (perhaps due to the polarized sunglasses). In shadow, having the backlight on still makes it visible. The only time I can't read it is when I pass under a brief shadow, like an overpass, and then it's only unreadable for a moment.
        • If you go for the Negative version, note that I had to set its contrast to 0x27 instead of the default 0x18 or text was almost invisible without the backlight, and hard to see even with backlight. I've read others say they found 0x18 to be the best contrast so I think I must have gotten a weirdly calibrated one or something. 0x18 worked decently for the Positive version but 0x22 seemed generally ideal. 0x22 worked pretty well for the Negative version as well.
        • Using either of these screens actually reduces the size of the compiled sketch by 10k after I added the driver for these LCDs and removed the code required to draw the HSI bar using custom characters on the 16x2 LCD. Even after adding code to draw the HSI bar graphically I've still saved about 9k. That 9k is important because there wasn't room to add SD card logging code within the Uno's 32k limit when I was using the 16x2LCD (compiled code was 34k just opening a log file and writing "Hello world"). Unfortunately, adding the SD code also used about 750 extra bytes of RAM, and that plus the LCD's use of 1024 bytes put me about 340 bytes beyond the Uno's 2K of available RAM. So if you want to do SD card logging, I recommend buying an Arduino Mega instead of Arduino Uno.
        • These screens are graphical and big enough to display plenty of car data and are actually cheaper than the serial LCD. Unfortunately their wiring is much trickier being as they need 8 wires (or 11 wires if you want to vary the backlight color) which makes for a larger cable snaking across your dashboard, plus they need a chip to convert most of those wires from 5V to 3.3V and a resistor to drop the backlight voltages. The tutorial for wiring it actually shows you need 9 wires but you can connect all the ground pins (GND, R-, G-, B-) to the same wire so you only need 8 wires as long as you're happy with a white backlight (I'm guessing you could hard wire some resistors to R-, G-, or B- to alter the color without adding a wire). Also note the tutorial is for an older version that only had a white backlight.
    • If you buy the 3.3V 16x2 character screen discussed above, you will need these additional parts:
      • 110 ohm and 220 ohm 1/4 Watt resistors
      • A few feet of 3 conductor, 22AWG wire to run from Arduino to LCD
        • I really wanted black wire to match the dashboard. The only place I found black sold by the foot was here, but it’s very expensive at a dollar a foot. I found grey here for 18c a foot, but ended up buying a 100 foot roll off ebay for future projects that was a bit cheaper per foot. I think I used about 6 feet of wire but I didn't measure it.
    • If you get the 128x64 pixel screen discussed above. you will need these additional parts:
      • A 1/4W resistor kit. If you're sure you're never going to do another electronics project and you want to save some money, you can get just the following resistors: 2.2K ohm, 1K ohm, and 27 ohm. However, if you want to get the green LED backlight to the exact brightness level you want or use a different color backlight at night, you'll need to have an assortment of resistors to try.
      • One or two 1/4 size breadboard. You can find cheaper ones if you look but not necessarily with rows already connected together. My guide will refer to the letter/number positions on this breadboard.
      • One PN2222 transistor or 2N3904 transistor. I used the 2N3904 only because it was available at my local Radio Shack but the PN2222 is generally better for a wider variety of projects.
      • One or two ethernet jacks. These will allow you to unplug the LCD from the Arduino. You can put a jack on each end, or permanently solder the wires of an ethernet cable on either or both ends. Instead of trying to solder to the Arduino header pins, I recommend buying a set of at least two rows of male header pins and solder to them, then plug them into the Arduino's headers. Read through the section on building the hardware to decide if you want one or two (or even none) ethernet jacks.
      • A few feet of 8-wire ethernet cable, black preferred.
      • 8 different colored rolls of 22AWG solid core wire. Trying to get the circuit put together to drive the LCD with too few wire colors will be very frustrating. Of course you can also go with 4 colors and mark some with permanent marker to produce 8 variations. Solid core rather than stranded allows you to slide the wires into Arduino's header pins, among other things.
      • A good 22AWG wire stripper. Also available cheaper if you're near All Electronics or you want to order a few things at once to cover shipping. I used to waste a lot of time with crappy strippers or my pocket knife scissors which all required turning the wire in the stripper which is often difficult as things start to get in the way. A good stripper will let you do a quick squeeze and pull off the insulation with no rotation required.
      • Half or quarter-sized prototyping breadboard. This isn't necessary if you follow this guide to build your breadboard, but it's recommended if you plan to do future electronics projects or you want to test things before soldering it all together and hoping you didn't get something in the wrong place. If you get one, get a breadboarding wire bundle too, and two or three packs of mini hook jumpers. Hook jumpers are so much better than alligator clips when working with small wires, but it's hard to find them in good quality with springs that aren't so strong they bend the wires or bend the hooks in the jumper. The ones I linked to work great (better than similar ones I bought from Amazon).
      • A good soldering iron with a fine tip (*cough* Hakko FX788 *cough*). Trying to solder the 40 or so connections this build requires with an iron that doesn't heat well will drive you insane.
      • Small diameter leaded solder with flux (aka rosin) core. Yeah, lead is bad for the environment, so send your project to electronics recycling if it ever breaks down or becomes obsolete. I've tried lead-free solder and its failure to melt and form strong joints is maddening. Plus higher melting point means more risk of damaging components. Leaded solder melts at 621F, which is far far from lead's boiling point (3,164F) so lead fumes aren't a problem, but flux and plastic fumes can still be bad for you so use a mask and/or a fan while soldering. Wash hands when done.
      • A desoldering tool. This is also optional, but very useful to remove most of the solder if you make a mistake and have to pull a wire out of a hole. A desoldering wick is a cheaper alternative and is also useful in conjuction with the desoldering tool to wick out the last bits of solder the tool can't pull. You need a higher temperature setting on your iron (800+ degrees) to heat up the desoldering wick enough to get it to pull solder between its braids.
      • Hot glue gun with high temp glue. Low temp glue may soften and fail in a hot car.
      • For experts only:
        • This tutorial explains how to alter the Arduino Uno to run natively on 3.3v by replacing a couple components on the Uno board. This is a huge advantage as you can simplify the wiring for this LCD and maybe save a little power. On the other hand, there might be overheating concerns stepping down 12V OBDII power to 3.3v with an inefficient linear regulator and the article mentions possible instability running the Arduino below its minimum 3.6V spec. My Uno already gets pretty hot stepping down 12V to 5V and it's not even in an enclosure, so I don't know. So this is only something I'd suggest experts attempt, but I wanted to throw the idea out there.
    • USB A/B Cable
      • $4 from Amazon.
      • Arduino has a large, almost square USB B port like you normally only find on printers and other larger PC peripherals. Why they didn’t use a Mini or Micro USB port I have no idea (maybe due to cost when Arduino was started, or maybe because you can plug/unplug more times from USB B than Mini USB). Make sure you have a cable with a USB B male end for the Arduino and USB A male on the other end that fits in your computer.
      • This cable is only needed to program the Arduino. After that it’s not needed, so you can always borrow this cable from something you own, like your printer or scanner.
      • On the other hand, you might want to power the Arduino in the car using this cable and a cigarette lighter USB adapter. That way the Arduino will turn off when the car is turned off. Otherwise, if you run off the 12V from the OBDII connector the Arduino will always be draining your battery. HSI bar detects car off and turns off the LCD but Arduino uses an inefficient linear voltage regulator to convert 12V to its native 5V so that's always sucking up extra power and producing heat. I don't know how long it would take to drain the Prius starter battery but maybe Alex can comment. Another possibility is to buy a 5V switching voltage regulator. I use one of those on the stereo's 12V to charge my phone at 5V while it plays audio and can post details if anyone asks. I seem to remember it was about $20 of parts.
    • OBDII to DB9 Cable
      • Bought on Amazon for $8 shipped. Unfortunately it shipped from China and took 2 weeks to get here.
      • The Sparkfun cable is $2 more but based on the picture it appears to be 3/4" shorter, which may be important. My wife is shorter and has a problem hitting the OBD cable plug with her leg. You might also want to look for a low-profile L-shaped OBDII connector that points to the right when plugged in. I found one on ebay (search for "OBDII DB9 right angle") but such listings come and go. This would work If you splice on your own DB9 or solder its wires to GND, CAN H, CAN L, and the arduino's power in pin. You could also buy the Sparkfun bare connector and cap it with Instamorph or even hot glue after running wires out to its side.
      • Note that you can not jam bare wires into the OBDII connector and run them to the CAN-bus shield. I'm not actually sure why not, but when I tried it made the car log ECU error codes that I had to clear with a bluetooth ELM27 OBDII device and the Torque app. I did make sure to connect the ground wire first. It's possible I pushed my wires too deep into the OBDII connector and shorted them to the body of the port or to another wire inside. Whatever went wrong, I don't recommend experimenting and risking your expensive electrical system.
      • There seems to be a standard way to wire the pins of the OBDII connector to the DB9 connector since the cable I bought was correct, but in case you want to double check, here are the pin assignments:

        Looking into the female OBDII connector on the car side:
        Code:
         __________________________
        \  1  2  3  4  5  6  7  8  /
         \ 9 10 11 12 13 14 15 16 /
          `---------___----------’

        Pins important to CAN protocol:
        5 Signal ground
        6 CAN high
        14 CAN low
        16 Battery voltage (12V)

        Looking into the female DB9 connector on the CAN shield:
        Code:
         ___________
        \ 1 2 3 4 5 /
         \ 6 7 8 9 /
          `-------’
        1 NA
        2 Ground
        3 CAN high
        5 CAN low
        9 12V It’s easy to double check these pins by testing continuity between the GND, CAN H, CAN L holes marked on the CAN shield and the DB9 pins.
    • Enclosure for LCD
      • Digikey might have one but Sparkfun doesn’t have them except for their larger screens (search for lcd bezel). They do sell enclosures where you could cut a hole for a screen but it's hard not to make that look messy.
      • As a temporary solution, I made an enclosure out of cardboard. You need to make it a somewhat odd shape, depending where you mount it. I’m thinking of using Instamorph for a permanent solution.
    Installing software
    • As long as you have an Arduino Uno with AtMega328P and serial LCD you should be able to install the pre-compiled .hex file to your arduino using a tool like XLoader for Windows. Otherwise, continue reading for how to install software to compile the source code and upload to Arduino.
    • Install Arduino IDE v1.0.5
      • Original HSI bar was created using something close to Arduino IDE V022 from 2010. In late 2011 they changed the version naming convention from V023 to V1.0 which also brought a few changes to their basic libraries and even a few keywords. Thus the original HSI source code needed some updating to compile in v1.0.5 which is the latest version as of April 2014.
    • After you run the Arduino IDE, Help > Getting Started is a good place to start if you’ve never used an Arduino board before.
      Before you can compile the HSI bar sketch, you need to install some additional libraries. What libraries are and how to install them is described here. As of Arduino v1.0.5 you can import libraries using “Sketch > Import library > Add Library…” within the arduino IDE. The page also describes how to install libraries manually in older Arduino IDE.
    • In Arduino IDE, choose “File > Open…” and pick BarraHSI_v1092.ino.
    • Ctrl-R or “Sketch > Verify / Compile”
    • Compiler errors automatically jump to the first line containing an error. After fixing it, you can Ctrl-R to compile again and jump to the next error.
    • For some reason I didn’t need to do this on Windows Arduino IDE, but on Mac I had to edit mcp2515/mcp2515.c and replace #include "WConstants.h" with #include "Arduino.h" to fix an error about WConstants.h not found.
    • Plug the Arduino into your computer. If a message pops up saying software was installed for it, notice what COM port it says it installed on (COM4 in my case).
    • Press the “Upload” button in the Arduino IDE. It looks like a right arrow. If it says Arduino wasn’t found, tell it what COM port it’s connected to (COM4 in my case).
    • If you noticed a light on the Arduino blinking orange when you first plugged it in but that light stops blinking, that’s normal. The blinking light was the default Arduino firmware just telling you it was running. The HSI firmware you just uploaded won’t blink that light.
    Building the hardware
    • Unplug the arduino from your computer and connect the CAN-bus shield using the header pins. The CAN-BUS shield (and all shields, I think) have holes only for two sets of 6 header pins on one side and two sets of 8 header pins on the other side. That means you must cut off four of the pins on the 10-pin stackable header that Sparkfun provides in their stackable header kit. That seems weird, but I’m guessing the extra pins are needed on some boards other than the Arduino Uno. Note that pins can easily be pulled out of headers with a needle nose pliers before you cut the header where the pin used to be by using an exacto blade or small saw.
      • I cut the left side off of the right header in this picture:
        IMG_20140418_145410.jpg
    • If you didn't buy the solderless header pins, follow the Sparkfun tutorial for soldering.
      • Header pins after soldering from the bottom:
        IMG_20140418_152523.jpg
      • I followed a different tutorial which suggested soldering the two outside pins with headers already connected, then pull them apart. I don't recommend that as it makes it hard to solder and hard to pull the two boards apart without bending pins as one side will suddenly release and leave the other side connected, bending the pins:
        IMG_20140418_151730.jpg
    • To wire the Sparkfun 16x2 serial LCD to the CAN shield (skip this section if using the 128x64 pixel LCD):
      • On the LCD connector, pin 1 has a square base.
      • Pin 1 puts out 5V power. Only use it if you bought the 5V serial LCD. Otherwise, use the pin marked 3.3V on the arduino header pins.
      • Pin 2 is ground. You can use it, or use the header ground pin next to the 3.3V pin.
      • Pin 3 is 5V TTL serial TX. If you bought the 3.3V LCD, use a 110 and 220 ohm resistor to drop this to 3.3V or less. Connect them as follows:
        • Code:
          Pin 3 ---- 110 ohm resistor ----|------ serial RX screw on back of LCD
                                           220 ohm resistor
          Pin 2 --------------------------|------ Gnd screw on back of LCD
        • According to the CAN-BUS schematic, Pin 3 on the LCD connector is also connected to the D6 pin on the arduino header, so you might be able to use that if you want to avoid soldering.
      • I used the 3 pins I cut off the 10-pin header to stick into the ground and 3.3v pins on the Arduino, then soldered two of my LCD wires to two of the 3 pins. This makes it possible to unplug those two wires from the header by pulling out the 3-pin header fragment:
        IMG_20140424_090505.jpg
      • I covered most of the Arduino and CAN shield in electrical tape, leaving the d-pad exposed. It would be nice to put it in a proper enclosure (I assume they must make them) and I guess you could cut out a hole to reach the d-pad. I later added code to make the Prius cruise control lever work as a d-pad when cruise is off, so I plan to put the Arduino in a full enclosure.
      • Here's where I mounted the display in a recessed cardboard "enclosure" to reduce glare:
        • IMG_20140424_090641.jpg
        • I like having the bar here. I can look at it and still see the road ahead. Since it takes some staring to pin down the values where you want them, having the bar in your line of site is an absolute necessity in my opinion.
      • Once the LCD is connected, you can power the Arduino by its USB port from your computer just to make sure it's working. It should say "Welcome!" on the top line and "HSI Bar" on the second line at some point. You should see the HSI bar for a few seconds at least and then it will say "No signal" "Hibernating" which will be very hard to read on the 16x2 LCD because the screen backlight turns off as it says that.
      • When your LCD is wired correctly, connect a cable between the Prius's OBDII port and the DB9 port on the CAN shield. Start the car to READY and you should see the HSI bar fill up when you press the gas pedal even in Park with the brake on. The amp and fuel injector timing numbers should also change.
        • Here's the HSI bar and 3 numbers that show up below it when the car is running. I've replaced the coolant temp in the middle with fuel injector timing since this picture was taken, but you can get back coolant temp by pressing left or right on the d-pad on the CAN shield. This LCD is defective and missing 3 or 4 columns of pixels towards the right. Sparkfun is shipping me a free replacement without asking me to send back the old one.
        • IMG_20140418_205440.jpg
    • Wiring the Adafruit ST7565 128x64 pixel LCD (skip this section if using the Sparkfun 16x2 serial LCD)
      • The ST7565 display library has some bugs in it that I fixed and included in the ST7565.zip file in HSI+ v1.093 and later, so install that into your Arduino libraries folder instead of downloading the ST7565 library linked to in the tutorial.
      • Solder wires to LCD:
        • I recommend soldering wires to the LCD by sticking them through the front of the LCD so they poke out the back and you solder to the back. This forces you to wrap the wires around the edge of the LCD, which is unfortunate, but it makes soldering much easier (you have solder to the back where the metal is) and I think it also provides some strain relief in the form of a wire loop where forces can spread out instead of concentrating movement right on the solder point. Solder wires about 3 inches in length to every pin on the LCD using the following colors:
          • IMG_20140503_125909.jpg
          • I'll reference these colors throughout my guide so really try to use these colors if you can or it will get very confusing.
          • SID orange wire. I had to use white with a red band added to each end for lack of orange.
          • SCLK yellow wire.
          • A0 green wire.
          • RST blue wire.
          • CS white wire.
          • VDD red wire.
          • GND black wire.
          • A+ yellow with black bands.
          • B- blue wire with black bands.
          • R- red wire with black bands.
          • G- green wire with black bands.
      • If you have a prototyping breadboard and jumper wires, you can follow this tutorial to connect and test the LCD, but read through this section for some details and changes. If you want to get right to soldering without testing the LCD first, skip the section indented below and move on to wiring the breadboard section.
        • The tutorial uses an older version of the LCD that has only a green backlight. Backlight terminals in the tutorial are labeled A (instead of A+ on newer LCD) and K (instead of G- on newer LCD).
        • The tutorial says to connect the LCD to Arduino pins 5 through 9, but many of those pins are used by the CAN-bus shield, so you'll have to use alternates. I put some long comments on why I chose these pins in the HSI+ source code. Don't forget to follow the tutorial and run each wire through the 4050 chip before connecting to the arduino. This setup is just for testing with a prototype board as described in the tutorial and is not the exactly the same as the final setup:
          • SID orange wire to pin 6 on arduino.
          • SCLK yellow wire pin A0 on arduino.
          • A0 green wire to pin 8 on arduino.
          • RST blue wire to pin A4 on arduino.
          • CS white wire to pin 7 on arduino.
          • VDD red wire to 3.3V pin on arduino.
          • GND black wire to ground pin on arduino.
          • For the sake of simplicity, leave A+, B-, R-, and G- unconnected for now. That just means the LCD won't have any backlights while you test it.
          • When your LCD is wired correctly, power the Arduino via its USB port and the LCD should show an Adafruit logo followed by the words "HSI Bar" with a version number for a second or two.
          • I don't have a picture of the above wiring because when I did my original tests, I did connect just the blue backlight, and I used slightly different pins. Feel free to skip the following indented discussion if you don't care about the technical details of my original tests.
            • In the picture below, I have B- connected to ground and a 220 ohm resistor plugged into A0 (which I later moved to pin 3 because pin 3 supports varying voltage using Pulse Width Modulation and A0 does not) and a yellow clip runs from the resistor directly to the yellow with black band wire soldered to A+ on the LCD.
            • IMG_20140503_160157.jpg
            • The resistor caused me a lot of confusion. I added it because the tutorial says you must use a resistor, but it doesn't say why. Reading through the spec sheet, it says to connect 3V (not 3.3V) to the A+ terminal and says nothing about a resistor. However, it also says the G and B LEDs should be driven at 3.1V and the R LED at 2.0V. So I thought maybe the resistor was meant to drop voltage from 3.3V to 3.1V or less, but that would imply you need a bigger resistor to drop to 2.0V or less for the red LED. I finally found this thread which says the resistor described in the tutorial is to limit current to under 20 mA to each LED to make them last longer (the spec sheet actually says 18mA, not 20mA, is their forward current, meaning current safe to flow through them in the normal forward + to - direction that causes them to light). I looked on the back of the LCD board and found the R- terminal runs through a 100 ohm resistor while the G- and L- run through 0 ohm resistors, so the board itself has resistors to reduce the red backlight to 2.0V given 3.0V connected to the A+ terminal. So only a single resistor is needed, and only to drop the 3.3V arduino power to 3.0V or less. A bigger resistor means dimmer LEDs and presumably longer life.
            • The tutorial says to use a 100 ohm resistor on the 3.3V line but my guestimating calculations showed that would limit each LED to 1.5V instead of their max 3.1V. So I used a 39 ohm resistor which causes all 3 LEDs to pull 2.5V or just the blue to pull 1.38V. More importantly, it limits amps for all 3 leds combined to 17mA or just blue to 12mA. That seems rather low (they should draw 18*3 = 54mA at max brightness), so I tried to briefly run with no resistor. The LCD glows very brightly in a blue-white hue, drawing 89mA, or 47mA for just the blue! Way too much.
            • 18 ohm gets me 2.6V combined or 1.4V blue. 8.2 ohm gets me 2.7V (44 mA) and 1.42V (29mA) blue. 3.9 ohm gets 2.86V (60mA) and 1.45V (37mA). I don't understand how blue could draw 37mA at 1.45V when the spec sheet says it's meant to run at 3.1V atn 18mA, so I must not be understanding the spec sheet somehow (maybe the volt numbers only work when all 3 LEDs are running?). Either way, blue looks overly bright at 37mA so I'll trust the 18mA figure is correct and I don't want to run it too close to 18mA.
            • As I said, at 8.8 ohm, RGB draws 44mA, but just B draws 29mA. I moved my volt meter to measure just the R- and G- lines when all 3 were running and they're showing 28mA combined, which means blue is pulling 44-27=17mA, a bit more than the 1/3 * 44= 14.6mA it should be drawing, which might explain why the LCD gets a blue hue with all 3 LEDs lit. I moved my meter to B- and measured 17mA with RGB on and 28mA with just B on, which is way more than the 18mA max.
            • After a lot more experimentation, I decided on these values:
              • No resistor on A+
              • 27 ohm between B- and ground
              • No resistor between R- and ground (it already has a 100 ohm resistor hard wired on the LCD board)
              • 1k ohm (1000 ohm) between G- and ground.
              • This results in 13.8 mA drawn by B, 12.9 mA by R, and 1 mA by G with RGB on or with just G on. Red and blue turn off when the dashboard is dimmed. Green light takes amazingly little power to produce so even at 1mA the display is easily visible at night. You can even push it down to 0.46mA with a 2.2k resistor and it's still readable, though I would say at that brightness it's noticeably harder to read.
            • Note that I originally left just B on at night but something about the darker shade of blue creates too little contrast against the black text, making it hard to read. This is probably why car dashboards are so often green, white, or bluish white.
            • Unless we run 9 wires to the display and find a 9 or more wire connector to plug those wires into, we only have one wire that can be used to turn the red and blue backlights off when the dashboard is dimmed. That means the green backlight must be wired to be always on. I suppose using a DB9 connector and cable instead of ethernet would conveniently give you the 9 wires you need, but it may be hard to find a long DB9 that isn't thick and heavy, and the plug on the DB9 is inherently somewhat heavy. The plug plus the cable might be heavy enough to tilt the LCD. 9-pin mini din might be lighter.
            • Since text is still easy to read with green drawing only 1mA, even if you forget to unplug the LCD it will take 31924 hours to drain an 80 amp hour aux battery by 20% according to this site. Unfortunately the arduino itself and the LCD electronics also draw power, but I haven't yet measured how much since it requires connecting the volt meter probes from the 12V pin in the OBD port to the power pin on Arduino without plugging in the OBD cable while still somehow connecting CAN high/low and ground.
            • Since I thought green would be brightest at any given power, I thought maybe I could turn on all 3 LEDs and then use analogWrite() to cut the voltage down low enough that green would remain lit at 1mA and other LEDs would be so dim they may as well be off. Unfortunately, even with no resistor, green LED pulls 1mA at analogWrite(10) but other LEDs are still fairly bright. In fact, despite blue running through a 27 ohm resistor, the screen has a blue tone to it instead of a green one, so it could be that blue is actually brighter than green at any given power.
            • This got me thinking I could add some components to cut the red and blue voltage to 0 below a certain analogWrite threshold and let green remain lit until analogWrite(0) was called. This thread suggests a Supervisor/Reset chip can be used. I'm guessing you might also need a capacitor to buffer the analogWrite PWM output to a more steady voltage or the reset chip might keep tripping as PWM drops briefly to 0 a few hundred times per second. At this point I don't want to take the time to figure it all out, but if turning off the green backlight is important to you, a reset chip or similar might be a solution. The chip would have to cut voltage to R- and B- paths whenever analogWrite was called with a low enough value, say below 128. The resistor on G- could be reduced to keep green at equal brightness to the other LEDs and then analogWrite could be used to lower the voltage until green uses 1mA or whatever you want it to use at night.
      • When you're done testing your LCD, here's how to wire the 1/4 size breadboard on the LCD end of the ethernet wire:
        • I used the 1/4 size Sparkfun breadboard. It's kind of expensive for its size, but it is nice that each numbered row of five solder points on either side of the divide in the middle are connected together just like on a prototyping board.
        • There are only 15 rows, which means the 8 pins on the ethernet jack and the 8 pins of the 4050 5V to 3.3V voltage converter chip won't fit without one pin overlapping. The pin I overlapped is pin 8 (ground) on the 4050 chip, so I had to make sure the bottom pin on the ethernet jack (connected to hole A8 on the board) was connected to the black wire on the other end of the ethernet cable (the wire that is plugged into the ground header pin on the Arduino). Be sure the half-circle cutout in one end of the 4050 chip is on the row-1 end of the breadboard:
          • IMG_20140503_203748.jpg
        • The ethernet jack I used was pulled off some broken piece of hardware I had and it wasn't meant for soldering to a 0.1" breadboard, but I was able to bend the pins far enough out to make it work. After I double checked each of its pins were solidly soldered to the breadboard and showed 0 ohm resistance through volt meter probes applied to row 8 through 15 in column E and to each corresponding wire coming down from the ethernet jack, I hot glued the jack down and covered the bare wires on the jack in glue:
          • IMG_20140503_205517.jpg
        • Here's how I connected the wires on the daughter board:
          • Put the 4050 chip on rows 1 to 8 with its 1 to 8 pins matching the row numbers (the semi-circle notch at one end of the chip is at row 1, and the pin to the lower left of the notch when viewed from above the chip is pin 1).
          • The resistors and black banded wires in the pictures above do not match the wiring I will describe below because I changed the design after taking those pictures.
          • Ethernet jack rows:
            • Remember that columns A-E and F-J are all permanently connected together on each numbered row. If your breadboard doesn't have that feature, you will need to make some additional connections.
            • 15C red wire to 1A
            • 14C orange wire to 8H (connected to pin 9 on 4050)
            • 13C green wire to 7A
            • 12B white wire to 3A (switched to column B instead of C because it made more room to reach every column on row 8, but 12B through 12D are all fine to use)
            • 11B blue wire to 5A
            • Bridge 10 E and 10F with a 27 ohm resistor.
            • Bridge 8C and 9F with a 1K (1000 ohm) resistor.
            • 9B yellow wire to 6H (connected to pin 11 on 4050)
          • Connect the wires from the LCD solder points to these points on the breadboard:
            • 1C red wire (VDD)
            • 7J orange wire (SID)
            • 6C green wire (A0)
            • 2C white wire (/CS
            • 4C blue wire (/RST
            • 5J yellow wire (SCLK on LCD)
            • 8B black wire (GND on LCD)
            • 15D yellow with black band wire (A+ on LCD)
            • 10C red with black band wire (R- on LCD)
            • 9J green with black band wire (G- on LCD)
            • 10G blue with black band wire (B- on LCD)
          • Final result:
            IMG_20140519_224232.jpg
            • I did some modifications to the wiring on the breadboard after gluing the ethernet jack to the back of the LCD, so I can't get any better picture of the final wiring.
      • Wiring on the Arduino side of the ethernet wire:
        • I decided to use an ethernet jack on the arduino side as well. It just dangles over the arduino for now:
          • IMG_20140503_174546.jpg
          • This picture is here just to show the ethernet jack (near the bottom of the picture). Its wires are not plugged into the correct pins in this picture and it's missing a transistor and resistor.
          • You could just as well skip adding this jack and plug the bare wires of an ethernet cable directly into the arduino's headers, but most ethernet wire is thinner than 22AWG and might not fit snugly into the header pins like solid 22AWG does. If your ethernet wire is stranded, you will need to solder it first so it's a solid piece. Alternately, solder the wire to male header pins and plug those header pins in.
          • Note that this ethernet jack (and probably most others) are not intended for wires quite as thick as 22AWG so I had a hard time cramming them in there. Since the normal crimping tool that came with the jacks wasn't strong enough, I used the end of a screwdriver, but it was hard to get the wire deep enough to make solid contact with the little metal V shapes that cut through the wire insulation and touch the wire. Test your jack for how much resistance there is between the jack pins and each wire. 0 to 2 ohms is good, anything higher means poor connection.
          • In my installation, the order of the wires in the ethernet jack didn't matter except for the black one needed to end up connecting to row 8 on the breadboard where pin 8 on the 4050 chip is also connected.
        • Connect the following wires from the ethernet jack to the arduino (you can use the continuity function of a volt meter to figure out which ethernet wire is connected to each color of wire coming out of the breadboard ethernet jack):
          • SID orange wire to pin 6 on arduino.
          • SCLK yellow wire pin A0 on arduino.
          • A0 green wire to pin 8 on arduino.
          • RST blue wire to pin A4 on arduino.
          • CS white wire to pin 7 on arduino.
          • VDD red wire to 3.3V pin on arduino.
          • GND black wire to ground pin on arduino.
        • Unfortunately, you can't power all 3 backlights off a 5V arduino data pin. According to this thread, you shouldn't try to pull more than 20mA through a data pin or you risk damaging the logic circuitry in the Atmega chip. The three backlights together pull about 26mA with the resistors I chose - too much for a data pin. So we need to power all 3 backlights from the main 3.3V power line and use a transistor to control when power flows to the red and blue backlights.
        • On the Arduino side of the ethernet wire, connect whichever wire ultimately leads to row 10 on the breadboard to the collector pin of a PN2222 or 2N3904 NPN transistor.
        • Connect the emitter pin of the transistor to either ground (GND) header pin on Arduino.
        • Connect the base pin of the transistor to a 2.2K resistor, and connect the other end of the resistor to Arduino header pin 3.
      • Fully connected transistor/resistor looks like this:
        IMG_20140519_194725.jpg
      • Hot glue all the exposed wires but leave the transistor and resistor uncovered since they need to shed heat. I carefully bent the pins so the final result is as flat as possible, making it easier to fit into an enclosure:
        IMG_20140519_202948.jpg
        • Now, whenever pin 3 is set HIGH, the transistor allows current to pass from its collector to emitter pins and the B and R LEDs turn on. When pin 3 is set LOW, B and R turn off. The 2.2K resistor is basically there to limit how much of the current that runs from collector to emitter can push through the base pin, the resistor, and into pin 3.
        • With this design, the green backlight is always on. When the dashboard isn't dimmed, the red and blue backlights turn on at full brightness. The green backlight remains dim, which gives the overall color a purplish hue that you may or may not like. Either way, you only see the backlight color during the day when a shadow passes over the display.
      • After finishing the daughter board, I hot glued the other side of the ethernet jack to the back of the LCD at an offset so the two would stand upright at the correct angle on the Prius dashboard:
      • IMG_20140503_213643.jpg
      • Of course once you plug in the ethernet cable and the car starts moving, it won't keep standing on its own, so I glued it down to cardboard as a temporary mount. Putting 6 globs of dried hot glue under the cardboard worked remarkably well to keep it from sliding. I think they worked better than rubber feet.
      • IMG_20140503_232809.jpg
      • Note that I don't think it's safe to plug or unplug the ethernet cable or the DB9 cable while the Arduino is powered because neither cable has the ground pin positioned to ensure it connects before the voltage pins. Always connect or disconnect power using the OBDII plug.
      • Here's the latest display as of 6-16-14:
        • IMG_20140614_090318.jpg
        • From upper left to lower right it's got:
        • Electric bar. Filling the left half means current is charging the traction battery, while filling the right half means current is flowing from traction battery. The bar is adjusted to ignore power drawn by air conditioner. Keeping the bar unfilled gets you Warp Stealth (aka glide) because anything above 3A or below -3A shows 2 pixels filled. The right half is scaled so it should fill just before the gas engine starts.
        • Gas engine bar. Shows minimum 2 pixels whenever gas engine is running. First mark on the left is 10k requested power, second mark is 15k, third 20k, full is 25k. Right half of the bar fills from 26k to 45k and represents increasingly less efficient use of gas engine. There is no attempt to scale this bar to where the electric assist will turn on since once you head into the right bar, it's likely you no longer care about being efficient and simply need the power. Trying to run the gas engine as high as possible without starting the electric motor is an inefficient state so I don't see much value in representing it even though the normal HSI bar is supposedly scaled to represent that point before it starts filling the "pwr" section.
        • Traction battery charge icon. It usually matches what you see on the MFD but tests have shown the MFD is slightly fluid about mapping charge percentage to number of battery bars and it's not clear what rules its using, so I can't match it exactly.
        • Door open indicator. Left arrow indicates left side driver door open in the picture. Right arrow would indicate passenger front door. Down with left/right arrows all at once indicates trunk or rear door open. Unfortunately the ECU only provides one bit to indicate any of the three rear doors are open.
        • Amps (- amps means traction batt is charging, + means traction batter is discharging)
        • Gas engine power requested in killowatts (k). __k means gas engine is either off, or if it's running it's not because you're pressing the pedal (it may run without pressing the pedal to provide heat to the cabin, raise the engine temperature to at least 46C, or charge the traction battery when it gets too low).
        • Accelerator pedal pressure from 0 to 200p.
        • Instantaneous MPG (m).
        • Aux battery voltage (140V means 14.0V). This is always 14.0V when my car is started (ready mode) which makes it useless while driving, so to save CAN bus bandwidth, it's only updated when the gear shift is not in Drive or Brake. As far as I can tell, this display only provides a useful value when car is in IG-On.
        • Fuel ignition timing (55T means 5.5ms fuel bursts).
        • RPM (followed by E for electric drive, G for gas, or C for combined)
        • Gallons of gas in tank (92g means 9.2 gallons). This is a rough estimate and should not be relied on to push the tank to nearly empty before you fill it. I saw it vary by a full gallon with the car in IG-on not moving on a level surface and it's actually risen over 2 gallons while driving (so far it hasn't risen over 3 gallons). At one point it said I had 0.3 gallons left but the 11 gallon tank only let me put in under 8 in warm weather, so it really isn't accurate.
        • Amps used by air conditioner/heater (0AC means no amps being used).
        • IGN aka ignition timing advance. 145I means 14.5 and I think the units are milliseconds to ignite the fuel before the piston is at a certain point. Supposedly 130I and 140I are best for fuel economy but it's really hard to get that low. -100I indicates you're in the forced warmup mode the car always enters for about 60 seconds when first started. I think -85I may indicate the engine is forced on because its temperature has gotten too low.
        • The number directly below IGN is throttle open percent (22t means 22%). 140I and 18t is supposedly one form of "Super Highway Mode".
        • The six numbers in the lower right are all temperatures in Celcius.
          • "ra" is radiator (aka coolant), "cv" is converter, "m1"/"m2" are motor generator 1 & 2 (the inside and outside planetary gears in the transmission), "i1"/"i2" are inverter 1 and 2 (I think they handle carrying electrical power to and from the electric motor generator 1 & 2 - note that "motor generator" refers to the fact that either one can be used as a motor to turn its planetary gear or a generator of electric power).
          • A mechanical temperature-sensitive valve opens at 86C to flow more coolant in the radiator so you will often see the "ra" temperature rise to 86C and then stick around there.
          • A warning exclamation point will appear next to an "ra" over 91, "m1"/"m2" over 65, or any other temp over 55 (those are based on the redline values from the priidash project). An "OVERHEAT" message will replace the top line of the display if any temperature reaches 99 or above.
    • I was going on a long trip and really wanted this HSI bar working before I left, but my OBDII to DB9 cable hadn't arrived. As I mentioned, jamming wires into the OBDII port didn't work, so I soldered some wires to another OBDII device I had. That was fine except I plugged them into the holes on a DB9 cable and plugged that into the CAN shield. That was also fine until I bent the wires down around the DB9 connector and covered them in electrical tape to make sure they didn't short anything... Ha ha. I didn't consider that by bending them, all 3 wires would short to the metal collar of the DB9 connector. So I had CAN H, CAN L, and GND all shorted together and the car immediately showed a red triangle with exclamation point, check engine light, and the gas gauge and all the squares around gear shift indicator began flashing.
      • Restarting the car fixed the flashing, but check engine and evil red triangle exclamation were still lit. Android Torque app with an ELM27 OBDII device showed the following DTC codes:
        • P0A1D Powertrain
        • U0100 Network
        • U0111 Network
        • U0293 Network
      • These trouble codes actually cleared themselves after 10 minutes, except I had to cause the problem two more times (leading to the same codes) before I figured out what I'd done to cause it (my electrical taped monster actually didn't short things immediately so it was very confusing). After it happened two more times, the car seemed unwilling to clear the codes on its own and only Torque could clear them.
      • I got rid of the DB9 cable and connected wires via solder and clips directly to the GND, CAN H, and CAN L solder pads on the CAN shield.
      • Ironically, my wife still managed to short the CAN H and GND wires together with her leg while we were driving (there was so little wire exposed I didn't think they could possibly touch - ha ha) and the car immediately stopped responding to gas and logged those same four DTC codes. Luckily we weren't in traffic.
      • So anyway, I highly discourage using MacGyvered cables. At least have Torque at hand or some other device like Mini VCL that can clear trouble codes.
    How to use HSI+ to get the best gas mileage

    I've read through a lot of threads and advice on mileage. So far, I haven't been able to replicate everything that's been claimed, like Super Highway Mode, and even Pulse and Glide doesn't seem to get me any decent numbers. Hobbit's "sweet spot" article is the most well researched thing I've read, but it's missing some critical information. For example, he says that pushing 15kw (15k on HSI+) should yield 52mpg on straight and level, whereas I only see about 45mpg at 60mph. Then I noticed 15k seems to reliably get me an mpg that equals about 0.75 * mph. 0.75 * 70mph = 52mpg, so I tried 70mph and I do get 52mpg (although my timing is still 63 instead of the 60 Hobbit says it should be).

    The problem is that going 70mph at 52mpg isn't that great unless you can push the overall average well over 60mpg by gliding down to say 60mph each time you reach 70. The problem is that I lose speed very quickly at 70, and applying 15k acceleration at 60mph is only 45mpg, so I get 45mpg that gradually moves to 52mpg as I pulse from 60 to 70, then I get infinite mpg for a short time as I drop back to 60, and repeat. I don't see how that can average to over 60mpg in the "long averages" Hobbit mentions. It's possible I lose speed too quickly because I'm not running thin transaxle oil or whatever other modifications can improve glide time. I do run 50 psi in the tires.

    What I found to be more valuable is that 11k gets you mpg = 1*mph. So I was able to hold 11k to go 60mph at 60mpg on straight and level assuming lack of headwind and reasonably warm air, and my speed did not drop. What I found more odd was that before I tried 60 at 60 (which Hobbit mentions briefly) I was applying 13k to hold 53ish mph at 49ish mpg, and my speed seemed to be steady there. Maybe I'm mistaken and speed was gradually increasing, but it really felt like using more power for less mpg and less sustained speed. I had to kill my mpg to get up to 60mph, but once at 60mph, getting 60mpg is pretty great, at least compared to what I used to get.

    This article for beginners describes the effect I think I was seeing: "Most Prius drivers have experienced an increase in current fuel economy when they back off the gas and still are able to maintain the same speed. By lifting up on the pedal, the driver told the computer to change into a higher gear and lower RPM into a more efficient state." This is incredibly important for getting better fuel economy without sacrificing anything, and it's something I never realized on my own in 10 years of driving the car (I did experiment with all this 10 years ago but the info I found online was pretty limited at the time). You would think the Prius would be able to do that low-RPM optimization itself, but maybe it can't without knowing things like you're on straight and level.

    Then there's 25k which gets you mpg = 0.5 * mph at higher speeds. Not useful on straight and level, but necessary uphill. Going up highway 18 into the San Bernardino mountains is about as steep a grade and they tend to put on a highway and I noticed that holding 25k at 30mph got me 15mpg and a stable speed (again, maybe very slowly increasing, but it seemed stable at least in the short term). What was surprising is that 25k at 40mph was 20mpg (0.5*40) and it would hold that speed, so it's like getting 5 extra mpg ant 10 extra mph for free. I tried to go to 50mph at 25k but suddenly the rule broke down and I didn't get more than 20mpg, in fact I may have gotten less. So there's some balance point where pushing too hard against gravity (going up a hill) or against air resistance (which increases exponentially with speed) gets you poorer mpg than you should get. Up until that balance point, going faster can actually increase your mpg. Counter intuitive, and very interesting.

    For acceleration from a stop in city driving, I've read a few suggestions of keeping mpg = 0.5 * mph. But if you hold about 11kw from a stop, you can accelerate at mpg = 1 * mph. At first glance that seems obviously twice as good. But it also means it takes longer to reach the speed limit, so it could be that you're spending more absolute time at lower mpgs. I assume someone's done the experiments and decided mpg = 0.5*mph is more efficient, but I haven't read of any actual experiments or reasoning behind it, so I plan to do my own tests. Once you're up to the speed limit, it seems like 11k or whatever is necessary to hold that speed is obviously going to be as good as you can do for mpg. Trying to any kind of 15k pulse and glide between stop lights is probably counter productive as your high speed pulse gets cut off by the next red light. Perhaps it can be done on a familiar route with lighter traffic.

    Then there's SHM (Super Highway Mode), the magical engine state that's supposed to give 70-90+ mpg at 45-52ish mph, depending on wind and air temperature. This thread goes on at length about it, and most seem to agree you enter it at 14IGN and 18TPS on scangauge (140I or 145I and 18t on HSI+). I've tried to hit that and failed, getting only as close as 145I or 150I at 22t and my speed was getting really low on the highway so I gave up. I'll probably try again later, but I think SHM is something only valuable on long, flat roads with little traffic and warm weather. Some people say they use SHM as a prolonged glide after pulsing up to a higher speed. The beginner's article has a section that lists different levels of SHM in terms of RPM and he says to start at 50-55mph and hold one of those levels "as long as you can" while you lose speed, then accelerate back to 50-55 at 1600rpm, 18t and repeat.

    I still wonder if using some variation on Hobbit's technique would work. Maybe instead of losing speed fast, I need to enter SHM so I don't lose speed so quickly. The real problem is that living in socal, the freeways around me are so crowded that it's hard to do any form of pulse and glide without feeling like other drivers will be hugely annoyed. Using glide while going down a slight hill is the best time to use it, but usually a car will be in the way so I have to regen brake and there goes probably all the fuel efficiency gains I might have built up (charging and discharging the battery loses a lot to heat). That or the hill is too long and I develop too much speed and risk a huge speeding ticket. So I think I'm stuck with 60mpg at 60mph for most of my freeway driving, but that's not such a bad thing. I achieved slightly over 50mpg on my last tank and that's a huge improvement over the 36ish I was getting before. An unknown percentage of that improvement came from replacing my shocks, spark plugs, HSV valve, transaxle oil (with factory spec stuff), coolant, and overinflating my tires to 48-50psi.
     

    Attached Files:

    #38 Chris Dragon, Apr 24, 2014
    Last edited: Jun 16, 2014
    protate and NortTexSalv04Prius like this.
  19. alexmol

    alexmol Junior Member

    Joined:
    Feb 24, 2011
    21
    22
    0
    Location:
    Portugal
    Vehicle:
    2005 Prius
    Model:
    N/A
    Hi everyone!

    I think Chris has already done a great work and got almost everything covered! Congratulations!

    I continued to slowly develop some features and have a new public release version for my original HSI bar now under Arduino IDE 1.0.

    You can find it here: Release Public Release 2.0.1 · avataranedotas/HSI-bar_Prius2G-Arduino · GitHub

    Just one issue that might have escaped Chris:
    I found out that in my original code the ICE RPM overflowed at 4096 RPM and started to display negative values between 4096 and 5000 ICE RPM.
    I tracked the cause to the message.data[] variables that are only 8bit unsigned integers, you need to convert them to int or long before doing math.

    Hope I've helped some people to enjoy more their Prii and get better MPG!

    I won't be working on more HSI bar development as I know have an EV as garage mate to the Prius. I'll be trying to get more info out of the EV!

    Best Regards
    Alexandre
     
    #39 alexmol, Mar 21, 2015
    Last edited: Mar 21, 2015
    smilyme and usbseawolf2000 like this.