Tải bản đầy đủ (.pdf) (10 trang)

Practical Arduino Cool Projects for Open Source Hardware- P36 docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (292.64 KB, 10 trang )

CHAPTER 15  VEHICLE TELEMETRY PLATFORM
provide 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
GND 1 GND Ground Display ground connection
+5V 2 VCC Power Display +5V connection
Digital OUT 6 3 Vo Contrast Contrast adjustment voltage
Analog IN 0 4 RS Register Select Data (HIGH)/Control (LOW)
GND 5 R/W Read/Write Read (HIGH)/Write (LOW)
Analog IN 1 6 E Enable Enable byte/nibble transfer
7 D0 Data0 Data bit 0
8 D1 Data1 Data bit 1
9 D2 Data2 Data bit 2
10 D3 Data3 Data bit 3
Analog IN 2 11 D4 Data4 Data bit 4
Analog IN 3 12 D5 Data5 Data bit 5


Analog IN 4 13 D6 Data6 Data bit 6
Analog IN 5 14 D7 Data7 Data bit 7
329
CHAPTER 15  VEHICLE TELEMETRY PLATFORM
(Transistor) 15 VB1 Backlight power Backlight +5V connection
GND 16 VB0 Backlight ground Backlight ground 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

contrast. Or if your LCD supports it, you can hard-wire this pin to GND for maximum contrast, as we did
in the Water Flow Gauge project.
LCD pin 15, the backlight + supply, connects to a transistor that, in turn, is controlled by the
Arduino. Arduino outputs can’t supply enough current to drive the backlight directly, so the transistor
allows a PWM output to control the backlight supply without danger to the CPU.
330
CHAPTER 15  VEHICLE TELEMETRY PLATFORM
Just 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.

331
CHAPTER 15  VEHICLE TELEMETRY PLATFORM

Figure 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
windshield by laying the display horizontally on top of the dashboard and mirroring the image vertically.
Don’t try to bite off more than you can chew in one go, though. Work at getting the basic system
operational first, then extend it with more exotic modifications. And remember that for initial testing at
least, it’s probably safest to keep the whole unit totally out of sight of the driver so you’re not tempted to
332
CHAPTER 15  VEHICLE TELEMETRY PLATFORM
play 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).

333
CHAPTER 15  VEHICLE TELEMETRY PLATFORM

Figure 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
back panel
The simplest approach to mounting the VDIP1 would be to put it directly on the prototyping shield
with the USB connector protruding through the back of the case, but we wanted the connector on the
front so we chose to separate it from the prototyping shield and mount it on a sub-board. We used a bit
334
CHAPTER 15  VEHICLE TELEMETRY PLATFORM
of 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.
335
CHAPTER 15  VEHICLE TELEMETRY PLATFORM

Figure 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).



Figure 15-29. Connections to the LCD module and menu buttons
336

CHAPTER 15  VEHICLE TELEMETRY PLATFORM
The 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
337
CHAPTER 15  VEHICLE TELEMETRY PLATFORM
That’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
project at the same time and using a source code management system, it minimizes the risk of getting in
each other’s way.
Another motivation for structuring it this way is that the original OBDuino32k codebase is designed
to fit within the 32KB of memory (less bootloader) of an ATMega328 CPU, like the ones used in a
Duemilanove. Just about all available memory is used and the project only barely fits, so the intention is
338

×