Unlike the Water Flow Gauge project, though, we will also control the backlight from the Arduino rather than hard-wire it to a fixed level using a resistor.. Almost all the connections t
Trang 1provide the specific features required by the project, all to reduce memory usage This is a classic
situation where a prewritten library might make things simpler from a development point of view, but in the end it just takes up too much space and needs to be replaced by minimal custom-written functions Just as in the Water Flow Gauge project, we’re going to drive the LCD in 4-bit mode to save on
wiring and I/O pins, but the MPGuino/OBDuino codebase on which we based this project also includes
a couple of extra features that are quite handy: backlight control and contrast control
If you are going to leave your car engine datalogger permanently connected, it’s important to
minimize the power it drains from your car battery while the engine isn’t running, and an LCD backlight can use a significant amount of power MPGuino/OBDuino includes a display-blanking feature that uses
a transistor to turn on the display backlight only when it’s needed, and then blank it when the engine
isn’t running It also uses PWM (pulse-width modulation) from an Arduino digital pin to vary the
brightness, giving you more than simple on/off backlight control
The LCD needs to be wired up in almost the same way as the display in the Water Flow Gauge
project, using a strip of ribbon cable to connect ground, +5V, RS, Enable, and D4 through D7 Unlike the Water Flow Gauge project, though, we will also control the backlight from the Arduino rather than
hard-wire it to a fixed level using a resistor The pin assignments are given in Table 15-6
Table 15-6 Connections from Arduino to HD44780 LCD module
Arduino Pin LCD Pin Label Name Description
Trang 2(Transistor) 15 VB1 Backlight power Backlight +5V connection
With the LCD laid out next to the prototyping shield, the pin assignments shown in Table 15-6 should have the LCD connections lined up nicely with the shield connections as in the schematic, allowing you to use a flat piece of ribbon cable to connect one to the other Almost all the connections to the Arduino will be in a row on one edge of the shield, so for convenience we connected the ribbon cable
to a length of male breakaway header strip so it can be easily removed It might look strange connecting the data lines to analog inputs, but in the software those inputs are switched to digital output mode and used as regular digital pins
To keep things neat, we cut off a 20-pin length of header strip so that it would run all the way from the +5V connector and adjacent GND pin, across the gap to the A0–A7 connector, and then across the next gap
to the A8–A15 connector The pins in the gaps between the connectors are unused, of course, so they can
be pulled out of the plastic strip with a pair of pliers Pins A8, A9, and A10 are used for the menu buttons, as described in a moment Figure 15-22 shows that the wire for those buttons has already been connected
Figure 15-22 The LCD module connected to the male break-away header strip
That takes care of most of the connections, with the exceptions of pin 3 (contrast) and pin 15 (backlight power) on the LCD
We connected LCD pin 3, the contrast control pin, to the center connection of a 10K variable resistor with the other two legs of the resistor connected to GND and +5V so that we could manually vary the contrast
An alternative is to connect LCD pin 3 instead to Arduino digital I/O line 6, which can operate as a PWM output The software can then control the LCD contrast by adjusting the PWM ratio, with an output level of 0 (low) giving highest contrast, and an output level of 255 (high) giving minimum
Trang 3Just about any small PNP switching transistor should work as long as it can handle the current
required by your LCD module If your LCD draws less than 100mA, you can use something like the
extremely common BC557 or 2N2907 Some backlights can draw more than 200mA, which means you’ll need to use a slightly higher rated transistor such as a 2N3906
We mounted the transistor and resistor directly on the back of the LCD, with the lead from the
resistor to Arduino digital pin 5 running to a male breakaway header We soldered a short length of
female header to the top of the prototyping shield to allow the connection to be easily removed
Logging Control Button and Status LEDs
We wanted a simple way to turn logging on and off, and a pushbutton works very nicely when combined with an interrupt input By using a button with a center LED, it’s possible to have it display the current logging status, so we chose a button with a blue LED mounted in it You could, of course, simply use a
separate LED and a regular button, but having them integrated into a single unit makes the result look a bit nicer and makes it more obvious that the logging state and the button are associated
The button connects between ground and Arduino digital I/O line 3 using a 1K resistor I/O line 3 is also connected to +5V via a 20K pull-up resistor inside the ATMega CPU itself The internal pull-up
resistor is activated in the software by setting the pin to INPUT mode and then performing a
digitalWrite() to set it to a HIGH state, so when the switch is open (off) the input will be biased high
When the switch is closed (on) the input is pulled low through the button via the 1K resistor
Because it’s only a momentary-action button that is on while pressed, sensing the mode is not quite
as simple as checking the state of the input on each pass through the main program loop Instead, the
button is connected to digital I/O line 3 so that we can attach an interrupt to it in the sketch, and when the input transitions from a high (unpressed) state to a low (pressed) state, an ISR (interrupt service
routine) is called The ISR simply sets the output driving the status LED appropriately to either high or
low, turning the LED on or off It also includes some debounce logic that checks the time that has passed since the button was last pressed so that as the mechanical switch contacts settle, the CPU doesn’t
interpret them as multiple button presses
Rather than set a logging status flag in a variable, we used a little trick that allows us to use the status
of an output pin as a flag: even though the logging status LED is connected to an I/O line in “output”
mode, we can still use digitalRead to read whether the output is high or low The status LED itself,
therefore, acts as a sort of hardware status flag for the software!
One other advantage of using a momentary button to toggle the logging state and an LED to indicate the current state is that it’s possible to turn logging on or off in the sketch and have it accurately reflected
by the LED With a simple on/off switch, you can end up with a situation where the switch is in an “on” position but logging has been turned off by some software event, while a pushbutton that toggles the
state on each press by inverting a flag will always do the right thing
The system has a total of four status LEDs including the one mounted in the center of the “Log”
button They aren’t strictly necessary, but when the system is running in your car and you don’t have a laptop plugged in, it can be handy to be able to see what state the system is in just by glancing at the
LEDs You could, of course, display the same information on the LCD module if you prefer, but using
LEDs keeps the LCD free to display current vehicle data The connections are all shown in Figure 15-23 Remember that the 20K resistor shown in the schematic doesn’t need to be fitted to the shield because it’s contained within the CPU and is activated by the sketch
Trang 4Figure 15-23 Schematic of logging control button and status LED connections to the Arduino
You will need to assemble the status LEDs and logging button to suit your particular case We glued ours
in place on the front panel of the project box as described next
Mount in Sub-Assemblies in the Case
How you mount everything will depend on whether you’re aiming for a permanent installation or
something you can connect temporarily in any car, and whether you’re intending to use the Vehicle Telemetry Platform to provide real-time feedback on driving style or mainly to log data for future analysis
To provide visibility of the display directly within the driver’s line of sight, some people on the
EcoModder forums have even experimented with making head-up displays that reflect information in the
Trang 5play with it while trying to drive It’s best to bring along a passenger or have someone else drive on your
first trip with the system so one person can drive while the other checks that it’s working as expected
For our prototype, our emphasis was on an easily removable device so we fitted everything inside a PVC project case that makes it fairly bulky but quite durable An alternative would be to fit the Vehicle
Telemetry System permanently into your dash, with the display and control buttons fitted into the dash surface or into a blank plate designed to fit a radio mounting location Remember, though, that a unit
sitting on a seat or in the passenger’s lap will be fairly well protected from vibration while a permanently fixed system will need to have all nuts held in place with lock-washers or thread-locking glue
We wanted to use it mainly to store data and analyze it later, so visibility of the display while driving wasn’t particularly important We fitted the LCD module into the top of the case, which is fine if it’s
sitting on a seat beside you and you only look at it occasionally while stationary If you want to view the display while driving, it would work better mounted in the end of the case so it could be placed up near the driver’s line of sight Remember to always keep safety in mind when using a device like this and don’t try driving around only half watching the road because you’re distracted by an awkwardly mounted
display that’s sliding around on the seat beside you
For our prototype, we mounted the ELM327 interface adapter’s PCB vertically in the back corner of the case with 6mm spacers holding it clear of the side, and M3 nuts and bolts keeping it secure Because the existing holes in the PCB were very large, we used plastic washers to provide a large enough contact area to overlap the holes on both sides of the PCB (see Figure 15-24)
Figure 15-24 The ELM327 OBD-II adapter mounted in the case
The DB9 socket was also mounted in the rear panel with the female header fitted to the 8-pin male header on the PCB (see Figure 15-25)
Trang 6Figure 15-25 The DB9 socket for OBD-II cable mounted in the case
For our prototype, we fitted the Arduino Mega into the bottom of the case using 6mm plastic spacers and 15mm M3 nuts and bolts, with plastic washers on top of the Arduino to prevent short-circuits caused by the nuts A hole was cut into the back panel to allow the USB socket to protrude, making it easy to reprogram the unit with everything mounted in the case or to connect a laptop for monitoring data via the USB connection while driving (see Figure 15-26)
Figure 15-26 The Arduino Mega mounted on plastic spacers with the USB socket protruding through the
Trang 7of scrap veroboard and soldered some female PCB-mount headers to it, soldered short lengths of ribbon cable to the pins that need connections, and used two-part epoxy to glue it into the case so that the
module sits with the front of the USB socket just protruding through the front panel (see Figure 15-27) Remember that the USB socket will take all the mechanical load of the USB memory stick plugged into it including weight, shocks, and vibration Make sure it’s firmly mounted and use a memory stick
that’s as small and light as possible—definitely don’t hang your keychain from the memory stick while it’s plugged into the system!
Figure 15-27 The VDIP1 module mounted on a sub-board with the USB socket protruding through the
front panel
Next, we mounted the LCD assembly prepared earlier into the top of the case Cutting out the
rectangular hole for the LCD was quite tricky, but a panel nibbling tool intended for cutting odd shapes
in thin metal helped keep things straight The edges were cleaned up with a craft knife and the end result was about as neat as can be expected when working with hand tools Holes were drilled for the three
menu buttons (referred to as left, middle, and right in the sketch) and for mounting bolts for the LCD,
which was held in place with 6mm plastic spacers to keep the face recessed just behind the case surface (see Figure 15-28)
The position of the LCD and buttons were carefully selected to allow enough clearance inside the
case for the VDIP1 module and the prototyping shield
The menu buttons couldn’t be wired up to the LCD assembly and header until it was fitted in the
case, so next we connected one side of each button to the ground connection on the LCD and then used ribbon cable to link the other side of the left, middle, and right buttons to analog inputs 8, 9, and 10,
respectively
Trang 8Figure 15-28 The LCD and menu buttons mounted in the case
The result is a self-contained assembly that can be plugged into the prototyping shield or removed with no soldering required, which is very handy when working on the Vehicle Telemetry System because
it means you can put the cover aside without it being awkwardly linked to the rest of the unit with short wires (see Figure 15-29)
Trang 9The prototyping shield can then be fitted, containing the power supply and connections for the LCD, buttons, and VDIP1 module The huge 4700uF capacitor attached to the power supply also needs to be
mounted We used foam tape in our prototype, which seemed reasonably secure, but you could also use a dab of epoxy glue or similar to make sure it definitely won’t move even with a lot of shock or vibration
The GPS module slipped in neatly on one side and attached sturdily to the side of the case with
more foam tape (see Figure 15-30) Keep in mind that for optimum performance the GPS antenna (the ceramic square on the LS20031) needs to be pointed at the sky and not be blocked by metal, so think
about how the case will be mounted and try to put the GPS on top if possible
Figure 15-30 The prototyping shield mounted on Arduino, the 4700uF capacitor taped to the case, and
the GPS module attached with foam tape
The “logging on/off” pushbutton with center-mounted LED was hard-wired to the prototyping
shield with short lengths of ribbon cable As you can see in Figure 15-31, we glued the button in place,
being very careful not to get glue on the moving part and only on the case
We also glued the LEDs in place after rubbing the end of each one flat using fine sandpaper on a flat surface Doing this squares off the end of the LED and gives it a frosted surface that diffuses the light
nicely, and the flat face then sits flush with the surface of the front panel You could alternatively use
mounting bezels if you prefer
Figure 15-31 The Logging button and status LEDs glued into the front panel
Trang 10That’s it! The hardware is now complete and you can plug in the LCD, fit the lid, and screw it together Our complete prototype is shown in Figure 15-32
Figure 15-32 The complete system assembled in a case with USB memory stick attached
You have a number of options for mounting the system in your car Self-adhesive velcro is a good option, allowing you to attach the box to a handy flat surface such as the center console or on top of the dash Just remember that cars can become extremely hot when left parked in the sun, so don’t leave it on top of the dash when the car is parked on a hot day
OBDuino Mega Sketch
The Vehicle Telemetry Platform uses a complex sketch called OBDuinoMega that’s still undergoing rapid development, as are the MPGuino and OBDuino32k codebases from which it is derived It’s quite likely that by the time of going to press, the code will have developed well beyond what is presented here The fundamentals should still be the same, though, so rather than provide line by line commentary on all 4500+ lines of code, we’ll skip through most of it and just discuss the interesting sections The full source
code is available for download from the project page on the Practical Arduino web site
The sketch itself is split into a number of different source files If you download the project
directory, copy it into your sketchbook directory, and open it in the Arduino IDE, you’ll see that there are
a number of tabs across the top instead of just a single tab as you see in most projects Each tab is a separate file There are several reasons for splitting up the code this way, but probably the most
important is to provide conceptual encapsulation of the different sections of the code Large software projects almost always divide their code between multiple files because it makes it easier to find the particular functions you’re looking for, simplifies the main code, and therefore makes it easier to
understand the overall flow of the program In addition, when multiple programmers are working on the