ee 477 final report · web viewthe mplab ide available on microchip’s website is being...
TRANSCRIPT
ECE 477 Final ReportSpring 2006
Team Code Name: __________Brightriders_______________________ Team ID: ___13__
Team Members (#1 is Team Leader):
#1: ____Joe Waugh______________ Signature: ____________________ Date: _________
#2: ____Evan Zelkowitz__________ Signature: ____________________ Date: _________
#3: ____Matt Cozza _____________ Signature: ____________________ Date: _________
#4: ____Elmer Chao_____________ Signature: ____________________ Date: _________
ECE 477 Final Report Spring 2006
REPORT EVALUATION
Component/Criterion Score Multiplier Points
Abstract 0 1 2 3 4 5 6 7 8 9 10 X 1
Project Overview and Block Diagram 0 1 2 3 4 5 6 7 8 9 10 X 2
Team Success Criteria/Fulfillment 0 1 2 3 4 5 6 7 8 9 10 X 2
Constraint Analysis/Component Selection 0 1 2 3 4 5 6 7 8 9 10 X 2
Patent Liability Analysis 0 1 2 3 4 5 6 7 8 9 10 X 2
Reliability and Safety Analysis 0 1 2 3 4 5 6 7 8 9 10 X 2
Ethical/Environmental Impact Analysis 0 1 2 3 4 5 6 7 8 9 10 X 2
Packaging Design Considerations 0 1 2 3 4 5 6 7 8 9 10 X 2
Schematic Design Considerations 0 1 2 3 4 5 6 7 8 9 10 X 2
PCB Layout Design Considerations 0 1 2 3 4 5 6 7 8 9 10 X 2
Software Design Considerations 0 1 2 3 4 5 6 7 8 9 10 X 2
Version 2 Changes 0 1 2 3 4 5 6 7 8 9 10 X 1
Summary and Conclusions 0 1 2 3 4 5 6 7 8 9 10 X 1
References 0 1 2 3 4 5 6 7 8 9 10 X 2
Appendix A: Individual Contributions 0 1 2 3 4 5 6 7 8 9 10 X 4
Appendix B: Packaging 0 1 2 3 4 5 6 7 8 9 10 X 2
Appendix C: Schematic 0 1 2 3 4 5 6 7 8 9 10 X 2
Appendix D: Top & Bottom Copper 0 1 2 3 4 5 6 7 8 9 10 X 2
Appendix E: Parts List Spreadsheet 0 1 2 3 4 5 6 7 8 9 10 X 2
Appendix F: Software Listing 0 1 2 3 4 5 6 7 8 9 10 X 2
Appendix G: FMECA Worksheet 0 1 2 3 4 5 6 7 8 9 10 X 2
Technical Writing Style 0 1 2 3 4 5 6 7 8 9 10 X 8
CD of Project Website 0 1 2 3 4 5 6 7 8 9 10 X 1
TOTAL
-ii-
Comments:
ECE 477 Final Report Spring 2006
TABLE OF CONTENTS
Abstract 1 1.0 Project Overview and Block Diagram 1 2.0 Team Success Criteria and Fulfillment 3 3.0 Constraint Analysis and Component Selection 4 4.0 Patent Liability Analysis 8 5.0 Reliability and Safety Analysis 13 6.0 Ethical and Environmental Impact Analysis 20 7.0 Packaging Design Considerations 24 8.0 Schematic Design Considerations 29 9.0 PCB Layout Design Considerations 3210.0 Software Design Considerations 3611.0 Version 2 Changes 4212.0 Summary and Conclusions 4313.0 References 44Appendix A: Individual Contributions A-1Appendix B: Packaging B-1Appendix C: Schematic C-1Appendix D: PCB Layout Top and Bottom Copper D-1Appendix E: Parts List Spreadsheet E-1Appendix F: Software Listing F-1Appendix G: FMECA Worksheet G-1
-iii-
ECE 477 Final Report Spring 2006
Abstract
The Purdue Solar Racing Telemetry System is a module which communicates with other
modules in the solar car, and relays these communications to a tracking car. The Telemetry
System communicates with the Motor Controller, the Battery Protection System, the Wireless
Packet Modem, the GPS Module, the Maximum Power Point Trackers, and the Driver Interface.
The Telemetry System receives data from all of the connected modules, and transmits this data
wirelessly to a laptop in the tracking car.
1.0 Project Overview and Block Diagram
1.1 Overview
The Purdue Solar Racing Telemetry System is a module which communicates with other
modules in the solar car, and relays these communications to a tracking car. The Telemetry
System communicates with the Motor Controller, the Battery Protection System, the Wireless
Packet Modem, the GPS Module, the Maximum Power Point Trackers, and the Driver Interface.
The Telemetry System receives data from all of the connected modules, and transmits this data
wirelessly to a laptop in the tracking car. This laptop uses a LabView setup to receive and
interpret the data, so that the tracking team can view and log the status of the solar car. This
project is a replacement for the current Telemetry System, which does not have a GPS module,
CAN bus interface, accelerometer, or temperature sensor.
The main features of the Telemetry System are the methods it uses to communicate with
the different modules inside the solar car. The system will be interfacing to the Driver Interface
and Maximum Power Point Trackers through the use of a CAN bus. The accelerometers and
temperature sensor are populated on the telemetry board itself, and the GPS Module, Motor
Controller, Battery Protection System, and Wireless Packet Modem are all interfaced via RS232.
The Telemetry system can run under two modes: race and diagnostics. During race mode, the
microprocessor of the Telemetry System is programmed to poll various parameters periodically
from the devices it’s interfaced to and then transmits this information to the chase vehicle via the
-1-
ECE 477 Final Report Spring 2006
Wireless Packet Modem. In addition, the Telemetry system serves as a center of communication
by allowing the chase vehicle to request to send text messages to the Driver Interface System.
Also, the Telemetry system takes requests from the Driver Interface System to provide
information about vehicle parameters back to the Driver Interface System. In the diagnostics
mode, the Telemetry system is able to listen to requests from the chase car to change parameters
within the individual modules connected to it.
Figure 1.1.1 Telemetry System Block Diagram
-2-
ECE 477 Final Report Spring 2006
Figure 1.1.2 Telemetry System Completed Project
2.0 Team Success Criteria and Fulfillment
Project-Specific Success Criteria:
1) Ability to receive and store motor status data from the motor controller via RS232.Assessment: This PSSC has been completed and demonstrated.
2) Ability to receive and store battery status data from the battery protection system via RS232.
Assessment: This PSSC has been completed and demonstrated.
3) Ability to receive, store, and transmit data to and from CAN nodes on the CANbus, acting as the CAN master.
Assessment: This PSSC has been completed and demonstrated.
4) Ability to read and store data retrieved from on-board sensors, including the 3D-accelerometer and temperature sensor.
Assessment: This PSSC has been completed and demonstrated.
5) Ability to send stored data through the packet modem linked with the chase vehicle, both automatically and upon request.
Assessment: This PSSC has been completed and demonstrated.
-3-
ECE 477 Final Report Spring 2006
3.0 Constraint Analysis and Component Selection
3.1 Design Constraint Analysis
The major design constraints when choosing our parts were connectivity. We need to
ensure that we can have at least four usable UART channels for communication as well as a way
to communicate over a CANbus. It would also be positive if the devices can be used in a low
power mode or be put to sleep when not in use so as to minimize the amount of power that they
draw. A large limiting factor is the size of the microcontroller itself. We are limited to using
the PIC 18F family in order to stay consistent with other components on the car. This fact
proves to limit our memory size as well as pin count, which later affects our choice of output
peripherals.
3.1.1 Computation Requirements
Our device has to be able to handle interrupts coming from the CANbus in order to
determine if it needs to gather and then send out information. It may also have to handle
interrupts over RS232 as well coming from the RF modem. It does not have any true real time
constraints as it is just collecting data and not controlling any part of the vehicle itself. The only
true possible real-time constraints would be our polling of data from the battery pack and motor
controller as we plan to do this about every second. Although this would not be a hard set
constraint, it would be heavily preferred to have it as consistent as possible.
3.1.2 Interface Requirements
The accelerometers require three ATD channels to acquire data and two general
purpose I/O channels to use as select lines. The SPI to UART interface chip also requires four
general purpose I/O pins to use as an interrupt line, a reset, and two chip select lines to go to both
of our SPI to UART chips. Both of these peripherals also require a voltage input of 3.3V. As is
evident, most of our interface requirements actually use the on board peripherals and not general
purpose I/O.
3.1.3 On-Chip Peripheral Requirements
-4-
ECE 477 Final Report Spring 2006
Depending on which chip solutions we decide to go with, we will be using SPI,
UART, a few general I/O ports, and a few ATD ports. The SPI will be used to interface to two
external UART chips to expand our serial capabilities. These expanded UART channels will be
used to communicate to the battery pack and the motor controller. The remaining UART port
will be used for communication with the RF modem. As stated above, three ATD channels will
be needed for the accelerometer chips. Depending upon our temperature sensor of choice we
will most likely also need one or two ATD channels for the temperature as well. Finally we will
be using the CAN interface provided on the microcontroller. This will first interface to a CAN
transceiver chip in order to give us the current voltage input to our controller since the CANbus
runs at 12 volts. After interfacing with the transceiver it will then process CAN requests and
output data on the bus as requested.
3.1.4 Off-Chip Peripheral Requirements
The main off-chip peripheral that we need is a way to expand our UART port
selection. The initial choice for this issue was a chip from Phillips that would let us gain either
four or eight UART channels by connecting to one of our 8-bit parallel ports. Later we
discovered that it would also require more pins than we could provide to create an address bus
and to use as select lines. It was determined that we could not give up this many pins on such a
small microcontroller.
We have since decided to go with another chip from Phillips which provides SPI to
UART interfacing. This chip connects to the SPI interface on the microcontroller and then
provides two UART ports. It also provides an interrupt input so that we can be notified of
changes on the RS232 lines and can read them accordingly. This chip also has built-in FIFO
buffers so that we do not have to constantly monitor the input and can just check the interrupt
line. Since we will be needing four UART ports, we will need two of these chips. Each chip has
a built in chip select to turn them off and on. These will be signaled using general I/O ports.
The other off-chip peripherals that we need are three accelerometer chips, one for each
axis, and a temperature sensor. We originally had looked at using a three axis accelerometer
from Freescale but discovered that the part was only offered in the QFN package which we have
no way of mounting with the equipment provided. The three-axis Freescale model is also
available pre-mounted on a PCB from Sparkfun.com. We would like to use this model but it is
-5-
ECE 477 Final Report Spring 2006
dependent on approval from the Purdue solar racing team. Due to these circumstances we have
decided to go with separate chips for each axis.
3.1.5 Power Constraints
Our device has to interface to a provided 12 volt rail and use as little power as
possible. We have found a 90-95% efficient 12 volt to 5 volt DC-DC converter that we plan on
using, as most of the other groups working on the solar car have also decided to use this part.
The device does not need to operate in a cool environment or be handled during use, so heat
dissipation is not a constraint.
3.1.6 Packaging Constraints
There is a large amount of open space in the cavity of the solar car so there is not
really a size constraint at all. The packaging itself needs to provide port access for three RS232
ports as well the as the proprietary CAN connector standard. For easy maintenance our
packaging should not have an overly complicated or permanently sealed system. This would
allow the solar team to replace parts or re-program the system without much hassle.
3.1.7 Cost Constraints
The cost constraint of this product is to make it as low cost as possible to fit within the
Purdue solar car team’s budget. Since this is a custom built project for specific use in the Purdue
solar car, there are no competing projects or products to have to match or beat price with. The
parts chosen should be sampleable. This will allow most of the parts to be received free of cost
to the solar team and allow the budget to be used for the more expensive parts such as the GPS
unit.
3.2 Component Selection Rationale
Our two main chips for consideration were our microcontroller and our UART
interface. When choosing the microcontroller we have been restricted to the PIC 18F family in
order to maintain a standard controller across all of the Purdue Solar Car. From this point we
wanted a controller that had built in CAN capabilities since it is the standard in this project with
which we all have the least amount of experience. This led us to two choices for our
microcontroller; the PIC 18f4680 and the 18f4585. The defining characteristic between the two
-6-
ECE 477 Final Report Spring 2006
was the amount of space provided on each. The 4680 [1] provides us with 64k of memory while
the 4585 only provides 48k. Since at this point we are unsure of how much space the libraries
and code will take up in our program we decided to go with the 4680 since it provides us with
the most amount of space while still providing us with a sufficient amount of I/O ports and CAN
functionality. A good example of a microcontroller not chosen from the PIC 18F would be the
Atmega1280 from Atmel. This microcontroller contains all the needed peripherals that we use
as well as incorporating quad-UART functionality. This would allow us to do our design
without the need for the SPI-UART chips. The issue with this chip would be its lack of support
for CAN so an external chip would be necessary. Atmel does make one chip, the AT90CAN128,
that contains a CAN interface as well as two UART connections. This would have allowed us to
use only one of the SPI-UART chips and would be a very good choice for this project. For the UART interface we looked at two chips; the [3] Phillips SC28L198A1A Eight
Channel UART and the [2] Phillips SC16IS752IPW I2C/SPI to dual UART. The first option
connects through an eight bit parallel bus to provide communication between the host CPU and
the UART chip. It also requires more pins to create an address bus, as well as select lines. The
latter chip only requires the standard SPI interface along with four general I/O pins to be used as
an interrupt, reset, and two chip selects. Due to the large amount of pins required by the first
choice and the size of the microcontroller we are using, we decided to go with [2]. In order to
expand our available UART ports we will be using two of these chips. Each one will have it’s
chip select lines interfaced through general purpose I/O. From there we can select which chip
we wish to activate.
3.3 Summary
This document has discussed the design constraints of the Purdue solar car telemetry system.
We have listed the functional needs of this project which include ability to communicate over
multiple RS232 connections and CANbus, as well as communicate to various off chip sensors.
We have listed the various on chip and off chip peripherals that we have decided to use in this
project including our choice of microcontroller and UART communication chips. This design is
not particularly limited by space or cost but by power consumption and the pre-defined limit of
controllers. This limited selection of controllers has greatly influenced the rest of our decisions
as far as off-chip peripherals are concerned due to the limiting factor of I/O pins.
-7-
ECE 477 Final Report Spring 2006
4.0 Patent Liability Analysis
4.1 Introduction
For the patent liability assessment, the collection of all of the functions employed by the
Telemetry System is of concern. There are several patents in existence today that describe some
of these functions and methods in its claims. What has to be determined is whether these claims
are an exact description of the function/method that our Telemetry System utilizes.
4.2 Results of Patent and Product Search
US Patent #6,023,232 [5]
Vehicle Communications Systems and Method
Filed: June 23, 1997
Condensed Abstract: This patent describes a vehicle communications system in which a
number of devices are connected to a central computer which processes data networking
applications. The devices are capable of transmitting and receiving information through
channels associated with the central computer. Within the central computer also lies an adaptive
control that is capable of selecting each individual device to perform a certain function.
Key Claim #1:
Key claim #1 basically describes the system consisting of a number of devices connected to
a central computer that runs networking applications. The key portion of the claim is the
description about the adaptive application control, which is said to be separate from the data
networking applications and communicates with the networking applications through a data
format that is unique to the individual devices. This claim seems to emphasize the role of an
independent adaptive control that communicates with the networking applications and then
makes a decision as to which devices will perform which functions given the requirements set by
the networking applications. The adaptive control in this case seems to act as a middle-manager
which takes in the needs of the networking applications and then executes them by utilizing the
connected devices.
-8-
ECE 477 Final Report Spring 2006
Key Claim #2: This claim describes a system of claim 1, where the interfaces used between
the device and the central computer must consist of at least a CAN interface, RS232 interface,
PCMCIA interface, Domestic Digital Bus interface, or a IR interface.
Key Claim #3: This claim describes a system of claim 1 and adds that the devices which
are connected to the central computer are at least one of a GPS, PDA, GSM, a CD-ROM unit,
and an RDS-TMC unit.
Key Claim #4: This claim describes a system of claim 1 and describes the data networking
applications in the central computer being at least one of a fleet management application, route
planning applications, a remote diagnosis application, an antitheft protection application, and an
electronic data communications application.
US Patent #6,941,194 [6]
Motor Vehicle Communication System and method for exchanging data in a motor
vehicle.
Filed: November 19, 1999
Condensed Abstract: This patent describes a vehicle communications system that uses a
processor connected to numerous data sources and numerous operator consoles.
Key Claim #1: This claim describes the vehicle communications system in which a number
of data sources and operator consoles are connected to a processor. The operator consoles must
have user interfaces which allow a person to access the applications on the processor and retrieve
information. The emphasis of this claim is that the processor allocates access rights with
different degrees of priorities to each of the operator consoles for access to the data applications.
US Patent #6,526,460 [7]
Vehicle communications system
Filed: August 30, 1999
Condensed Abstract: The patent describes a vehicle communications system that consists
of numerous devices used for transmitting, receiving, acquiring, or processing data for the
purpose of executing applications all while using a common data bus.
Key Claim #1: This claim describes a system in which a number of devices used for
transmitting, receiving, and processing information are connected together by a common bus.
The emphasis in this claim is that the devices are all connected through a common bus. In this
-9-
ECE 477 Final Report Spring 2006
system, the applications within the system are each assigned functions which are executed
through one or more of the devices connected to the system.
4.3 Analysis of Patent Liability
US Patent #6,023,232 has four claims that have aspects in common with the Telemetry
System. Claims 2, 3, and 4 are dependent upon claim #1, and will act as literal infringements for
the Telemetry System if claim #1 is proven to be an infringement under the doctrine of
equivalents [9]. Ignoring claim 1 for the time being, however, it can be seen that claims 2, 3, and
4 are otherwise directly infringed upon by the Telemetry System. Claim 2 is infringed upon
because the Telemetry system does use both RS232 and CAN to interface to the other devices in
the vehicle communications system. Claim 3 is infringed upon because the Telemetry system
also interfaces to a GPS. Claim 4 is infringed upon because the Telemetry System supports a
diagnostic mode in which the chase vehicle can access and change registers through the
Telemetry System. However, taking Claim 1 into account shows that all four of these claims
will not be infringed upon. Most of the aspects within Claim #1 are an accurate description of
the Telemetry System. However, the key portion which states, “an adaptive application control
separate from the data networking applications which communicates with the data networking
applications through a uniform data format that is independent of the interfaces and the
individual devices,” [5] seems to be the critical difference between the claim and the Telemetry
System. The Telemetry System does have an adaptive control in the sense that for different
applications different devices and functions are utilized, but this adaptive control is not separate
from the data networking applications at all. According to Claim #1, “separate,” in this case
refers to an adaptive control that communicates to the actual data applications through a uniform
data format independent of the other interfaces. Instead, the control and networking applications
within the Telemetry system are integrated within the embedded microcontroller software. The
microcontroller is capable of receiving requests from the chase vehicle wirelessly through the
wireless packet modem directly choosing the correct device to communicate to without the use
of a discrete adaptive application control. Thus, claim #1 doesn’t hold, which relinquishes the
Telemetry System from any possibility of infringement with patent #6,023,232.
-10-
ECE 477 Final Report Spring 2006
US Patent #6,941,194 has many claims that seem to have aspects in common with the
Telemetry System. However, similar to the previous patent in question, there is a critical
difference in its description within its first claim, which will relinquish the Telemetry System
from infringing upon the rest of the claims. From claim #1, statement “a plurality of operator
consoles (9) which are connected to the processor unit (1) and have user interfaces for accessing
the applications (9) and for data playback, and a central system controller (17) having a priority
management system (19) which allocates to the individual operator consoles (9) access rights
with different degrees of priority to the applications (15),” [6] is of concern. The first italicized
portion states that there’s a plurality of operator consoles. There is exactly one driver interface,
which can be interpreted as an operator console in that it can act to request parameters from the
other devices in the system such as speed, battery life, etc. However, assuming that the word
“plurality” does not exclude the use of a single operator console, the second italicized portion
states that the central system controller can provide access rights with different degrees of
priority to the applications. Since the Driver Interface is the only operator console connected to
the Telemetry system, the Driver Interface should be the only operator console with access to the
applications. Therefore, there is no priority structure associated with the access of applications
by individual operator consoles. US Patent #6,941,194 is therefore a patent that cannot be
infringed upon by the Telemetry System.
US Patent #6,526,460 is a good description of some of the methods of the Telemetry
System. The italicized statement, “each of the plurality of equipment units being connected to
the common vehicle data bus via said associated one of said hardware interfaces;……. wherein
the functions are executed within any desired one of said equipment units” [7]. The fact that the
Driver Interface System and Maximum Power Point Trackers are connected to a common CAN
bus cannot be denied. However, the rest of the equipment including the GPS, Motor Controller,
Battery Protection System, and Wireless Packet Modem are not connected to a common vehicle
data bus. However, this can be argued in the other direction by claiming that since a common
bus does exist for a plurality of equipment, then this statement holds true. The second portion of
the italicized statement is also debatable. The Telemetry System does not utilize any of the
devices to perform any major functions, but it does poll data from those devices. The act of
polling requires the polled devices to perform the “function” of accepting the request and
sending out the requested data back to the Telemetry System. Whether this is considered
-11-
ECE 477 Final Report Spring 2006
function is debatable. In reality, US Patent #6,941,194 does have the potential of being infringed
upon under the doctrine of equivalents [9].
4.4 Action Recommended
The above analysis shows that the first two queried patents can be excluded, but the third
patent has the potential of being infringed upon. There is a clear solution that can be
implemented to prevent all possibility of infringement in this case. Since the “common bus” is a
feature of US Patent #6,941,194 claim #1, it is possible just to move every module on the CAN
bus to an independent RS232 line. The main drawback of this change is that future
expandability on RS232 would be very expensive compared to expandability on the CANbus. If
the Purdue Solar Racing team were to add additional modules, an RS232 implementation would
require a redesign of the Telemetry Board to expand RS232 ports. Also, instead of the Driver
interface being able to communicate directly with the Maximum Power Point Trackers, it would
have to go through the Telemetry System to communicate with it. However, this solution does
not take away from any of the features of the telemetry system, and could actually be
implemented if need be.
4.5 Summary
The three patents that were found all have claims with aspects in common with the
Telemetry System. However, it is the differences that are most important when analyzing with
the purpose of detecting potential infringement. The patents [5] & [6] were determined to be
free of infringement by the Telemetry System. The infringement liability in patent [7] is
debatable and needs to be further analyzed by an intellectual property lawyer in order to
determine if infringement is likely to exist. If the potential for infringement is real, then the
Telemetry System, Driver Interface, and Maximum Power Point Trackers need to be redesigned
to use RS232 transceivers. However, taking into account the non-profit nature of the uses of the
Telemetry System, attention must be put into determining the likelihood of a lawsuit if an
infringement actually did exist. It may not be logical to increase the cost of the system and
decrease its later expandability if there is little possibility of being sued realistically.
-12-
ECE 477 Final Report Spring 2006
5.0 Reliability and Safety Analysis
5.1 Introduction
Reliability analysis is a critical part of designing a robust, and safe electronic system. The
analysis serves as an early warning for designers, alerting them about potential risks and
opportunities for improvement before the design reaches the testing stage. This early warning is
crucial, because design changes during later stages of the product life are much more costly than
design changes early in the product life. Reliability analysis is especially important now, with
lead-free parts adding additional failure modes to electronic devices. These failure modes
include tin whiskers, which can form shorts between consecutive pins, weaker solder joints, and
increased chip failures due to higher temperature solder profiles. These failure modes increase
the necessity to design for reliability up front, since there are even more obstacles to overcome
for a robust design.
5.2 Reliability Analysis
Ideally, a reliability analysis would be performed on every component in the schematic.
However, the failure rate contributions from many of the components will be insignificant
compared to the more complex devices that operate at higher temperatures. Therefore, our
analysis will be limited to four key components:
1. PIC 18F4680 – the microcontroller.
2. SC16IS752 – the SPI to dual UART converter.
3. MAX1684 – the switching regulator, providing 5v
4. LT1121 – the linear regulator, providing 3.3v
The reliability for each of these four components was determined using the following three
formulas:
λp = (C1πT + C2πE) πQπL (1)
TJ = TC + θJC*P (2)
-13-
ECE 477 Final Report Spring 2006
MTTF = 1 / λp [10] (3)
Equation 1 determines the part failure rate, or the number of failures per 106 hours. To
calculate Equation 1, the junction temperature is required, which can be calculated from
Equation 2. Finally, Equation 3 is used to determine the Mean Time To Failure. A summary of
the symbols used in these equations appears below.
λp = Part Failure Rate (failures per 106 Hours)
C1 = Die Complexity Failure Rate
πT = Temperature Factor
C2 = Package Failure Rate
πE = Environment Factor
πQ = Quality Factor
πL = Learning Factor
TJ = Junction Temperature (ºC)
TC = Case Temperature (ºC)
θJC = Junction-to-Case Thermal Resistance (ºC/W)
P = Maximum Power Dissipation (W)
MTTF = Mean Time To Failure
MTBF = Mean Time Between Failures [10]
5.2.1 PIC 18F4680 Microcontroller Reliability
Parameter Value Rationale
TC 50 Ground, Mobile classification [10]
θJC 28 Used the largest “Dual-In-Line” thermal resistance estimate [10]
P 1.0 Maximum power dissipation rating [1]
C1 0.14 8-bit MOS microcontroller [10]
πT 0.64 Rounded up the calculated TJ to 80 ºC [10]
C2 0.024 DIP with glass seal with 40 pins [10]
πE 4 Ground, Mobile classification [10]
πQ 10 Commercial device [10]
-14-
ECE 477 Final Report Spring 2006
πL 1 2+ years in production [10]
Table 5.2.1.1 – Parameter Selection and Rationale for PIC 18F4680
Parameter Equation Result
TJ TC + θJC*P 78 ºC
λp (C1πT + C2πE) πQπL 1.86 failures per 106 hours
MTBF 1 / λp 538,793 hours, or
61.5 years
Table 5.2.1.2 – Reliability Calculation Results for PIC 18F4680
The PIC 18F4680 was analyzed because it is the most critical component in the system. It
is also the component which is the most complex, and dissipates the most power. The
microcontroller drives all of the functionality of the telemetry system, so a single point failure
here could render the entire system unusable. For this reason, the microcontroller was designed
to fit into a DIP socket, so it could be easily replaced after a failure. Because the microcontroller
is user replicable, the MTBF is calculated instead of the MTTF.
The PIC 18F4680 is a 40 pin, 8-bit MOS microcontroller in a DIP package. It is a
commercial product, which has been in production for over two years. Since the telemetry
system is designed to be used in a solar car application, the environment classification of
“Ground, Mobile,” was chosen. The ambient temperature, TC, in this classification according to
[10] is 50ºC, which matches the approximate ambient temperature of the Purdue solar car, 45ºC.
The power parameter in the junction temperature calculation was set to be the maximum rated
power dissipation of the device. Using the parameters from Table 5.2.1.1, the part reliability was
determined to be 1.86 failures per 106 hours, giving a MTBF of over 61 years.
5.2.2 SC16IS752 SPI to Dual UART ReliabilityParameter Value Rationale
TC 50 Ground, Mobile classification [10]
θJC 22 Used the largest “Flat Package” thermal resistance estimate [10]
-15-
ECE 477 Final Report Spring 2006
P 0.3 Maximum power dissipation rating [2]
C1 0.14 Modeled as an 8-bit MOS microcontroller [10]
πT 0.42 Rounded up the calculated TJ to 60 ºC [10]
C2 0.013 Non-hermetic SMT with 28 pins [10]
πE 4 Ground, Mobile classification [10]
πQ 10 Commercial device [10]
πL 1.8 Approximately 0.5 years in production [10]
Table 5.2.2.1 – Parameter Selection and Rationale for SC16IS752
Parameter Equation Result
TJ TC + θJC*P 56.6 ºC
λp (C1πT + C2πE) πQπL 1.99 failures per 106 hours
MTTF 1 / λp 501,403 hours, or
57.2 years
Table 5.2.2.1 – Reliability Calculation Results for SC16IS752
The SC16IS752 was analyzed because it also is a relatively complex device, which drives a
majority of the functionality of the telemetry system. A pair of these chips is utilized in the
telemetry system design to add three additional UARTs to the system. These UARTs are used to
communicate with the Battery Protection System, the Motor Controller, and the GPS Module.
These devices constitute the majority of the devices from which the telemetry system collects
data. These chips are 28-pin surface mount devices with a maximum power dissipation of 0.3
watts. They were modeled as 8-bit MOS microcontrollers, since they have a selectable I2C or
SPI interface, two UART modules, internal registers, and GPIO pins. These devices have only
been in production for a short time of around 0.5 years, based on the date of the initial revision of
the datasheet. Therefore, the learning factor is 1.8. Using the parameters from Table 5.2.2.1, the
part reliability was determined to be 1.99 failures per 106 hours, giving a MTTF of over 57 years.
This failure rate will improve as the length of time it has been in production increases. Once it
finally reaches two years of production, the MTTF will improve to almost 103 years.
-16-
ECE 477 Final Report Spring 2006
5.2.3 MAX1684 Switching Regulator ReliabilityParameter Value Rationale
TC 50 Ground, Mobile classification [10]
θJC 22 Used the largest “Flat Pack” thermal resistance estimate [10]
P 0.667 Maximum power dissipation rating [11]
C1 0.02 Assumed 101 to 300 transistor linear MOS [10]
πT 2 Rounded up the calculated TJ to 65 ºC [10]
C2 0.0072 Non-hermetic SMT with 16 pins [10]
πE 4 Ground, Mobile classification [10]
πQ 10 Commercial device [10]
πL 1 2+ years in production [10]
Table 5.2.3.1 – Parameter Selection and Rationale for MAX1684
Parameter Equation Result
TJ TC + θJC*P 64.7 ºC
λp (C1πT + C2πE) πQπL 0.688 failures per 106 hours
MTTF 1 / λp 1,453,488 hours, or
165.8 years
Table 5.2.3.2 – Reliability Calculation Results for MAX1684
The MAX1684 was analyzed because it is the main voltage regulator in the telemetry
system. It converts the 12v input voltage supply to a 5v supply, which drives every component
in the system except for the SC16IS752 SPI to dual UART chips. Since a single point failure of
this component will render the entire system unusable, and since the device is not user
serviceable, it is important for this component to have a high MTTF. The device itself is a 16-
pin surface mount chip with a maximum power dissipation of 0.667 watts. It was assumed to be
a 101 to 300 transistor linear MOS device. It is a commercial device that has been in production
for over two years. Using the parameters from Table 5.2.3.1, the part reliability was determined
-17-
ECE 477 Final Report Spring 2006
to be 0.688 failures per 106 hours, giving a MTTF of over 165 years. The MTTF could further
be increased by adding an inexpensive heat sink to the system to reduce the junction temperature.
5.2.4 LT1121 Linear Regulator Reliability
The LT1121 reliability analysis uses one additional equation, and a few additional
parameters. The equation for power dissipated by the LT1121 from [12] was used to provide a
more accurate reliability prediction. The equation and parameter descriptions appear below:
P = IOmax(VImax – Vout) + (Ignd * VImax) (4)
IOmax = Maximum Output Current (A)
VImax = Maximum Input Voltage (V)
Vout = Output Voltage (V)
Ignd = Ground Pin Current (A) [12]
Parameter Value Rationale
IOmax 0.020 Sum of the maximum currents of both SC16IS752 chips [2]
VImax 5.0 5 volt input from the MAX1684 chip
Vout 3.3 3.3 volt output from the LT1121 chip
Ignd 0.001 Ground pin current with 20mA load [12]
TC 50 Ground, Mobile classification [10]
θJC 28 Used the largest “Dual-In-Line” thermal resistance estimate [10]
C1 0.02 Assumed 101 to 300 transistor linear MOS [10]
πT 1.0 Rounded up the calculated TJ to 55 ºC [10]
C2 0.021 DIP with glass seal with 8 pins [10]
πE 4 Ground, Mobile classification [10]
πQ 10 Commercial device [10]
πL 1 2+ years in production [10]
Table 5.2.4.1 – Parameter Selection and Rationale for LT1121
-18-
ECE 477 Final Report Spring 2006
Parameter Equation Result
P IOmax(VImax – Vout) + (Ignd * VImax) 0.039 W
TJ TC + θJC*P 51.0 ºC
λp (C1πT + C2πE) πQπL 0.284 failures per 106 hours
MTTF 1 / λp 3,521,126 hours
401.6 years
Table 5.2.4.2 – Reliability Calculation Results for LT1121
The LT1121 was analyzed because it supplies the regulated 3.3v to the SC16IS752 SPI to
dual UART chips, which provide a majority of the functionality of the telemetry system. The
device is an 8-pin DIP, dissipating a mere 0.039 watts. It was assumed to be a 101 to 300
transistor linear MOS device. It is a commercial device that has been in production for over two
years. Using the parameters from Table 2.4.1, the part reliability was determined to be 0.284
failures per 106 hours, giving a MTTF of over 401 years.
5.3 Failure Mode, Effects, and Criticality Analysis (FMECA)
The schematic was divided up into functional blocks, and each functional block was
analyzed for possible failure modes and causes. These functional blocks are summarized in
Table 5.3.0.1. Each failure mode was then analyzed for its effects on the functionality of the
system, and on the end users. Finally a criticality level was assigned based on the scheme in
Table 5.3.0.2.
Block Letter Block Description Figure Location
A 5v switching regulator circuit Figure A.1
B 3.3v linear regulator circuit Figure A.1
C RS-232 transceiver circuit Figure A.2
D SPI-to-UART conversion circuit Figure A.2
E Analog circuits Figure A.3
F Microcontroller circuit Figure A.4
G CAN transceiver circuit Figure A.4
-19-
ECE 477 Final Report Spring 2006
Table 5.3.0.1 – Schematic Functional Block Summary
Criticality Probability Effects
High λ < 10-9 Possible fire hazard, electrocution, or other harm to user
Low λ < 10-6 Partial or complete reduction of system functionality
Table 5.3.0.2 – Criticality Level Definitions
The FMECA Worksheet attached in Appendix B has four high criticality failure modes, all
relating to the power supply circuits. The risk associated with these failures can be mitigated by
modifying the design to include a fuse, or some other current limiting device, like a PTC. If the
current can be limited to a safe value to eliminate the possibility of fire, then these four high
criticality failure modes can be reduced to low criticality. The tradeoff for these current limiting
solutions is the possibility of nuisance trips of the fuse, which can completely disable the
telemetry system even though a dangerous situation would not have occurred. In this case
however, the positives outweigh the negatives.
5.4 Summary
The reliability and failure mode analysis has shown that the component failure rates from Section
2, which can lead to high criticality failure modes, A1, A4, B1, and B3, do not meet the
necessary λ < 10-9 probability threshold for high criticality failures. It has been determined,
however, that the safety risks associated with these high criticality failure modes can be abated
by modifying the design to include a current limiting device, like a fuse. Therefore, it is
recommended to include this simple change before any additional boards are assembled.
6.0 Ethical and Environmental Impact Analysis
6.1 Introduction
-20-
ECE 477 Final Report Spring 2006
As with anything in engineering, this project carries certain ethical and environmental
impacts which will be addressed in the following sections. Specifically, from an ethical
standpoint, the main concerns are the safety of the driver and others on the road during a race, as
well as the durability of the design because of the nature of the environment it operates within.
Along with the ethical considerations we face, environmental concerns are mainly centered on
the manufacturing, normal use, and disposal of the system which could produce hazardous
byproducts. This report will not only focus on these concerns, but also consider how they will be
addressed.
6.2 Ethical Impact Analysis
The engineering profession has a direct, visible impact on society. It is paramount that
those practicing the profession are held to the highest standards of honesty and integrity in the
products and services they provide. As a result, it is important that a product follows proper
ethical guidelines such as making decisions which are consistent with the safety, health, and
welfare of the public. Also, a company or organization should not sell or distribute a product
which will not be durable enough to withstand the environment it operates within. [13], [14] All
of these ethical challenges are addressed.
First, steps will need to be taken to ensure the safety of the driver of the car, as well as
those on the road during the race. The primary concern is in the event the chase vehicle sends a
command to modify the contents of the Motor Controller registers while the car is moving. This
could cause unpredictable behavior in the motor operation, and could ultimately result in a
crash. Precautions to avoid this scenario include establishing two modes of operation, race mode
and diagnostic mode. Diagnostic mode will be the only time which these registers can be
modified, and the car can only be in this mode while not in motion. Software checks have been
put in place to ensure that a command to change the registers will not occur while in race mode.
Also, the user’s manual will mention safe operating conditions for modifying registers in the
Motor Controller.
Second, in addition to the primary safety concern, the other safety considerations
include the possible inability to communicate Battery Protection data to the driver interface and
the possibility of electrical shock from an exposed board and wires. In the case where
communication of Battery Protection data fails, the Battery Protection systems already has built
-21-
ECE 477 Final Report Spring 2006
in fail safe protocols to protect the batteries from exploding. Considerations have been made to
include an external monitoring of Battery Protection data by the telemetry system, thus allowing
the telemetry systems to shut down the battery pack. When dealing with the possibility of
electrical shock, ensuring that all wires and the PCB are enclosed and covered to prevent
accidental exposure will be of most importance. Warning labels will also be placed on the
telemetry system case warning of possible shock if the case is opened or wires are exposed.
Third, it is important to make sure that the telemetry system is durable enough to
withstand the environment which it will operate in. Since the telemetry system will be mounted
inside the car during races, it will experience a lot of vibration. As a result of this vibration,
components may be knocked loose. Since the microcontroller the telemetry system uses is a DIP
package set in a socket, a zip tie can be wrapped around the microcontroller and attached to the
board. This will ensure that the microcontroller will stay in the socket, even through adverse
vibration. For mass production, it would be more advantageous to simply solder the
microcontroller directly to the board. Wires connecting DB9 and MTE connectors will need to
be fastened securely to the project casing to avoid them being disconnected. On top of these
procedures, the casing which holds the telemetry system will need to be fastened to the solar car
in a secure fashion to avoid the possibility of breaking loose during a race. All of these
precautions will allow the telemetry system to have a longer lifespan and ultimately be a safer
product.
Finally, it is important that all functionality of the telemetry system is tested both in
operational conditions, as well as abnormal conditions. Tests need to include verification of
proper communication between the telemetry system and the chase vehicle and all other
devices. This testing will also occur during start-up using a self test that verifies functionality
and communication. Testing will also be done using controlled software bugs to test the
system’s functionality in adverse operating conditions. Once the board and system are mounted
in the casing, vibration tests will be conducted to test how well the board and wires are fastened
to the casing. After all of the testing and precautions are completed, the telemetry system will be
fit to go to market while following all ethical guidelines.
6.3 Environmental Impact Analysis
-22-
ECE 477 Final Report Spring 2006
There exists a growing concern for the environment in today’s society. People are
taking steps to preserve and maintain the health of the environment and the creatures and people
who live in it. Because of this, there is a greater push towards Green engineering. Green
engineering is the process of design, commercialization, and use of products and processes that
minimize pollution at the source, as well as minimize risk to human health and the environment.
As engineers, we need to use life cycle thinking in all activities, ensure that all energy inputs
and outputs are as inherently safe as possible, and strive to prevent waste. [15] There are three
areas in a product’s lifecycle which need to attain these goals. Environmental analysis needs to
be done on the manufacture, normal use, and disposal of the telemetry system.
The main environmental impact from the telemetry system during the manufacturing
process would come from the fabrication of the printed circuit board. Negative impacts to the
environment could occur during fabrication of the PCB because of the hazardous byproducts
created in the process. These byproducts include air pollutants such as acid fumes, ammonia
fumes, and CFCs, as well as water stream pollutants such as acid and alkaline solutions,
electroless copper baths, and etchants. [16] If not properly handled by those responsible for
fabrication of the PCB, these pollutants could find their way into the atmosphere and water
supply. The EPA has outlined steps to help prevent these pollutants from reaching the
environment. These steps include eliminating chelated baths to improve metal wastewater
treatments and reuse of spent alkali and acid to neutralize the other’s waste streams before
introducing them to water waste systems. [17]
There will be minimal to no adverse affects to the environment while the telemetry
system is in normal use. The system’s printed circuit board will be enclosed and out of contact
with the environment, as well as the fact that there are no harmful byproducts being produced or
emitted. The system also uses no rechargeable batteries. Although the system interfaces to the
battery system on the solar car, these batteries are not a part of the telemetry system itself.
The telemetry system will need to be disposed of and recycled properly due to the
negative impact that the printed circuit board could have on the environment. One of the main
concerns of disposal of the PCB is the presence of lead based solder. Due to the lead based
solder and other materials considered hazardous, PCBs need to be segregated from other non-
hazardous solid materials and handled separately. Several companies offer services for recycling
the board by systematically removing raw material from the board matrix. Some of the
-23-
ECE 477 Final Report Spring 2006
recovered materials that can be recycled from the board include silver, gold, lead, and copper.
As an added benefit, recycling these raw materials recovers the value of those materials for
reuse in the fabrication of boards. [18]
7.0 Packaging Design Considerations
7.1 Introduction
Since the Telemetry System communicates with so many modules, the packaging for the
project needs to accommodate four DB9 RS-232 connectors, and four 6-pin MTE CANbus
connectors. The Telemetry System is a custom module for the solar car, so commercial issues
such as attractiveness, and cost do not apply. Size is not an important issue, since the solar car
has plenty of room inside. Weight, however, is the most important issue, due to the nature of
solar racing.
7.2 Commercial Product Packaging
Our team was unable to find off-the-shelf Telemetry Systems designs for solar car
applications, since the market for commercial solar car racing is miniscule, if it exists at all.
Therefore, we will analyze the product packaging of the current Purdue Solar Racing Telemetry
System, and a commercial Telemetry System designed for RC racing.
7.2.1 Current Purdue Solar Racing Telemetry System Packaging Analysis
The current Solar Racing Telemetry System is housed in a lightweight ABS plastic molded
project box. The box measures 6” x 4”, with two DB9 connectors for the Battery Protection
System and Packet Modem, and one connector for the Maximum Power Point Trackers. The
enclosure is mounted to the solar car with double sided tape. Although double sided tape is not
the strongest mounting method, it has been a successful mounting method for the Telemetry
System so far.
-24-
ECE 477 Final Report Spring 2006
Figure 2.1.1 – Current Purdue Solar Racing Telemetry System
This enclosure is nothing fancy, but it meets the needs of the Telemetry System packaging
perfectly. It provides adequate protection and stability to the module, and it is lightweight
enough for a solar racing application. Since our project is a replacement for this old Telemetry
System, and since this enclosure was successful, we plan to use a similar enclosure.
Our enclosure will be slightly larger, to accommodate the four DB9 connectors, and four
MTE connectors. We will use the same ABS plastic material for our enclosure. We researched
other common materials for project boxes, such as aluminum, in an attempt to minimize the total
weight of the packaging. While aluminum weighs more than plastic, it can be made much
thinner than plastic, possibly making the overall weight less. Plastic project boxes are commonly
available in 0.100” and 0.070” thicknesses, while aluminum project boxes are commonly
available in 0.040” thickness. The datasheets for these enclosures generally did not list a weight,
but we found that aluminum has a specific gravity of 2.64 [19], and plastic is very close to 1.00.
Since aluminum has over twice the specific gravity of plastic, and only a 57% reduction in
thickness, ABS plastic is the best solution to minimize weight.
-25-
ECE 477 Final Report Spring 2006
7.2.2 Spektrum Nitro Telemetry System Packaging Analysis
The Spektrum Nitro Telemetry System [20] is a commercial off-the-shelf Telemetry
System intended for RC car racing. The system consists of an on-car module with connections
for an infrared RPM sensor, a lap counter, a temperature sensor, and a battery voltage monitor.
The on-car module uses a RF link to communicate with the handheld module. The handheld
module has a display which shows the current readings from all the sensors.
Figure 7.2.2.1 – Spektrum Nitro Telemetry System
The Spektrum Nitro Telemetry System’s on-car package is incredibly small. The entire on-
car module weighs an impressive 8 grams. The mounting hardware is sturdy and lightweight,
and the sensors are modular, allowing the user to place them anywhere in the car. The handheld
receiver clearly displays all of the readings at once, and it even features a metric for the quality
of the RF link.
-26-
ECE 477 Final Report Spring 2006
Although the packaging is attractive and small, the feature set is also small. The product is
designed to allow the user to test the results of tweaks such as gearing, and protect the car from
low battery levels and high temperatures. However, it is difficult for a user to measure the
results of tweaks without immediate feedback, like from an accelerometer. The user must use
lap times as his measurement. Without logging features, it becomes difficult to really analyze
the data from the Telemetry System. Additionally, this product is incredibly expensive at $189
MSRP for such a simple device.
7.3 Project Packaging Specifications
Our project packaging is very similar to the project packaging of the old Solar Car
Telemetry System. The old Telemetry System is packaged in a 4”x6” plastic project box, which
provides adequate protection while minimizing weight. Since the old packaging has performed
adequately, and has met all it’s requirements, so there is no need for any big changes. Our
packaging will use a slightly larger project box, 5”x7”, to accommodate for all of the extra
connectors. A CAD drawing of our packaging can be found in Appendix A. The specifications
of the project box can be found in Appendix B.
The connectors will be mounted to the project box, and connect to headers on the PCB via
wires. This method ensures that there will be no issues with lining up PCB mounted connectors
to holes in the packaging. The PCB will be mounted to the box with standoffs. All of the
materials required to complete the packaging are listed below, in Table 7.3.0.1.
Item Estimated Weight (g) Estimated Cost
Plastic Project Box 200 $7.00
PCB (populated) 100 $180.00
Standoffs 30 $5.00
Double Sided Tape 15 $1.00
DB9 Connectors (4) 40 $8.00
MTE Connectors (4) 20 $3.00
Total 405 $84.00
-27-
ECE 477 Final Report Spring 2006
Table 7.3.0.1 – Packaging Materials List
For construction, we will only need to cut holes for the connectors, mount the connectors,
and wire the connectors to headers. Therefore, our tooling requirements are: A screwdriver, a
drill, a rotary hand tool (Dremel) or saw, and a soldering iron.
7.4 PCB Footprint Layout
The major components listed in the Design Constraint Analysis are the microcontroller
(PIC 18F4680), the SPI to UART chips (SC16IS752), the accelerometers (MMA 2260D and
MMA 1260D), and the DC to DC converter (MAX 1684). Most of the components are available
only in surface mount packages, so those choices were trivial. The microcontroller, however, is
available in both surface mount, and DIP packages. Since size is not a constraint, and since so
much of our size is determined by the DB9 connectors, we decided that a DIP package is the
most appropriate for the microcontroller. By using a DIP socket, replacing a broken
microcontroller will be simple. The microcontroller can be easily replaced if it fails during
debugging, or if for some reason it fails during a solar car race.
After laying out the footprint size, as seen in Appendix C, we estimate the final PCB size
to be approximately 60mm by 120mm. This size should leave enough room for all of the passive
components and headers.
7.5 Summary
Our project will be packaged similarly to the old Solar Car Telemetry system, in a plastic
project box. This package minimizes the weight, which is the most important constraint of solar
racing, while providing adequate protection to the electronics. Note that since this project is not
commercial, attractiveness is not important. Since there is plenty of space available, we are
using a DIP package for our microcontroller, which will allow us to easily replace it during
debugging, and allow the solar racing team to easily replace it if a failure occurs during a race.
Therefore, this packaging is well suited for a solar racing application.
-28-
ECE 477 Final Report Spring 2006
8.0 Schematic Design Considerations
8.1 Theory of Operation
8.1.1 Power:
Our power circuit uses a MAX1684[12] and an LT1121[11]. 12v is available throughout the
entire solar car so this is what we must use as the basis for our power needs. This 12v power is
received through the MTE CANbus port which will be discussed later. The 1684 provides a step
down from 12v to 5v DC in order to power the majority of our components[12]. The LT1121
provides a step down from 5v to 3.3v which is necessary for the SPI to UART chips. These
chips have 5 volt tolerant inputs for serial connections but require a power input of 3.3v. Each of
the solar teams are using the same 1684 chip for power conversion. These chips are shown to be
over 90% efficient while in our operating ranges. Hopefully this will provide the most stable
operation over the CANbus since this how each part will communicate with each other. The
operating frequency of the microcontroller has been decided to be 10MHz. Each of the solar
racing teams are using the exact same crystal to ensure that all the components of the car are
running at the same speed. This may help alleviate problems with future designs by ensuring a
standard clock rate and standard component usage.
8.1.2 Microcontroller:
The Microcontroller, a PIC4680[1], interfaces to most of our hardware. A DIP package
was chosen for our microcontroller in order to provide an emergency solution. The telemetry
system will be operating in a fairly hot environment as well as subject to vibrations. By using a
DIP package this will allow the team to quickly interchange a replacement microcontroller if
something were to happen to the original. Through ATD channels the microcontroller receives
data from the accelerometers and the temperature sensor which all output in voltage levels. We
are using three accelerometer chips, one for each axis, provided by Freescale. This solution was
chosen over the single board solution because each of the accelerometers could be sampled while
the board could not.
The controller has built in CAN support through which it communicates to a CAN
transceiver chip, MCP2551[21]. The outputs of the CAN transceiver are then taken to headers to
-29-
ECE 477 Final Report Spring 2006
be connected to an external MTE port on which all of the teams have decided to be the standard
connection for the CANbus. Through the MTE port we receive our 12v input from the CANbus
which powers the entire board. The port itself has been chosen to be a lock-in type connector in
order to ensure that the connector remains plugged in during strong vibrations which may occur
during operation. The built in RS232 support on the controller will be used to communicate with
the external packet modem interface or for debugging purposes. This will broadcast the
available information at a regularly scheduled interval to the ‘chase car’ which is following the
solar car.
The SPI system on the microcontroller is used to communicate with the SPI to UART
chips. Using two general purpose I/O pins as chip selects the microcontroller will choose which
chip to turn on for communication. These SPI chips also provide extra general purpose I/O pins
which we will use for debugging or expansion purposes[2]. These chips are discussed further
below.
The PIC18F1684 was chosen over other PIC microcontrollers because we are unsure
of the size that our program will take up and this microcontroller offers one of the greatest
amounts of available memory in this PIC family which we are limited to. This microcontroller
also affords the solar team many possibilities for expansion by leaving many open I/O pins and
access to each of the microcontroller’s modules.
8.1.3 SPI to UART Communication
The SPI system on the controller is used to communicate with the SPI to UART
chips[2]. Using two general purpose I/O pins as chip selects for each chip, these chips can each
talk to two serial devices. This will facilitate communication with the motor controller, battery
pack, and GPS unit. The SPI chips communicate externally using the MAX238 level translator
[22] which is a four driver version of the MAX232. The outputs of the MAX238 have then been
taken to external connectors which will be connected to ports to which cables can be attached
from the outside of the packaging. Each of these chips also provides a great number general
purpose I/O pins. We have taken these I/O pins from one chip to headers since we already have
a great number of pins left on the microcontroller we do not believe that we would need the
general purpose I/O from both SPI chips. The interrupt lines from these chips have also been
taken to headers so that the pin they connect to on the microcontroller can be used
-30-
ECE 477 Final Report Spring 2006
interchangeably in case future application specific pins on the PIC controller are needed and the
interrupt pin needs to be changed. A possible alternative we had looked at was using a quad-
UART chip which connected to a port on the microcontroller to interface to four UART lines.
This would make designing our project a lot easier, but we can not afford to use that many I/O
pins since many of the pins on the port are also used for A/D and other operations that we need
access to.
8.1.4 Accelerometers
We have chosen to use the MMA2260D [23] and MMA1260D [24] as our
accelerometers. Each of these chips provides data on a single axis. The 2260D is an X-axis chip
of which we are using two and mounting one side-ways. The 1260D is a Z-axis chip. The
output of each of these chips is in voltage levels and has been taken to ATD pins on the
microcontroller. This solution was chosen over the single-chip solution on a breakout board
because these chips are able to be sampled and the solar team felt it was not worth the extra cost
to order a separate board.
8.1.5 GPS
The GPS unit that was chosen was the GPS18 from Garmin[25]. This communicates over
RS232 to the microcontroller. This model was chosen over other solutions because it comes
with a 12v car adapter. Since a 12v supply is available all over the car this seemed like a wise
choice as most other models relied on a 5v input. This model also specifically stated that it
works with RS232 levels and can be interfaced with a laptop. Many other units specify that they
only work with “RS232 TTL levels” which is a misnomer. This unit appeared to be the most
compatible solution with the RS232 system we have available to us. Using the Garmin unit
ensures that we will be able to gather GPS data while using one of the other unit’s we may find
out later that either our schematic or PCB are laid out wrong for proper communication with
whatever data transfer scheme it uses. Finally the Purdue solar team already has experience
using the USB version of this device so they are already familiar with how it works and what to
expect from it.
An alternative to the Garmin unit would have been an onboard GPS module and using
antennae, extend its range outside of the car. The solar team decided to go with the Garmin
-31-
ECE 477 Final Report Spring 2006
because using a module would make it very difficult to change out the GPS unit if it was desired
later.
8.2 Summary
This document has described the basic operation of our circuit as well as our part
consideration for our major components. We have discussed how the telemetry system will
communicate with the various off-board devices such as the GPS unit and the motor controller.
This data is then sent by request over the CANbus to other devices on the vehicle such as a
display system. This data is also sent over packet modem to the chase car for data logging and
analysis. The telemetry system acts as an overall hub for data collection and communication
across the entire vehicle and is a valued addition to the solar car’s inner workings.
9.0 PCB Layout Design Considerations
9.1 Introduction
Since the Telemetry System will be housed inside the solar car, it was determined that any
PCB board that fits into a 4x6 inch rectangular box can be tolerated. Within reason, cost and
attractiveness do not apply because the Purdue Solar Racing Team is the only customer of this
board. The most important considerations include low EMI interference, ample component
spacing, intuitive placement for easy troubleshooting, and good trace width and copper trace
spacings. Weight was another consideration due to the nature of the solar racing car, but little
would be added by the Telemetry System so it wasn’t considered a main concern during the
design. The board was designed to be as compact as possible without jeopardizing usage
simplicity in order to reduce weight.
9.2 PCB Layout Design Considerations
The general layout for the Telemetry System board was designed by first grouping the
subsystem circuits into their functional areas: digital, analog, and power. This serves the primary
purpose of creating a board with an easier and more intuitive method of troubleshooting in the
-32-
ECE 477 Final Report Spring 2006
later stages, since the schematic is also grouped into areas of functionality. This grouping also
serves like components together (ie. digital with digital, analog with analog, power with power).
Consequently, the circuit was laid out so that the digital components were mainly at the bottom
half of the board, the power circuit in the upper right-hand corner, and the analog components in
the upper left-hand corner of the board (assuming the view of the board is horizontal with the
microcontroller on the left-hand side).
Special considerations were taken into account when routing the board. Higher frequency
lines such as the SPI feeding into the SPI-UART chip were routed through direct paths that
avoided crystals to prevent noise from disrupting the SPI signals. The bottom-side of the board
was created to be a ground plane to cut down on ground routes and to reduce EMI noise, and
image rails were used so that higher frequency signal paths were ensured to have a short, non-
looping ground return path. Image rails are routes placed on the opposite side of the ground
plane in order to connect two sections of ground planes separated by a non-ground signal ground.
This ensures a short ground return path that doesn’t loop around the non-ground signal. The
term “image-rail” was defined in a proprietary GE documentation and therefore is not referenced
in this report.
9.2.1 Power Distribution
After the parts were placed into the correct subsections, the next step was to take distribution
of power into consideration. The only source of power on the Telemetry board is the 12v and
ground lines feeding in through the 6-pin CAN bus connector. Consequently, this connector was
placed in the upper right-hand subsection of the board along with the rest of the power circuit.
The power circuit is confined in the upper right-hand side to prevent the higher current flowing
throughout it from interfering with the rest of the circuit. A ground and 12v line feeds in directly
through the 6-pin connector, and the power circuit’s output of 3v and 5v feeds in to the rest of
the circuit through the use of a thicker 40mil 5v power rail. The bottom-side of the board was
made to be a ground plane so that a short return path would always be possible. This would
prevent looping currents which create unnecessary EMI interference [26].
-33-
ECE 477 Final Report Spring 2006
9.2.2 Placement Themes
With the general placement of the parts and the power rails and ground plane complete, the
next step was to set a consistent placement theme. One priority while choosing the orientation of
each component was to simplify routing. This was done by rotating each component until the
simplest rats nest was obtained. Another consideration was the proximity of the bypass
capacitors and crystals(if applicable) for each IC. The recommended configuration is for the
crystal to lie on the side of the IC that it will be connected to along with the two capacitors
sandwiched between the crystal and its corresponding IC. This was done for both of the SPI-
UART chips. Likewise, the microcontroller’s bypass capacitors and crystal oscillator were
placed underneath the microcontroller to ensure proximity and to make way for the 9-pin
connectors on the top side of the board to route easily to the microcontroller. Finally, many of
the headers were given a location at or near the bottom edge of the board when possible.
However, a few of the smaller 3-pin UART headers and a 2-pin interrupt header were placed in
the middle of the board to allow for easier routing.
9.2.3 Power Section
Since there are three sections of the board: power, analog, and digital, individualized
consideration of part placements had to be given to the components in each section. The power
section takes a 12v and ground input from the 6-pin CAN connector and outputs 5v and 3.3v to
the rest of the board. This 6-pin CAN connector was placed at the top edge of the board so that it
will be easier to connect to the casing of the box that will be housing the board. The final
purpose of the power circuit is to convert the 5v output to a 3.3v output to feed into the SPI-
UART chips. After the 5v is fed through the linear regulator, the 3.3v output is decoupled
through a 1uF capacitor (C26). This capacitor was placed next to the linear regular as specified
by [27].
-34-
ECE 477 Final Report Spring 2006
9.2.4 Analog Section
The analog section consists of the three accelerometers for the x, y, and z axis (3 dimensions
of the physical world) and a temperature sensor. The analog section was chosen to be the top
left-hand corner of the board because of its placement above the microcontroller and easier
access to the analog pins. The location was chosen due to the importance of the separation of
digital and analog signals. Analog signals that cross with digital signals can be easily corrupted
[27]. Two of the accelerometers had to be oriented at 90 degree angles to each other so that the x
and y axis could be sensed. The temperature sensor was positioned for a short routing path to the
analog pin on the microcontroller. All of the analog components in this section were placed for
the shortest direct route to their corresponding microcontroller pins
9.2.5 Digital Section
The digital portion of the board occupies the entire bottom half of the board. Given the
placement of the power and analog portions of the board, the options were limited in regards to
the positioning. The microcontroller, two SPI-UART chips, and the RS232 transceiver were
spaced out and placed so that the higher frequency signals running from the microcontroller have
fewer obstacles to avoid. The CAN transceiver feeds off the CAN_H and CAN_L line from the
CAN connector in the power section of the board. Therefore, the CAN transceiver was placed
closer to the power section so that the CAN bus signals would be close to the 6-pin connector in
the power section. Image rails were added between the path from the microcontroller to the
CAN transceiver in order to reduce the ground return path. This was done to prevent current
from flowing through a longer path which might loop around and create EMI interference that
generates noise and affects other signals in the circuit. According to the spec sheet, the
microcontroller’s crystal oscillator and bypass capacitors should be placed very close to the
microcontroller [1]. Therefore, they were placed underneath the microcontroller on the bottom
side of the board.
-35-
ECE 477 Final Report Spring 2006
9.2.6 Routing Considerations
The Telemetry System is not a high current device. The total current being drawn by the
system was estimated to be under 500mA. Therefore, trace widths did not have to be too wide.
12 mil traces were used for the majority of the routes. The 3.3v and 5v power rails stemming
from the power circuit are 40mils, since they carry slightly higher currents than the other routes.
All via coppers were set to 20 mil widths to prevent clearance violations. Extensive effort was
spent in editing traces so that nothing violates the 12 mil spacing rule as set by the ECE477 PCB
Layout lecture [28]. There are currently 43 DRC errors remaining. All of the remaining errors
are from pad spacings for the switch-mode regulator in the power section and the components
placed underneath the microcontroller.
9.3 Summary
The final design of the Purdue Solar Racing Telemetry System Board was a logical and
user-friendly layout. The single input header is the 6-pin connector located at the top edge of the
board for easier access. The positions of the individual components were selected to simplify
routing and at the same time model the schematic’s functional placements of the components.
Noise and EMI issues were minimized through the placement of the 40 mil power rail and a
ground plane on the bottom side of the board. All bypass capacitors were placed near their
corresponding chips. Image rails were used to ensure a direct ground return path to minimize
EMI interference.
10.0 Software Design Considerations
10.1 Introduction
The software for this project features a main polling loop which is responsible for
acquiring data from the Motor Controller and Battery Protection System through SPI, as well as
Maximum Power Point Tracker information through CAN. An interrupt service routine will be
triggered every second to receive GPS data, as well as read both the accelerometers and
temperature sensor. Requests from both CAN and the packet modem will also operate using
-36-
ECE 477 Final Report Spring 2006
interrupt service routines. The primary software considerations will be communication with the
chase vehicle through the packet modem, constantly updating and accurate vehicle data, and
translating data between devices.
10.2 Software Design Considerations
Memory Considerations:
For this project we are using the PIC18F4680 microcontroller, which has two main
memory sections available on-chip. The PIC18F4680 has 64 KB of Flash and 3.25 KB of
SRAM. [29]
1. 64 KB Program Flash – All of the compiled program code and static data will be
located in this section. The majority of static data we will have in our software comes
from a look-up table which will hold a structure for each piece of critical vehicle data.
Each structure will consist of the vehicle data’s ID, update priority, command, and a
pointer to it’s location in SRAM. With 97 pieces of vehicle data and a structure size
of 10 bytes, the total size of this look-up table is estimated to be approximately 970
bytes. The size of the look-up table, along with other constants for the software, is
estimated to be no larger than 2 KB. This allows for approximately 62 KB of space
for compiled program code, which will be more than sufficient since finalized code
takes up approximately 7 KB of space.
2. 3.25 KB (3328 bytes) Data SRAM – The stack and all of the temporary variables will
be located in this section during program execution. Most of our temporary variables
will come from the 97 variables to hold the vehicle data for updates and transmission.
These 97 variables include 46 Battery Protection System variables, 20 Motor
Controller variables, 5 Power Point Tracker variables times 8 PPTs, accelerometer
data, temperature data, variables for text messages sent between the chase vehicle and
driver interface, and variables for the send and receive buffers for CAN. This vehicle
data, along with all other temporary variables, is estimated to be no larger than 350
bytes. In terms of the stack, the deepest that function calls and interrupts will be made
is four deep. Available memory in SRAM should be more than sufficient.
The MPLab IDE available on Microchip’s website is being used for software
development. MPLab handles memory mapping, and it was decided to be unnecessary to change
-37-
ECE 477 Final Report Spring 2006
from the default memory mapping because of the adequate amount of space present in both Flash
and SRAM. [30]
External Interface Mapping:
The telemetry system will be interface to several external devices. The following are
descriptions of what devices are connected to the microcontroller through (1) UART, (2) SPI,
and (3) ADC.
(1) A packet modem for communications with the chase vehicle is connected to the
UART serial communications with the microcontroller. The transfer pin of the UART
communication is mapped to pin 6 of portC. The receive pin of the UART
communication is mapped to pin 7 of portC. [29]
(2) Several devices are connected to the microcontroller through SPI. With a hardware
implementation, the single SPI is capable of communicating with up to four UART
connections. The devices using SPI to communicate with the microcontroller include
the Motor Controller, Battery Protection System, and GPS. The transfer pin of SPI is
mapped to pin 5 of portC. The receive pin of SPI is mapped to pin 4 of portC. [29]
(3) On-board sensors for acceleration data and temperature data are connected through
the ADC. The ADC is mapped across various pins of portA, portB, and portE. The
three accelerometers are mapped to ADC channels 0-2, which correspond to portA
pins 0-2. The temperature sensor is mapped to ADC channel 5, which corresponds to
portE pin 0. [29]
Integrated Peripheral Utilization:
The three integrated peripherals which required changes to the default configuration
file provided with the MPLab IDE [31] were the (1) integrated ECAN module, (2) ADC, and (3)
internal oscillator.
(1) The ECAN module on the microcontroller is being initialized to have a baud rate of
125 kbps for a clock frequency of 40 MHz.
(2) Changes to the default configuration file included setting the ADC to have channels
0-5 be analog input for the on-board sensors connected to channels 0-2 and 5. Since it
was only possible to change a set number of channels in order starting from channel
-38-
ECE 477 Final Report Spring 2006
0, channel 4 was set as analog input, even though it is not needed. The ADC interrupt
was changed to be disabled, and the voltage reference was set to accept an external
voltage reference.
(3) The default configuration file uses the microcontroller’s internal oscillator for
clocking, but this was changed to be disabled. [31] The ability to use an external
oscillator was enabled because the solar car teams will be using the same oscillator
chip to avoid small discrepancies if everyone was using their microcontroller’s
internal oscillator.
Overall Organization and Rationale:
The telemetry system utilizes a combination of a polling loop and interrupt service
routines to accomplish all of its required tasks. The main routine of the software consists of an
infinite loop which polls data from the Battery Protection System, Motor Controller, and
Maximum Power Point Trackers. The function will poll data from the various devices, store it
locally, and send it to the chase vehicle. In diagnostic mode, this is done explicitly by request
from the chase vehicle. In race mode, this is done by priority system.
All other data acquisition and other functionality are interrupt-driven. First, GPS
information is handled through an interrupt which occurs every second. The service routine
associated with the GPS interrupt will not only receive and process GPS data, but will also read
data from the accelerometers and temperature sensors. We are reading this data together because
the Aerospace Engineers on the solar team need coordinated GPS and acceleration data. Second,
CAN will have an interrupt service routine for handling requests for data from other devices on
the CANbus. Finally, an interrupt for UART will allow the chase vehicle to make a request to
change mode of operation via the packet modem.
Since all data acquisition from the Battery Protection System, Motor Controller, and
Maximum Power Point Trackers is on a request basis, polling the devices in a loop was the best
choice of implementation. GPS, on-board sensors, and chase car commands via packet modem
are all available as output on those devices, not on a request basis. Therefore, the most
appropriate way to handle acquisition of that data is through interrupts. A flowchart of the
overall organization of the software is available in “Appendix A”.
-39-
ECE 477 Final Report Spring 2006
10.3 Software Design Narrative
The following sections of the document highlight specific descriptions of the four
main modules of code and their subroutines. Modules presented are the system
start-up/initialization, race mode, diagnostic mode, and interrupt service routines. A code module
hierarchy is presented in “Appendix B”. Currently, all written code can be found in the main.c
file at:
http://shay.ecn.purdue.edu/~477grp13/homework_docs/main.c
System Start-Up/Initialization Module:
After the system is powered on or reset, the start-up code for setting up the stack and
copying initialized data is called. [29] Upon completion of this task, the microcontroller will
jump into the main function of our code. The initialization module is called first in the main
program, and its job is to initialize all integrated peripherals. For initialization of all of our
integrated peripherals aside from the ECAN, we are using supplied routines from header files
provided with the MPLab IDE. [32] All of these routines simply require the appropriate
arguments for configuration. Initialization of the ECAN will be done through a CAN
initialization function which will be written collectively by the Solar Car teams. It will configure
the ECAN module to have a baud rate of 125 kbps for a clock frequency of 40 MHz.
When these routines are complete, entry into the loop for main system operation will
occur. The first thing done in this loop is to check a status flag and determine which mode of
operation the system is currently in, race or diagnostic. Once this is determined, the appropriate
module call will be made. Currently, the overall initialization routine has been written and tested,
including the initialization of the ECAN.
Race Mode Module:
The primary responsibility of the race mode module is to run the main polling loop for
acquiring vehicle data from the Motor Controller, Battery Protection System, and Maximum
Power Point Trackers. Once data is received, it will be stored locally and sent to the chase
vehicle via the packet modem. A counter will be kept for the purpose of a priority system which
will decide which vehicle data is updated during that iteration of the polling loop. During an
iteration of the polling loop, the lookup table holding a structure for each piece of data is
-40-
ECE 477 Final Report Spring 2006
scanned. The structure contains the data’s ID, update priority, command, and a pointer to the
local variable for that piece of data in SRAM. If the specific piece of data is to be updated, the
command for polling that data is sent to the appropriate device holding the information. Upon
receiving a response, the variable in SRAM is updated. When completion of the look-up table
scan is reached, the priority counter will be incremented, and an update of all vehicle data will be
sent through the packet modem. The Watch Dog Timer will be kicked and the loop will start
over.
Standard functions for communicating with the various devices will be used. There
will be a read and write function for CANbus communication. For all other device
communication the MPLab IDE provides us with some of the functions such as the following
[2]:
1. ReadSPI() and getsSPI() in spi.h, which read a byte or string respectively
2. WriteSPI() and putsSPI() in spi.h which write a byte or string respectively
3. ReadUSART() and getsUSART() in usart.h, which read a byte or string
respectively
4. WriteUSART() and putsUSART() in usart.h which write a byte or string
respectively
Currently, the race mode routine had been written and tested. A protocol was
established along with the other solar teams, and the CAN read/write functions are finished and
tested.
Diagnostic Mode Module:
The primary responsibility of the diagnostic mode module is to allow members of the
race team to have explicit access to the vehicle information, rather than to just have updates sent
like in race mode. The ultimate goal is to give the team in the chase vehicle the ability to have
direct communication to set/get registers on the car. The only data that can be modified are the
registers of the Motor Controller, and all other data is read only. All of the same functions for
communications that race mode uses will be used for diagnostic mode. Since it was not a part of
any of the project success criteria, the diagnostic mode had been designed, but it has not been
written.
-41-
ECE 477 Final Report Spring 2006
Interrupt Service Routines:
The system will have interrupt service routines for (1) CAN and (2) Timer
(1) CAN ISR – The CAN ISR will handle any requests or data being sent across the
CANbus. It should get triggered whenever a device publishes something on the bus.
In the current state of the car, the only devices which should be providing data over
CAN are the Maximum Power Point Trackers, and the only device which should be
sending requests for information is the driver interface. This ISR will require the use
of the CAN read and write functions, and has been written and tested.
(2) Timer ISR – The Timer ISR will set flags at different time intervals to be used in the
main polling loop for acquiring data at specified times. For example, the BPS flag
will be set every 1 ms and the GPS flag will be set every 7 ms. This ISR also has
built in timeout functionality and recovery if a device is not responding. All of the
code to be processed is done in the main loop based off of these flags.
11.0 Version 2 Changes
Now that the prototype for the project has been completed, there are several design changes
that would be beneficial in creating a more polished product. The first design change would be
to re-do the PCB layout and board. The pins on one side of the microcontroller are reversed, and
because of this a device had to be constructed to swap those pins around. This needed to be done
in order to insert the controller and use it in a functional manner. The pins on the temperature
sensor were also reversed so that device had to be fly-wired in order to operate properly.
Along with these issues, pin usage with reset lines, IRQ’s, and chip selects were not
properly designed during the schematic phase of creation and had to be fly-wired in order to
operate some of our peripherals. If this device were to go into mass production a surface mount
form factor would be preferable for reduction in size. The original microcontroller was chosen
as a DIP package to allow the solar team to make emergency changes to the programming on the
controller or in case of damaged during use.
Aside from these hardware changes, software could be greatly condensed and re-organized.
Changing the software in this manner would help with the maintainability of the code as well as
making changes and adding features to it. A feature of the software that was not implemented
-42-
ECE 477 Final Report Spring 2006
but planned for was a diagnostic mode that would allow the solar team to directly communicate
with any attached device as if they had a direct terminal connection with that device. This would
allow them to change settings on the various devices in the car without having to leave the chase
vehicle as it could be done over the wireless packet modem.
12.0 Summary and Conclusions
The final Telemetry System that our team created was a success in terms of satisfying all of
our Project Specific Success Criteria. The system was tested using both simulators and actually
hooking it up to the devices that it is supposed to be hooked up to. Getting to this stage of
completion was not without lessons, however. Beginning with the Component Selection and
Constraint Analysis, we were able to rationalize exactly what types of functions were necessary
to achieve our goals, and at the same time compare different options in order to choose the best
components. For the schematic, we had to relearn how to create devices in Cadence and route
them together to create our schematic. A very tough lesson that we learned was working with
Layout Plus when designing our Layout. All of the team members became skillful in using
Layout Plus after having to spend many hours creating footprints and routing the rats nest. Also,
this project was important in bringing us a taste of the real-life industry aspects of engineering.
The Patent Analysis homework assignment was a step out of the realm of academic EE and into
the world of industrial EE in that it helped us realize the impact of the technology that our system
was utilizing, and its real potential to infringe on existing patents. The Environmental and Safety
analysis gave us another angle for viewing the project. It made us think about the lasting impact
of the materials used in making the Telemetry System after its useful life. Finally, some of the
most important lessons were related to programming the microcontroller. We had to review the
concepts of a microcontroller's operations and utilize the knowledge we learned in ECE362 in
order to program the Telemetry System to execute the correct operations. Although we didn’t
assembly language as we did in ECE362, we still utilized the same types of concepts performing
register settings, timer interrupts, ISR's, port pin interrupts, ATD sampling, and SPI port
programming all by using C programming. All in all, this project has been an in-depth first
exposure to embedded system designs from an industry viewpoint.
-43-
ECE 477 Final Report Spring 2006
13.0 References
[1] Microchip Technology Inc., PIC18F2585/2680/4585/4680 Data Sheet. Microchip Technology Inc., 2004. Available Online http://shay.ecn.purdue.edu/~477grp13/data_sheets/PIC18F4680.pdf
[2] Philips Semiconductors, SC16IS752/SC16IS762 Product Data Sheet. Philips Semiconductors, 2006. Available Online http://shay.ecn.purdue.edu/~477grp13/data_sheets/SC16IS752-SC16IS762.pdf
[3] Philips Semiconductors, SC28L198 Octal UART for 3.3V and 5V Supply Voltage Data Sheet. Philips Semiconductors, 2005. Available Online http://www.standardics.philips.com/products/sc28/pdf/sc28l198.pdf
[4] Freescale Semiconductor, MMA7260Q ±1.5g - 6g Three Axis Low-g Micromachined Accelerometer Data Sheet. Freescale Semiconductor, 2005. Available Online http://www.sparkfun.com/datasheets/Accelerometers/MMA7260Q-Rev1.pdf
[5] Eitzenberger, "Vehicle communication system," US Patent #6,023,232, February 8, 2000 http://patft.uspto.gov/netacgi/nph-Parser?Sect2=PTO1&Sect2=HITOFF&p=1&u=%2Fnetahtml%2Fsearch-bool.html&r=1&f=G&l=50&d=PALL&RefSrch=yes&Query=PN%2F6023232
[6] Dauner, "Motor communication system and method for exchanging data in a motor vehicle," US Patent #6,941,194, November 22, 2005 http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&Sect2=HITOFF&u=/netahtml/search-adv.htm&r=33&f=G&l=50&d=PTXT&p=1&S1=Telematic&OS=Telematic&RS=Telematic
[7] Dauner, et al., "Vehicle communications system," US Patent #6,526,460, February 25, 2003 http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&Sect2=HITOFF&p=1&u=/netahtml/search-adv.htm&r=15&f=G&l=50&d=CR00&S1=6,023,232.UREF.&OS=ref/6,023,232&RS=REF/6,023,23
[8] USPTO Search Engine, United States Government http://patft1.uspto.gov/netahtml/PTO/search-bool.html
[9] Understanding Patent Infringement Legal Opinions, David V Radack http://www.tms.org/pubs/journals/JOM/matters/matters-9512.html
[10] United States of America. Department of Defense. Military Handbook: Reliability Prediction of Electronic Equipment, 217F. Washington DC: Department of Defense, 1991. http://shay.ecn.purdue.edu/~dsml/ece3477/Homework/Spr2006/Mil-Hdbk-217F.pdf
-44-
ECE 477 Final Report Spring 2006
[11] Maxim Integrated Products, MAX1684/MAX1685 Data Sheet. Sunnyvale, CA : Maxim Integrated Products, 2001. Available Online http://shay.ecn.purdue.edu/~477grp13/data_sheets/MAX1684-MAX1685_DC-DC.pdf
[12] Linear Technology, LT1121/LT1121-3.3/LT1121-5 Data Sheet. Milpitas, CA : Linear Technology, 1994. Available Online http://shay.ecn.purdue.edu/~477grp13/data_sheets/LT1121.pdf
[13] IEEE, “IEEE Code of Ethics,” April 2006, Available Online http://www.ieee.org/portal/pages/about/whatis/code.html
[14] National Society of Professional Engineers, Code of Ethics for Engineers. Alexandria, VA : National Society of Professional Engineers, 2006. Available Online http://www.nspe.org/ethics/Code-2006-Jan.pdf
[15] Environmental Protection Agency, “What is Green Engineering?,” April 2006, Available Online http://www.epa.gov/oppt/greenengineering/pubs/whats_ge.html
[16] Silicon Valley Toxics Coalition, “The Environmental Cost of Printed Circuit Boards,” April 2006, Available Online http://www.corpwatch.org/article.php?id=3433
[17] A. Gemmell, “Printed Circuit Board Manufacturing Pollution Prevention Opportunities Checklist,” April 2006, Available Online http://es.epa.gov/techinfo/facts/cheklst7.html
[18] “Printed Circuit Board Recycling,” April 2006, Available Online http://p2library.nfesc.navy.mil/P2_Opportunity_Handbook/2_II_8.html
[19] Reade Advanced Materials, “Specific Gravity Weights of Materials From READE,” April 2006, Available Online http://www.reade.com/Particle_Briefings/spec_gra2.html
[20] Spektrum, “Spektrum Nitro Telemetry System,” April 2006, Available Online http://www.maxxtraxxusa.com/Spektrum_Nitro_Telemetry_System.cfm
[21] Microchip Technology Inc., MCP2551 High-Speed CAN Transceiver Data Sheet. Microchip Technology Inc., 2003. Available Online http://ww1.microchip.com/downloads/en/DeviceDoc/21667d.pdf
[22] Maxim Integrated Products, MAX238 +5V-Powered, Multichannel RS-232 Drivers/Receivers Data Sheet. Sunnyvale, CA : Maxim Integrated Products, 2004. Available Online http://pdfserv.maxim-ic.com/en/ds/MAX220-MAX249.pdf
[23] Freescale Semiconductor, MMA2260D ±1.5g X-Axis Micromachined Accelerometer Data Sheet. Freescale Semiconductor, 2006. Available Online http://www.freescale.com/files/sensors/doc/data_sheet/MMA2260D.pdf
-45-
ECE 477 Final Report Spring 2006
[24] Freescale Semiconductor, MMA1260D Low G Micromachined Accelerometer Data Sheet. Freescale Semiconductor, 2006. Available Online http://www.freescale.com/files/sensors/doc/data_sheet/MMA1260D.pdf
[25] Garmin International, Inc., GPS18 Technical Specifications. Olathe, KS : Garmin International, Inc., 2005. Available Online http://www.garmin.com/manuals/425_TechnicalSpecification.pdf
[26] D. L. Jones, PCB Design Tutorial. 2004. Available Onlinehttp://alternatezone.com/electronics/files/PCBDesignTutorialRevA.pdf
[27] Motorola, Inc., System Design and Layout Techniques for Noise Reduction in MCU-Based Systems. Motorola, Inc., 1995. Available Onlinehttp://shay.ecn.purdue.edu/~dsml/ece477/Homework/Spr2006/AN1259.pdf
[28] ECE477 Module 2: Digital System Design Considerations and PCB Layout Basicshttp://shay.ecn.purdue.edu/~dsml/ece477/Notes/PDF/4-Mod2.pdf
[29] PIC18F4680 User's Manualhttp://ww1.microchip.com/downloads/en/devicedoc/39625b.pdf
[30] Microchip Technology Inc., MPLAB IDE User’s Guide. Microchip Technology Inc., 2005. Available Online http://ww1.microchip.com/downloads/en/DeviceDoc/51519a.pdf
[31] Microchip Technology Inc., PIC18 Configuration Settings Addendum. Microchip Technology Inc., 2005. Available Online http://ww1.microchip.com/downloads/en/DeviceDoc/C18_Config_Settings_51537e.pdf
[32] Microchip Technology Inc., MPLAB C18 C Compiler Libraries. Microchip Technology Inc., 2005. Available Online http://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB_C18_Libraries_51297f.pdf
-46-
ECE 477 Final Report Spring 2006
Appendix A: Individual Contributions
A.1 Contributions of Matt Cozza:
I was involved in every single phase of the project. I helped with component selection
and acquisition, schematic design, PCB layout, soldering and populating the PCB, testing the
populated PCB, software development, and software testing and debugging. Some of these areas
I helped with more than others, but I tried to maintain an equal footing provide help in all aspects
of the project. I also was the team member who maintained and updated the website on a weekly
basis.
When it came to everything from component selection to soldering and populating the
PCB, I was usually helping someone or making small adjustments. When components were
selected for the design, I sampled a lot of them from various companies. After Evan had made
the schematic, there were a few things that needed to be adjusted. I mostly cleaned up the
schematic to allow for more readability and better clarity. Then, after Joe had made footprints for
the PCB, I organized the footprints and routed a good portion of the traces. I soldered a lot of the
0805 surface mount capacitors and resistors, as well as the accelerometers and portions of the
power circuit. I also helped to write software to test the accelerometers and there functionality
after being placed on the board. I also wrote and compiled the bill of materials from the list of all
the parts we used.
A majority of what I worked on for the project was the software. I helped to develop
the main basis for a lot of the software and wrote a lot of the functions used in the final code.
Except for a lot of the CAN functionality, I helped to develop most of the software. Some of the
functions I wrote include, but are not limited to a function for reading strings from UART
through the SPI chips, parsing functions for both the battery pack and motor controller, a
function for polling UART through the SPI chips, send/receive functions for the motor
controller, the majority of the timer ISR, and a base skeleton for the main polling loop. I also
helped to set up some of the functionality for writing data to the UART through the SPI chips
and the A/D functions. On top of writing all of the software, I helped to debug and test it. I
noticed a discrepancy in the use of parenthesis for the function which reads a byte from UART
through the SPI chips. After fixing this discrepancy, the functionality of one of the SPI to dual
A-1
ECE 477 Final Report Spring 2006
UART chips we had believed to be broken was restored. The majority of what I tested centered
on the data processing functions like parsing motor controller and battery pack, UART and A/D
capabilities, and the timer ISR.
I wrote the software considerations and narrative report, as well as the ethical and
environmental impact report. I also made an effort to proof read everyone else’s reports before
they turned them in. I always helped to create the power point presentations for the TC
practicum, as well as the midterm and final project presentations. In addition, I made the team’s
poster and helped to write the ECE senior design report. I tried to play an active role in helping
in all aspects of the design process and the work accompanying it.
A.2 Contributions of Joe Waugh
In the early phases of the project, I worked on the packaging homework, and helped
with some of the component and module selection. The packaging itself was mostly trivial,
since there were no aesthetic or size constraints. However, the report was more challenging,
since it was basically an entire report on using a plastic project box. I helped research
accelerometer and GPS solutions. The accelerometers we ended up using were the single-axis
chips I picked out, and the GPS solution we used was the external RS-232 module I picked out.
Additionally, I selected all of the passive components in the system, and I filled out the
component order form which the solar car club ordered.
During the layout phase, I did most of the layout for the second pass of the PCB. We
determined that we could significantly improve on the first layout design, so Matt and Evan re-
placed the components and made some initial routes. I completed the routing, and then went
through many iterations of placement tweaks and route tweaks until the layout was very good.
The final layout featured a near-solid ground plane on the bottom copper, with the power and
analog circuitry entirely single sided. The power, digital, and analog sections were clearly
separated in the layout. I used image rails around any medium to high speed traces that had
ground plane interruptions. That means I basically stitched together the ground plane by pulling
a trace from the ground plane up to the top layer, over the interruption, then back to the bottom
A-2
ECE 477 Final Report Spring 2006
layer. This technique essentially eliminated any negative effects of ground plane interruption.
After I completed the layout, I prepared it for manufacturing.
After we received the actual PCB, I soldered most of the components onto it. I also
helped debug the hardware. I found, and corrected problems with a feedback network in the
power supply, as well as the problem with the pins on one side of our microcontroller being
flipped. After the PCB was soldered, I did most of the module-by-module software testing,
except for CAN and some A/D testing.
In the late phases of the project, I did the reliability homework, and a lot of the
software and debugging. I created the large, constant structure which drives our data collection,
the final version main loop, the final version of most CAN functions, the GPS routines, some of
the underlying SPI routines, and the packet modem routines. I contributed to the timer-based
heartbeat, the BPS and the motor controller routines. I created simulators in Excel which
mimicked the operation of the connected UART devices, to make testing possible when the real
devices were unavailable. Finally, I did most of the software debugging, and ensured all of the
solar projects worked together.
A.3 Contributions of Evan Zelkowitz:
I covered a great number of roles and aspects in this project as our whole team did. In
the beginning of the project I focused on component selection and constraint analysis. I received
the requirements of the project from the solar team and from this determined possible solutions
for the many of the parts we needed. The main aspect of the project was the data collection and
information passing of the telemetry system. To accomplish this we needed a way to
communicate with four UART devices and the PIC family we were restricted to only contained
one. I started researching solutions to this such as UART expansion chips but most of these
required an entire port on our microcontroller which we could not give up since at the start of the
project we were unsure of how many general purpose I/O pins we would need. This led me use
some sort of expansion through a serial bus interface and I found the Philips SPI-UART chips
which used the SPI bus to let us gain the additional UART channels. I also researched
accelerometers and temperature sensors.
A-3
ECE 477 Final Report Spring 2006
After part selection I focused on the schematic design as it was one of the reports I had
to write. I started by creating schematic parts for each of our integrated circuit chips. Using the
data sheets from each of the manufacturer I laid these designs out. After creating each of the
parts I started work on combining all the parts together in to a usable schematic for translation to
our PCB. I did this by focusing my design in to blocks, first focusing on the SPI-UART
communication since it was the most complicated and then moving to the microcontroller and
CAN and then finally power and A/D functionality. After receiving feedback on the report I was
helped by some of my teammates to make the schematic a bit more readable and address the
concerns that were presented in the feedback. This schematic was then used to create our final
PCB. I helped in creation of the PCB with my knowledge of the schematic and how everything
connected in the overall design. This helped the team by allowing me to give guidance to my
teammates as far as part placement and routing strategies for the best possible use of space on the
board.
After the PCB and schematic were complete I helped in testing the traces of the PCB
as well as the functionality of the parts as they were placed. The team started by first soldering
on the power supply and testing it for correct output and then moved to all the peripherals. Once
all the parts were soldered work began on software development. I helped in this area by first
setting up our IDE for use in lab as well as gathering all the necessary libraries. I then start
writing initial functions to gather data from the accelerometers as well as the temperature sensor.
While writing these functions I also wrote much of the initialization for our devices such as the
A/D, SPI, and CAN. After the initializations were complete Joe and Matt took over and did a lot
more of the software development. My focus at this point was working on the CAN software
when I had a chance. I did testing using the CAN simulator and finally determined how to send
and receive CAN messages on the bus using this simulator and finding the correct initialization
values. After CAN was initially designed the majority of my time was helping to debug the
overall design since other team members wrote much of the other code. I helped in debugging
the communication with most of the peripherals as well as communication over the CANbus
with the other groups' projects.
After project completion I started work on the final documentation. I wrote the ECE
Senior Design Report which was then proofread by Matt. I also wrote many of the slides for the
final presentation. The only areas I did not cover were the patent analysis and the safety analysis
A-4
ECE 477 Final Report Spring 2006
since those were not my areas of expertise. Throughout the semester I always helped with the
presentations whenever they arose and always tried to help out members whenever possible. I
enjoyed designing a system from the ground up and learning the aspects of a team based design
of a marketable product.
A.4 Contributions of Elmer Chao:
I was involved with every single aspect of the project, as was the rest of the team.
Since the early stages, I was involved in the component selection and constraint analysis portions
of the project. I attended the initial meetings with the solar racing team in order to determine
what our constraints were and discussed with our team what our attack plans were going to be.
For the components, I helped select the linear regulator later on in the component selection
process when the team found out that the SPI-UART chips needed 3.3v instead of 5v.
During the design phase of the project I was an integral part in the Schematic and PCB
Layout. I helped in creating the CAN transceiver part of the schematic by referencing the data
sheet and deciding on what bypass capacitors and pins we needed to short to ground. For the
PCB Layout, I spearheaded the team into it and completed the majority of the first pass of the
Layout myself. I took on most of the learning curve for importing the schematic and learning to
use the Layout program to route the components. Joe and I also spent a lot of time creating and
finding footprints at the beginning of the Layout process. I also wrote up the PCB Layout report.
After the PCB Layout homework submission, Matt, Joe, and Evan later created a second pass
layout which included a ground plane, simpler routing, and less vias. I also participated in the
second pass of the layout by helping troubleshoot problem DRC errors after the layout was
completed. I also improved on many of the slides for the midterm presentation.
After the board was manufactured, I took the initiative to begin the soldering. I
finished up the main components in the power circuit and tested them. The rest of the team
finished up soldering the remainder of the circuit. When we began writing software to test the
various functionalities of the system, I was there to help out and follow what was going on. I
contributed during the testing phase by helping out in creating the function that sends messages
through the UART ports. There were many difficulties that we faced during the testing phase,
one of which was not being able to see messages coming from the microcontroller's UART port.
A-5
ECE 477 Final Report Spring 2006
I helped out by hooking up the output to the oscilloscope and verifying that the peak to peak
voltages were correct. I also helped in troubleshooting other problems such as the dead SPI-
CHIP, which just wouldn't work when we tried to send a UART message out of it. We later
found out that it was just a parenthesis that was missing. Another problem that I helped solve
was the fried temperature sensor that we borrowed from another solar racing team. I found out
that the sensor was supposed to operate at 4.4V instead of 5V and realized that we were using the
wrong version of the temperature sensor. During this time I was also responsible for writing the
Patent Liability report. I researched and found three patents and analyzed those carefully to
come up with possible solutions to avoid infringement by the Telemetry System. Since this
system is custom and will most likely never be mass produced for profit, it was determined that
there's very little risk for any type of a patent infringement lawsuit.
During the last phase of the project, I mainly focused on the packaging design and
creation while the other team members focused on writing the main loop for the microcontroller.
I made the whole packaging, drilled all the holes, and decided on all the ideal mounting
positions. I mounted the 4 UART connectors and the 4 6-pin CAN connectors. I also created the
cables for all of the connectors. I also collaborated with the rest of the team about placements,
cable design, and mounting methods to ensure that they could work with the board while it was
inside the packaging. I helped in the filming of the PSSC's and in editing the video clip. I also
made the ECE362 presentation. Finally, I created the final report.
Throughout the semester I always took an active role in team homework assignments
and presentations. Also, I proofread most of the other teammate's homework assignments when
they were due, and offered suggestions if I had any. Although I wish I could've helped out more
with software, I felt like the Joe, Evan, and Matt were very understanding in taking the time to
explain to me what they were doing with much of the programming. I made sure that I was
involved in all the aspects of the creation of the Telemetry system, and always tried hard to
contribute my expertise to the project. It was a great experience that will definitely benefit me
when I'm a product development engineer.
A-6
ECE 477 Final Report Spring 2006
Appendix B: Packaging
Figure B.1 – Packaging CAD Drawing
B-1
ECE 477 Final Report Spring 2006
Appendix C: Schematic
Figure C.1 – Analog Schematic
C-1
ECE 477 Final Report Spring 2006
Figure C.2 – Microprocessor and CAN Schematic
C-2
ECE 477 Final Report Spring 2006
Figure C.3 – Power Schematic
C-3
ECE 477 Final Report Spring 2006
Figure C.4 – SPI – UART Schematic
C-4
ECE 477 Final Report Spring 2006
Appendix D: PCB Layout Top and Bottom Copper
Figure D.1 PCB Top Copper
D-1
ECE 477 Final Report Spring 2006
Figure D.2 Bottom Copper
D-2
ECE 477 Final Report Spring 2006
Appendix E: Parts List Spreadsheet
E-1
Vendor Manufacturer Part No. Description Unit Cost
Qty Total Cost
Digi-Key Microchip PIC18F4680 Microcontroller 13 1 13Philips Philips SC16IS752 SPI to UART 3.89 2 7.78Sparkfun.com Sparkfun and
FreescaleMMA7260Q Triple Axis Accelerometer
Breakout – Using Freescale accelerometer
35.95 1 35.95
Digi-key Freescale MMA2260D Accelerometer 15.32 3 45.96Digi-key Microchip TC1047 Temperature sensor 0.47 1 0.47
GPS Unit – TBD by solar car team
~70.00 1 ~70.00
Digi-key MAXIM MAX1684 DC to DC power converter 8.56 1 8.56
TOTAL $181.72
ECE 477 Final Report Spring 2006
Appendix F: Software Listing
#ifndef __MAIN_H_#define __MAIN_H_
// _ ___ // _ _ ( ) /'___)_ // _( )( )_ _| | __ | (__ (_) ___ __ ___ // (_ .. _) /'_` | /'__`\| ,__)| |/' _ `\ /'__`\/',__)// (_ _)( (_| |( ___/| | | || ( ) |( ___/\__, \// (_)(_) `\__,_)`\____)(_) (_)(_) (_)`\____)(____/
#define HASSELHOFF_IS_COOL 1
#define SPI_A0 1 // SPI-UART Chip A (U26), Channel 0, J15 (UART_4)#define SPI_A1 2 // SPI-UART Chip A (U26), Channel 1, J14 (UART_3)#define SPI_B0 3 // SPI-UART Chip B (U25), Channel 0, UNUSED #define SPI_B1 4 // SPI-UART Chip B (U25), Channel 1, J17 (UART_2)#define PIC_UART 5 // build in UART channel, J?? (UART_1)
#define SPI_BPS SPI_B1 // SPI-UART Channel Assignment for Battery System#define SPI_MC SPI_A0 // SPI-UART Channel Assignment for Motor Controller#define SPI_GPS SPI_A1 // SPI-UART Channel Assignment for GPS#define PACKET_MODEM PIC_UART // UART Channel Assignment for Packet Modem
#define SPI_RHR 0x00 // Receive Holding Register (read)#define SPI_THR 0x00 // Transmit Holding Register (write)#define SPI_IER 0x01 // Interrupt Enable Register#define SPI_FCR 0x02 // FIFO Control Register (write)#define SPI_IIR 0x02 // Interrupt Identification Register (read)#define SPI_LCR 0x03 // Line Control Register#define SPI_MCR 0x04 // Modem Control Register#define SPI_LSR 0x05 // Line Status Register (read)#define SPI_MSR 0x06 // Modem Status Register#define SPI_SPR 0x07 // Scratchpad Register#define SPI_TCR 0x06 // Transmission Control Register#define SPI_TLR 0x07 // Trigger Level Register#define SPI_TXLVL 0x08 // Transmit FIFO Level Register (read)#define SPI_RXLVL 0x09 // Receive FIFO Level Register (read)#define SPI_IODir 0x0A // I/O Pins Direction Register#define SPI_IOState 0x0B // I/O Pins State Register (read)#define SPI_IOIntEna 0x0C // I/O Pins Interrupt Enable Register#define SPI_IOControl 0x0E // I/O Pins Control Register
F-1
ECE 477 Final Report Spring 2006
#define SPI_EFCR 0x0F // Enhanced Features Control Register#define SPI_DLL 0x00 // Divisor Latch LSB#define SPI_DLH 0x01 // Divisor Latch MSB#define SPI_EFR 0x02 // Enhanced Features Register#define SPI_XON1 0x04 // Xon1 Word#define SPI_XON2 0x05 // Xon2 Word#define SPI_XOFF1 0x06 // Xoff1 Word#define SPI_XOFF2 0x07 // Xoff2 Word
#define TEMP_TOO_HIGH 90 // in F? threshold for temperature alert
#define UART_ARR_LENGTH 10 // array length for sending strings through UART
// restrictions on length of input buffer#define MIN_GPS_BUFFER_LENGTH ( 1 )#define MAX_GPS_BUFFER_LENGTH ( 64 ) // the SPI-UART fifo only holds 64
/*Sentences transmitted by GPS18: GPRMC (default) : Recommended minimum specific GNSS data GPGGA (default) : Global positioning system fixed data GPGSA (default) : GNSS DOP and active satellites GPGSV (default) : GNSS satellites in view PGRME (default) : Estimated Error GPGLL : Geographic position - latitude / longitude GPVTG : Course over ground and ground speed PGRMV : 3d velocity PGRMF : Fix Data Sentence (contains date) PGRMB (default) : (unsupported?) DGPS beacon info PGRMT (default) : GPS unit sensor status*/
// GPS States for state machine#define GPSS_IGNORE ( 0 )#define GPSS_START ( 1 )#define GPSS_SENTENCE_ID ( 2 )#define GPSS_SENTENCE_ID_G ( 3 )#define GPSS_SENTENCE_ID_GP ( 4 )#define GPSS_SENTENCE_ID_GPG ( 5 )#define GPSS_SENTENCE_ID_GPGG ( 6 )#define GPSS_SENTENCE_ID_GPGGA ( 7 )#define GPSS_SENTENCE_ID_GPGL ( 8 )#define GPSS_SENTENCE_ID_GPGLL ( 9 )
/*
F-2
ECE 477 Final Report Spring 2006
$GPGGA Sentence (Fix data)Example (signal not acquired): $GPGGA,235947.000,0000.0000,N,00000.0000,E,0,00,0.0,0.0,M,,,,0000*00Example (signal acquired): $GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,19.7,M,,,,0000*1F
Field Example CommentsSentence ID $GPGGAUTC Time 092204.999 hhmmss.sssLatitude 4250.5589 ddmm.mmmmN/S Indicator S N = North, S = SouthLongitude 14718.5084 dddmm.mmmmE/W Indicator E E = East, W = WestPosition Fix 1 0 = Invalid, 1 = Valid SPS, 2 = Valid DGPS, 3 = Valid PPSSatellites Used 04 Satellites being used (0-12)HDOP 24.4 Horizontal dilution of precisionAltitude 19.7 Altitude in meters according to WGS-84 ellipsoidAltitude Units M M MetersGeoid Seperation Geoid seperation in meters according to WGS-84 ellipsoidSeperation Units M MetersDGPS Age Age of DGPS data in secondsDGPS Station ID 0000Checksum *1FTerminator CR/LF*/
#define GPSS_GPGGA_TIME ( 10 )#define GPSS_GPGGA_LAT ( 11 )#define GPSS_GPGGA_NS ( 12 )#define GPSS_GPGGA_LONG ( 13 )#define GPSS_GPGGA_EW ( 14 )#define GPSS_GPGGA_POS_FIX ( 15 )#define GPSS_GPGGA_SATS ( 16 )#define GPSS_GPGGA_HDOP ( 17 )#define GPSS_GPGGA_ALT ( 18 )#define GPSS_GPGGA_ALT_UNIT ( 19 )#define GPSS_GPGGA_GEOID ( 20 )#define GPSS_GPGGA_GEOID_UNIT ( 21 )#define GPSS_GPGGA_AGE ( 22 )#define GPSS_GPGGA_STATION_ID ( 23 )#define GPSS_GPGGA_CHECKSUM ( 24 )
/*$GPGLL Sentence (Position)Example (signal not acquired): $GPGLL,0000.0000,N,00000.0000,E,235947.000,V*2DExample (signal acquired): $GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D
F-3
ECE 477 Final Report Spring 2006
Field Example CommentsSentence ID $GPGLLLatitude 4250.5589 ddmm.mmmmN/S Indicator S N = North, S = SouthLongitude 14718.5084 dddmm.mmmmE/W Indicator E E = East, W = WestUTC Time 092204.999 hhmmss.sssStatus A A = Valid, V = InvalidChecksum *2DTerminator CR/LF*/
#define GPSS_GPGLL_LAT ( 25 )#define GPSS_GPGLL_NS ( 26 )#define GPSS_GPGLL_LONG ( 27 )#define GPSS_GPGLL_EW ( 28 )#define GPSS_GPGLL_TIME ( 29 )#define GPSS_GPGLL_STATUS ( 30 )#define GPSS_GPGLL_CHECKSUM ( 31 )
#define CR ( 13 )#define LF ( 10 )#define TAB ( 0x09 )
// return values from ParseGPS()#define GPS_PARSING_COMPLETE ( 1 )#define GPS_PARSING_INCOMPLETE ( 2 )#define GPS_PARSE_ERROR ( 3 )#define BUFFER_EMPTY ( 4 )
// globals for data output#define GPS_LATITUDE_LENGTH ( 9 )#define GPS_LONGITUDE_LENGTH ( 10 )#define GPS_ALTITUDE_LENGTH ( 4 )#define GPS_TIME_LENGTH ( 10 )
#define BPS_PARSING_COMPLETE GPS_PARSING_COMPLETE#define BPS_PARSING_INCOMPLETE GPS_PARSING_INCOMPLETE#define BPS_PARSE_ERROR GPS_PARSE_ERROR#define RETURN_COMPLETE GPS_PARSING_COMPLETE#define RETURN_INCOMPLETE GPS_PARSING_INCOMPLETE
#define MIN_BPS_BUFFER_LENGTH MIN_GPS_BUFFER_LENGTH#define MAX_BPS_BUFFER_LENGTH MAX_GPS_BUFFER_LENGTH
F-4
ECE 477 Final Report Spring 2006
#define MC_STATE_SEND 1#define MC_STATE_RECV 2
#define BPS_START_CHAR ( 0x0c ) // BPS starting char set to be form feed
#define NUM_BATTERIES ( 15 )
#define BPSS_START ( 0 )#define BPSS_CELL_VOLTAGE ( 1 )#define BPSS_CELL_TEMP ( 2 )#define BPSS_CELL_BALANCE ( 3 )#define BPSS_BATTERY_CURRENT ( 4 )
// designating characters#define DC_PPT0_IN_VOLTAGE ( 0 )#define DC_PPT0_OUT_VOLTAGE ( 1 )#define DC_PPT0_IN_CURRENT ( 2 )#define DC_PPT0_OUT_CURRENT ( 3 )#define DC_PPT0_TEMPERATURE ( 4 )#define DC_PPT0_MAX_POWER ( 5 )#define DC_PPT0_RESERVED ( 6 )#define DC_PPT1_IN_VOLTAGE ( 8 )#define DC_PPT1_OUT_VOLTAGE ( 9 )#define DC_PPT1_IN_CURRENT ( 10 )#define DC_PPT1_OUT_CURRENT ( 11 )#define DC_PPT1_TEMPERATURE ( 12 )#define DC_PPT1_MAX_POWER ( 13 )#define DC_PPT1_RESERVED ( 14 )#define DC_PPT2_IN_VOLTAGE ( 16 )#define DC_PPT2_OUT_VOLTAGE ( 17 )#define DC_PPT2_IN_CURRENT ( 18 )#define DC_PPT2_OUT_CURRENT ( 19 )#define DC_PPT2_TEMPERATURE ( 20 )#define DC_PPT2_MAX_POWER ( 21 )#define DC_PPT2_RESERVED ( 22 )#define DC_PPT3_IN_VOLTAGE ( 24 )#define DC_PPT3_OUT_VOLTAGE ( 25 )#define DC_PPT3_IN_CURRENT ( 26 )#define DC_PPT3_OUT_CURRENT ( 27 )#define DC_PPT3_TEMPERATURE ( 28 )#define DC_PPT3_MAX_POWER ( 29 )#define DC_PPT3_RESERVED ( 30 )
F-5
ECE 477 Final Report Spring 2006
#define DC_PPT4_IN_VOLTAGE ( 32 )#define DC_PPT4_OUT_VOLTAGE ( 33 )#define DC_PPT4_IN_CURRENT ( 34 )#define DC_PPT4_OUT_CURRENT ( 35 )#define DC_PPT4_TEMPERATURE ( 36 )#define DC_PPT4_MAX_POWER ( 37 )#define DC_PPT4_RESERVED ( 38 )#define DC_PPT5_IN_VOLTAGE ( 40 )#define DC_PPT5_OUT_VOLTAGE ( 41 )#define DC_PPT5_IN_CURRENT ( 42 )#define DC_PPT5_OUT_CURRENT ( 43 )#define DC_PPT5_TEMPERATURE ( 44 )#define DC_PPT5_MAX_POWER ( 45 )#define DC_PPT5_RESERVED ( 46 )#define DC_PPT6_IN_VOLTAGE ( 48 )#define DC_PPT6_OUT_VOLTAGE ( 49 )#define DC_PPT6_IN_CURRENT ( 50 )#define DC_PPT6_OUT_CURRENT ( 51 )#define DC_PPT6_TEMPERATURE ( 52 )#define DC_PPT6_MAX_POWER ( 53 )#define DC_PPT6_RESERVED ( 54 )#define DC_PPT7_IN_VOLTAGE ( 56 )#define DC_PPT7_OUT_VOLTAGE ( 57 )#define DC_PPT7_IN_CURRENT ( 58 )#define DC_PPT7_OUT_CURRENT ( 59 )#define DC_PPT7_TEMPERATURE ( 60 )#define DC_PPT7_MAX_POWER ( 61 )#define DC_PPT7_RESERVED ( 62 )#define DC_PPT8_IN_VOLTAGE ( 64 )#define DC_PPT8_OUT_VOLTAGE ( 65 )#define DC_PPT8_IN_CURRENT ( 66 )#define DC_PPT8_OUT_CURRENT ( 67 )#define DC_PPT8_TEMPERATURE ( 68 )#define DC_PPT8_MAX_POWER ( 69 )#define DC_PPT8_RESERVED ( 70 )#define DC_PPT9_IN_VOLTAGE ( 72 )#define DC_PPT9_OUT_VOLTAGE ( 73 )#define DC_PPT9_IN_CURRENT ( 74 )#define DC_PPT9_OUT_CURRENT ( 75 )#define DC_PPT9_TEMPERATURE ( 76 )#define DC_PPT9_MAX_POWER ( 77 )#define DC_PPT9_RESERVED ( 78 )#define DC_PPT10_IN_VOLTAGE ( 80 )#define DC_PPT10_OUT_VOLTAGE ( 81 )#define DC_PPT10_IN_CURRENT ( 82 )
F-6
ECE 477 Final Report Spring 2006
#define DC_PPT10_OUT_CURRENT ( 83 )#define DC_PPT10_TEMPERATURE ( 84 )#define DC_PPT10_MAX_POWER ( 85 )#define DC_PPT10_RESERVED ( 86 )#define DC_PPT11_IN_VOLTAGE ( 88 )#define DC_PPT11_OUT_VOLTAGE ( 89 )#define DC_PPT11_IN_CURRENT ( 90 )#define DC_PPT11_OUT_CURRENT ( 91 )#define DC_PPT11_TEMPERATURE ( 92 )#define DC_PPT11_MAX_POWER ( 93 )#define DC_PPT11_RESERVED ( 94 )#define DC_PPT12_IN_VOLTAGE ( 96 )#define DC_PPT12_OUT_VOLTAGE ( 97 )#define DC_PPT12_IN_CURRENT ( 98 )#define DC_PPT12_OUT_CURRENT ( 99 )#define DC_PPT12_TEMPERATURE ( 100 )#define DC_PPT12_MAX_POWER ( 101 )#define DC_PPT12_RESERVED ( 102 )#define DC_PPT13_IN_VOLTAGE ( 104 )#define DC_PPT13_OUT_VOLTAGE ( 105 )#define DC_PPT13_IN_CURRENT ( 106 )#define DC_PPT13_OUT_CURRENT ( 107 )#define DC_PPT13_TEMPERATURE ( 108 )#define DC_PPT13_MAX_POWER ( 109 )#define DC_PPT13_RESERVED ( 110 )#define DC_PPT14_IN_VOLTAGE ( 112 )#define DC_PPT14_OUT_VOLTAGE ( 113 )#define DC_PPT14_IN_CURRENT ( 114 )#define DC_PPT14_OUT_CURRENT ( 115 )#define DC_PPT14_TEMPERATURE ( 116 )#define DC_PPT14_MAX_POWER ( 117 )#define DC_PPT14_RESERVED ( 118 )#define DC_PPT15_IN_VOLTAGE ( 120 )#define DC_PPT15_OUT_VOLTAGE ( 121 )#define DC_PPT15_IN_CURRENT ( 122 )#define DC_PPT15_OUT_CURRENT ( 123 )#define DC_PPT15_TEMPERATURE ( 124 )#define DC_PPT15_MAX_POWER ( 125 )#define DC_PPT15_RESERVED ( 126 )#define DC_MC_RPM ( 128 )#define DC_MC_THROTTLE_INPUT ( 129 )#define DC_MC_REGEN_INPUT ( 130 )#define DC_MC_PHASE_CURRENT ( 131 )#define DC_MC_SUPPLY_VOLTAGE ( 132 )#define DC_MC_MOTOR_TEMP ( 133 )
F-7
ECE 477 Final Report Spring 2006
#define DC_MC_HEATSINK_TEMP ( 134 )#define DC_MC_OPERATING_STATUS ( 135 )#define DC_MC_OBSERVED_ROTATION_DIR ( 136 )#define DC_MC_FAULT1 ( 137 )#define DC_MC_FAULT2 ( 138 )#define DC_MC_FAULT3 ( 139 )#define DC_MC_FAULT4 ( 140 )#define DC_MC_THROTTLE_ENABLE ( 141 )#define DC_MC_INPUT_DIR ( 142 )#define DC_MC_ACTUAL_DIR ( 143 )#define DC_MC_SPEED_CONTROL ( 144 )#define DC_MC_DIGITAL_DISABLE_STATE ( 145 )#define DC_MC_THROTTLE_ENABLE_STATE ( 146 )#define DC_MC_FORWARD_INPUT_STATE ( 147 )#define DC_BPS_CELL_1_VOLTAGE ( 148 )#define DC_BPS_CELL_2_VOLTAGE ( 149 )#define DC_BPS_CELL_3_VOLTAGE ( 150 )#define DC_BPS_CELL_4_VOLTAGE ( 151 )#define DC_BPS_CELL_5_VOLTAGE ( 152 )#define DC_BPS_CELL_6_VOLTAGE ( 153 )#define DC_BPS_CELL_7_VOLTAGE ( 154 )#define DC_BPS_CELL_8_VOLTAGE ( 155 )#define DC_BPS_CELL_9_VOLTAGE ( 156 )#define DC_BPS_CELL_10_VOLTAGE ( 157 )#define DC_BPS_CELL_11_VOLTAGE ( 158 )#define DC_BPS_CELL_12_VOLTAGE ( 159 )#define DC_BPS_CELL_13_VOLTAGE ( 160 )#define DC_BPS_CELL_14_VOLTAGE ( 161 )#define DC_BPS_CELL_15_VOLTAGE ( 162 )#define DC_BPS_CELL_1_TEMPERATURE ( 163 )#define DC_BPS_CELL_2_TEMPERATURE ( 164 )#define DC_BPS_CELL_3_TEMPERATURE ( 165 )#define DC_BPS_CELL_4_TEMPERATURE ( 166 )#define DC_BPS_CELL_5_TEMPERATURE ( 167 )#define DC_BPS_CELL_6_TEMPERATURE ( 168 )#define DC_BPS_CELL_7_TEMPERATURE ( 169 )#define DC_BPS_CELL_8_TEMPERATURE ( 170 )#define DC_BPS_CELL_9_TEMPERATURE ( 171 )#define DC_BPS_CELL_10_TEMPERATURE ( 172 )#define DC_BPS_CELL_11_TEMPERATURE ( 173 )#define DC_BPS_CELL_12_TEMPERATURE ( 174 )#define DC_BPS_CELL_13_TEMPERATURE ( 175 )#define DC_BPS_CELL_14_TEMPERATURE ( 176 )#define DC_BPS_CELL_15_TEMPERATURE ( 177 )#define DC_BPS_CELL_1_BALANCING ( 178 )
F-8
ECE 477 Final Report Spring 2006
#define DC_BPS_CELL_2_BALANCING ( 179 )#define DC_BPS_CELL_3_BALANCING ( 180 )#define DC_BPS_CELL_4_BALANCING ( 181 )#define DC_BPS_CELL_5_BALANCING ( 182 )#define DC_BPS_CELL_6_BALANCING ( 183 )#define DC_BPS_CELL_7_BALANCING ( 184 )#define DC_BPS_CELL_8_BALANCING ( 185 )#define DC_BPS_CELL_9_BALANCING ( 186 )#define DC_BPS_CELL_10_BALANCING ( 187 )#define DC_BPS_CELL_11_BALANCING ( 188 )#define DC_BPS_CELL_12_BALANCING ( 189 )#define DC_BPS_CELL_13_BALANCING ( 190 )#define DC_BPS_CELL_14_BALANCING ( 191 )#define DC_BPS_CELL_15_BALANCING ( 192 )#define DC_BPS_BATTERY_CURRENT ( 193 )#define DC_BPS_UNKNOWN1 ( 194 )#define DC_BPS_UNKNOWN2 ( 195 )#define DC_DI_TEXT_MESSAGE_0_6 ( 196 )#define DC_DI_TEXT_MESSAGE_7_13 ( 197 )#define DC_DI_TEXT_MESSAGE_14_20 ( 198 )#define DC_DI_TEXT_MESSAGE_21_27 ( 199 )#define DC_DI_TEXT_MESSAGE_28_34 ( 200 )#define DC_DI_TEXT_MESSAGE_35_41 ( 201 )#define DC_DI_TEXT_MESSAGE_42_48 ( 202 )#define DC_DI_TEXT_MESSAGE_49_55 ( 203 )#define DC_DI_TEXT_MESSAGE_56_62 ( 204 )#define DC_DI_TEXT_MESSAGE_63_69 ( 205 )#define DC_DI_TEXT_MESSAGE_70_76 ( 206 )#define DC_DI_TEXT_MESSAGE_77_79 ( 207 )#define DC_TELEM_GPS_TIME ( 208 )#define DC_TELEM_GPS_LATITUDE ( 209 )#define DC_TELEM_GPS_LONGITUDE ( 210 )#define DC_TELEM_GPS_ALTITUDE ( 211 )#define DC_TELEM_X_ACCELERATION ( 212 )#define DC_TELEM_Y_ACCELERATION ( 213 )#define DC_TELEM_Z_ACCELERATION ( 214 )#define DC_TELEM_TEMPERATURE ( 215 )#define DC_TELEM_TEMPERATURE_ALERT ( 216 )#define DC_CONNAND_TURN_OFF ( 254 )#define DC_COMMAND_REQUEST ( 255 )
// constants for the data_type field of the polled_data_type struct#define TYPE_INT ( 1 )#define TYPE_CHAR_POINTER ( 2 )#define TYPE_ASCII_DECIMAL ( 3 )
F-9
ECE 477 Final Report Spring 2006
#define TYPE_ASCII_HEX ( 4 )#define TYPE_ASCII_FLOAT ( 5 )#define TYPE_UCHAR ( 6 )
// constants for the device_id field of the polled_data_type struct#define DEVID_PPT0 ( 0 )#define DEVID_PPT1 ( 1 )#define DEVID_PPT2 ( 2 )#define DEVID_PPT3 ( 3 )#define DEVID_PPT4 ( 4 )#define DEVID_PPT5 ( 5 )#define DEVID_PPT6 ( 6 )#define DEVID_PPT7 ( 7 )#define DEVID_PPT8 ( 8 )#define DEVID_PPT9 ( 9 )#define DEVID_PPT10 ( 10 )#define DEVID_PPT11 ( 11 )#define DEVID_PPT12 ( 12 )#define DEVID_PPT13 ( 13 )#define DEVID_PPT14 ( 14 )#define DEVID_PPT15 ( 15 )#define DEVID_MOTOR ( 16 )#define DEVID_BPS ( 17 )#define DEVID_DI ( 18 )#define DEVID_TELEM ( 19 )
#define MAX_COMMAND_SIZE ( 4 )#define POLLED_DATA_SIZE ( 148 )#define ALL_DATA_SIZE ( 217 )#define MAX_PPTS ( 16 ) // maximum number of power point trackers in the system#define NUM_PPTS ( 8 ) // maximum number of power point trackers in the system
#define RACE_MODE_SEND 0#define RACE_MODE_WAIT 1#define RACE_MODE_RCV 2#define INC_COUNTER 3#define DIAGNOSTIC_MODE 4#define ERROR 5#define POLL_GPS 6#define POLL_BPS 7
#define COUNTER_TOO_BIG 500 // counter value maximum limit for detecting error
#define GPS_ERR_STATUS 0x0001 // mask to access GPS error bit
F-10
ECE 477 Final Report Spring 2006
#define BPS_ERR_STATUS 0x0002 // mask to access BPS error bit#define MC_ERR_STATUS 0x0004 // mask to access MC error bit#define CAN_ERR_STATUS 0x0008 // mask to access CAN error bit#define POLL_ADC_FLAG 0x0010 // mask to access ADC poll flag bit#define POLL_GPS_FLAG 0x0020 // mask to access GPS poll flag bit#define POLL_BPS_FLAG 0x0040 // mask to access BPS poll flag bit#define SEND_STATUS_FLAG 0x0080 // we should spew our data at PM#define POLL_CAN_FLAG 0x0100 // we should spew our data at PM#define POLL_MC_FLAG 0x0200 // we should spew our data at PM#define SERVICE_CAN_INT 0x0400 // we got a can interrupt, service it#define ROTATE_TAGS_FLAG 0x0800 // rotate our flags
#define TAG_ECE 1#define TAG_BXR 2#define TAG_HG 3#define TAG_SD 4
#define MAX_RESPONSE_LENGTH 10 // response length from SPI-UART devices
#define CAN_POLL_STATE_IDLE 1 // not polling ppts#define CAN_POLL_STATE_REQUEST 2 // requesting data#define CAN_POLL_STATE_RESPONSE 3 // waiting for response#define CAN_POLL_STATE_NEXT 4 // response recieved#define CAN_POLL_STATE_COMPLETE 5 // response recieved
#define CAN_POLL_INCOMPLETE 6#define CAN_POLL_COMPLETED 7
#define GPS_STATE_MEASURE_ADC 1#define GPS_STATE_INCOMPLETE 2
#define PM_STATE_POLLED 1#define PM_STATE_TEMP 2#define PM_STATE_TEMP_ALERT 3#define PM_STATE_GPS_TIME 4#define PM_STATE_ACCEL_X 5#define PM_STATE_ACCEL_Y 6#define PM_STATE_ACCEL_Z 7#define PM_STATE_GPS_LAT 8#define PM_STATE_GPS_LON 9#define PM_STATE_GPS_ALT 10#define PM_STATE_BPS_VOLTAGE 11#define PM_STATE_BPS_TEMPERATURE 12#define PM_STATE_BPS_BALANCE 13#define PM_STATE_BPS_CURRENT 14
F-11
ECE 477 Final Report Spring 2006
#define PM_START_CHARACTER 12#define PM_DELIMITER ','#define PM_END_CHARACTER ';'#define PM_TRANSMIT_INCOMPLETE 1#define PM_TRANSMIT_COMPLETE 2
//#define PM_STATE_PPT 6
//CAN Definitions//---------------------------------////--------NODE IDENTIFIERS---------////---------------------------------//#define PPT0 0x00 //MPPT boards#define PPT1 0x01#define PPT2 0x02#define PPT3 0x03#define PPT4 0x04#define PPT5 0x05#define PPT6 0x06#define PPT7 0x07#define PPT8 0x08#define PPT9 0x09#define PPT10 0x0A#define PPT11 0x0B#define PPT12 0x0C#define PPT13 0x0D#define PPT14 0x0E#define PPT15 0x0F#define DI 0x10 //driver interface board#define TELEM 0x11 //telemetry board
//First byte to indicate a change//of state for an MPPT#define MPPX_CHNG_STATE 0xFE//the second data byte in the CAN message//indicates to the MPPT whether to//connect or disconnect the array#define MPP_CON 0x01#define MPP_DISCON 0x00
//BATTERY PROTECTION SYSTEM#define BPS_CELL_VOLT 0x94//to get other cells, just add cell number - 1 to BPS_CELL_VOLT
F-12
ECE 477 Final Report Spring 2006
//15 CELLS TOTAL
#define BPS_CELL_TEMP 0xA3//to get other cells, just add cell number - 1 to BPS_CELL_TEMP//15 CELLS TOTAL
#define BPS_CELL_BAL 0xB2//to get other cells, just add cell number - 1 to BPS_CELL_BAL//15 CELLS TOTAL
#define BPS_BATT_CUR 0xC1
//DRIVER INTERFACE#define DI_TEXT_MESSAGE 0xC4//to get at all of the characters, start at DI_TEXT_MESSAGE// and add 1 to get at chars 7-13, 2 to get at chars 14-20, etc// until 0xCF which is chars 77-79 and clear command
//TELEMETRY#define TELEM_GPS_TIME 0xD0#define TELEM_GPS_LOC_1 0xD1#define TELEM_GPS_LOC_2 0xD2#define TELEM_GPS_LOC_3 0xD3#define TELEM_X_ACCEL 0xD4#define TELEM_Y_ACCEL 0xD5#define TELEM_Z_ACCEL 0xD6#define TELEM_TEMP 0xD7#define TELEM_ALERT 0xD8
#define TEMPERATURE_TOO_HIGH 200#define MC_COUNTER_TOO_BIG 1000#define CAN_TIMEOUT 10 //(ms)
// is can data little or big endian?//#define CAN_BIG_ENDIAN
// ___ _ // /'___) ( )_ _ // | (__ _ _ ___ ___ | ,_)(_) _ ___ // | ,__)( ) ( )/' _ `\ /'___)| | | | /'_`\ /' _ `\// | | | (_) || ( ) |( (___ | |_ | |( (_) )| ( ) |// (_) `\___/'(_) (_)`\____)`\__)(_)`\___/'(_) (_)
F-13
ECE 477 Final Report Spring 2006
// _ _ // ( )_ ( )_ // _ _ _ __ _ | ,_) _ | ,_) _ _ _ _ __ ___ // ( '_`\ ( '__)/'_`\ | | /'_`\ | | ( ) ( )( '_`\ /'__`\/',__)// | (_) )| | ( (_) )| |_ ( (_) )| |_ | (_) || (_) )( ___/\__, \// | ,__/'(_) `\___/'`\__)`\___/'`\__)`\__, || ,__/'`\____)(____/// | | ( )_| || | // (_) `\___/'(_)
#pragma idata my_isection_proto
/* Function Prototypes */void writecSPI_UART( unsigned char, unsigned char, unsigned char);char readcSPI_UART( unsigned char, unsigned char);void readsSPI_UART( unsigned char, unsigned char, unsigned char *, unsigned char );void write_byte_UART(unsigned char);void write_str_UART(unsigned char);void write_array_UART(unsigned char [], unsigned char);unsigned char poll_SPI_UART( unsigned char );void disable_interrupts(void);void enable_interrupts(void);void polled_loopback(unsigned char);void initialize_CAN(void);void init(void);void readAccel(void);void readTemp(void);unsigned char ParseGPS( unsigned char* gps_buffer, unsigned char length );unsigned char ParseBPS( unsigned char *, unsigned char);void CANintrequest(void);unsigned char CANpollPPT(unsigned char pptID);void send_MC (unsigned char );unsigned char recv_MC ( unsigned char );unsigned char ParseMC (unsigned char *, unsigned char, unsigned char );void write_u16_UART( unsigned int write_me );void write_u8_UART( unsigned char write_me );unsigned char send_PM(void);int hatoi(char *hexStg);unsigned char UARTIntGetTxBufferEmptySpace(void);
//void can_test(void);//void send_to_device( unsigned char, char* );//void receive_from_device( unsigned char );
F-14
ECE 477 Final Report Spring 2006
// _ _ _ _ _ // (_ ) ( ) (_ ) ( ) ( )_ // __ | | _ | |_ _ _ | | _| | _ _ | ,_) _ _ // /'_ `\ | | /'_`\ | '_`\ /'_` ) | | /'_` | /'_` )| | /'_` )// ( (_) | | | ( (_) )| |_) )( (_| | | | ( (_| |( (_| || |_ ( (_| |// `\__ |(___)`\___/'(_,__/'`\__,_)(___) `\__,_)`\__,_)`\__)`\__,_)// ( )_) | // \___/'
#pragma idata my_isection_globo
/*
struct status{ unsigned UARTIntTxBufferFull :1; unsigned UARTIntTxBufferEmpty :1; unsigned UARTIntRxBufferFull :1; unsigned UARTIntRxBufferEmpty :1; unsigned UARTIntRxOverFlow :1; unsigned UARTIntRxError :1;};
struct status vUARTIntStatus;
#pragma idata my_isection_uart1#pragma idata my_usection_uart1#define TX_BUFFER_SIZE 64unsigned char vUARTIntTxBuffer[TX_BUFFER_SIZE];#pragma idata my_isection_uart2#pragma idata my_usection_uart2
unsigned char vUARTIntTxBufDataCnt = 0;unsigned char vUARTIntTxBufWrPtr = 0;unsigned char vUARTIntTxBufRdPtr = 0;*/char response[MAX_RESPONSE_LENGTH]; // response from SPI-UART
// polled data structuretypedef struct{ void* data_location; // void pointer to where the data should be stored in memory char command[ MAX_COMMAND_SIZE ]; // the command needed to request the specified information unsigned char device_id; // the device id of the device which has the data, see above
F-15
ECE 477 Final Report Spring 2006
unsigned char priority; // how frequently is the data updated (1=most, 8=least) unsigned char designating_char; // the designating character needed by labview unsigned char data_type; // what type should the void pointer be casted back to? unsigned char data_length; // if the void pointer corresponded to an array, how long is it?} polled_data_type;
// structure for holding power point tracker datatypedef struct{ unsigned int in_voltage; unsigned int out_voltage; unsigned int in_current; unsigned int out_current; unsigned int temperature; unsigned int max_power; unsigned int reserved;} ppt_type;
// structure to hold acceleration data recieved from accelerometersstruct Acceleration{ unsigned int x; unsigned int y; unsigned int z;};
char write_UART[UART_ARR_LENGTH]; // array for sending a message through UART
typedef struct cell_struct1{ unsigned char data[4];} cell_type_3byte;
typedef struct cell_struct2{ unsigned char data[5];} cell_type_4byte;
#pragma udata my_section_1#pragma idata my_isection_1
unsigned char CAN_poll_state = CAN_POLL_STATE_IDLE;unsigned char temperature_alert = 0;unsigned int current_temperature = 0;
F-16
ECE 477 Final Report Spring 2006
struct Acceleration accel = {0,0,0}; //acceleration datachar temp_buf[6]= {0,0,0,0,0,0}; //temperature buffer // globals for GPS data returnunsigned char gps_latitude[ GPS_LATITUDE_LENGTH + 1 ] = {'0','0','0','0','0','0','0','0','0',0}; // ddmm.mmmmunsigned char gps_longitude[ GPS_LONGITUDE_LENGTH + 1 ] = {'0','0','0','0','0','0','0','0','0','0',0}; // dddmm.mmmmunsigned char gps_altitude[ GPS_ALTITUDE_LENGTH + 1 ] = {'0','0','0','0',0}; // mm.munsigned char gps_time[ GPS_TIME_LENGTH + 1 ] = {'0','0','0','0','0','0','0','0','0','0',0}; // hhmmss.sssunsigned char gps_ew = '0'; // E or Wunsigned char gps_ns = '0'; // N or Sunsigned char gps_alt_unit = '0';
#pragma idata my_isection_ppt
ppt_type ppt[ MAX_PPTS ] = { {10,10,10,10,10,10,10}, // ppt0 {10,10,10,10,10,10,10}, // ppt1 {10,10,10,10,10,10,10}, // ppt2 {10,10,10,10,10,10,10}, // ppt3 {10,10,10,10,10,10,10}, // ppt4 {60,61,62,62,62,62,62}, // ppt5 {64,64,64,64,64,64,64}, // ppt6 {10,10,10,10,10,10,10} }; #pragma idata my_isection_ppt2
ppt_type ppt2[ MAX_PPTS ] = { {11,12,13, 32000 ,15,16,17}, // ppt8 {10,10,10,10,10,10,10}, // ppt9 {10,10,10,10,10,10,10}, // ppt10 {10,10,10,10,10,10,10}, // ppt11 {10,10,10,10,10,10,10}, // ppt12 {10,10,10,10,10,10,10}, // ppt13 {10,10,10,10,10,10,10}, // ppt14 {10,10,10,10,10,10,10} }; #pragma udata my_section_2#pragma idata my_isection_2
char mc_rpm[6] = {'0','0','0','0','0',0};char mc_throttle_input[6] = {'0','0','0','0','0',0};char mc_regen_input[6] = {'0','0','0','0','0',0};char mc_phase_current[7] = {'0','0','0','0','0','0',0};char mc_supply_voltage[7] = {'0','0','0','0','0','0',0};char mc_motor_temp[7] = {'0','0','0','0','0','0',0};char mc_heatsink_temp[7] = {'0','0','0','0','0','0',0};char mc_operating_status[4] = {'0','0','0',0};
F-17
ECE 477 Final Report Spring 2006
char mc_observed_rotation_dir[4] = {'0','0','0',0};char mc_fault1[4] = {'0','0','0',0};char mc_fault2[4] = {'0','0','0',0};char mc_fault3[4] = {'0','0','0',0};char mc_fault4[4] = {'0','0','0',0};char mc_throttle_enable[4] = {'0','0','0',0};char mc_input_dir[4] = {'0','0','0',0};char mc_actual_dir[4] = {'0','0','0',0};char mc_speed_control[4] = {'0','0','0',0};char mc_digital_disable_state[4] = {'0','0','0',0};char mc_throttle_enable_state[4] = {'0','0','0',0};char mc_forward_input_state[4] = {'0','0','0',0};
#pragma idata section_imain#pragma idata section_umain
// GLOBAL VARIABLES FOR MAIN AND INTERRUPTS
unsigned int GPS_counter = 0; // timeout counter for GPSunsigned int BPS_counter = 0; // timeout counter for BPSunsigned int MC_counter = 0; // timeout counter for MCunsigned int CAN_counter = 0; // timeout counter for CANunsigned int device_flags = 0x0000; // status register for device flagsunsigned int ppt_status_flags = 0x0000;unsigned char main_state = POLL_GPS;unsigned long int unreal_time_clock = 0;
#pragma idata section_isection_3#pragma udata section_usection_3
unsigned char mc_state = MC_STATE_SEND;unsigned char pm_state = PM_STATE_POLLED;
unsigned int wait_counter = 0;
char cell_voltage[ NUM_BATTERIES ][4] = { {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0},
F-18
ECE 477 Final Report Spring 2006
{'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0} }; char cell_temperature[ NUM_BATTERIES ][4] = { {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0}, {'0','0','0',0} };char battery_current[4] = {'0','0','0',0};char cell_balance[5] = {'0','0','0','0',0};
#define ROTATE_TEXT_MESSAGES
#pragma idata section_itext_message#pragma udata section_utext_message
char di_text_message[12][7] = { {' ',' ','_','_',' ',' ',' '}, {' ',' ',' ',' ',' ',' ',' '}, {' ',' ',' ',' ',' ',' ',' '}, /* __ */ {'|',' ',' ','|','-','-','.'}, /* | |--.--.--.----. */ {'-','-','.','-','-','.','-'}, /* | _ |_ _| _| */ {'-','-','-','.',' ',' ','|'}, /* |_____|__.__|__|bxr*/ {' ',' ','_',' ',' ','|','_'}, {' ',' ',' ','_','|',' ',' '}, {' ','_','|',' ',' ','|','_'},
F-19
ECE 477 Final Report Spring 2006
{'_','_','_','_','|','_','_'}, {'.','_','_','|','_','_','|'}, {'b','x','r',0 ,0 ,0 ,0 } };
#pragma idata section_ibxr_tag#pragma udata section_ubxr_tag const rom char bxr_tag[12][7] = { {' ',' ','_','_',' ',' ',' '}, {' ',' ',' ',' ',' ',' ',' '}, {' ',' ',' ',' ',' ',' ',' '}, /* __ */ {'|',' ',' ','|','-','-','.'}, /* | |--.--.--.----. */ {'-','-','.','-','-','.','-'}, /* | _ |_ _| _| */ {'-','-','-','.',' ',' ','|'}, /* |_____|__.__|__|bxr*/ {' ',' ','_',' ',' ','|','_'}, {' ',' ',' ','_','|',' ',' '}, {' ','_','|',' ',' ','|','_'}, {'_','_','_','_','|','_','_'}, {'.','_','_','|','_','_','|'}, {'b','x','r',0 ,0 ,0 ,0 } }; #pragma idata section_iece#pragma udata section_uece const rom char ece_tag[12][7] = { {'_','/',' ','_','_',' ','`'}, {'_','/',' ','_','_','_','`'}, {'/',' ','_','_',' ','`','`'}, /* _/ __ \_/ ___\/ __ \ */ {' ',' ','_','_','_','/','`'}, /* \ ___/\ \__\ ___/ */ {' ',' ','`','_','_','`',' '}, /* \___ >\___ >__ > */ {' ','_','_','_','/',' ','`'}, /* \/ \/ece\/ */ {'_','_','_',' ',' ','>','`'}, {'_','_','_',' ',' ','>','_'}, {'_',' ',' ','>',' ',' ',' '}, {' ',' ','`','/',' ',' ',' '}, {' ',' ','`','/','e','c','e'}, {'`','/',' ',0 ,0 ,0 ,0 } };
#pragma idata section_isd#pragma udata section_usd
const rom char sd_tag[12][7] = { {' ',' ',' ',' ',' ',' ',' '}, {' ',' ',' ',' ',' ',' ',' '}, {' ','|',' ',' ',' ',' ',' '}, /* | */ {' ',' ',' ',' ','_','_','|'}, /* __| _` | */ {' ',' ',' ',' ','_','`',' '},
F-20
ECE 477 Final Report Spring 2006
/* \__ \ ( | */ {'|',' ',' ',' ',' ',' ',' '}, /* ____/_)\__,_|s.d. */ {' ','`','_','_',' ','`',' '}, {' ',' ','(',' ',' ',' ','|'}, {' ',' ',' ',' ',' ',' ',' '}, {'_','_','_','_','/','_',')'}, {'`','_','_',',','_','|','s'}, {'.','d','.',0 ,0 ,0 ,0 } };
#pragma idata section_ihg#pragma udata section_uhg const rom char hg_tag[12][7] = { {' ',' ',' ',' ','/',' ','/'}, {' ',' ','_','_','_',' ','_'}, {'/',' ','/',' ',' ',' ',' '}, {' ',' ','/',' ','_',' ','`'}, /* / / ___ _/ / */ {'/',' ','_',' ','`','/','_'}, /* / _ \/ _ `/_/ */ {'/',' ',' ',' ',' ',' ',' '}, /* /_//_/\_, (_) */ {'/','_','/','/','_','/','`'}, /* /___/hg! */ {'_',',',' ','(','_',')',' '}, {' ',' ',' ',' ',' ',' ',' '}, {' ',' ',' ',' ','/','_','_'}, {'_','/','h','g','!',' ',' '}, {' ',' ',' ',0 ,0 ,0 ,0 } };
#pragma idata section_ipd#pragma udata section_upd // _ _ _ _ _ // (_ ) (_ ) ( ) ( ) ( )_ // _ _ _ | | | | __ _| | _| | _ _ | ,_) _ _ // ( '_`\ /'_`\ | | | | /'__`\ /'_` | /'_` | /'_` )| | /'_` )// | (_) )( (_) ) | | | | ( ___/( (_| | ( (_| |( (_| || |_ ( (_| |// | ,__/'`\___/'(___)(___)`\____)`\__,_) `\__,_)`\__,_)`\__)`\__,_)// | | // (_)
#pragma idata section_ipolled#pragma udata section_upolled
const rom polled_data_type polled_data[ ALL_DATA_SIZE ] ={ /* ------------------------------------------------- POWER POINT TRACKERS ----------------------------------------------------- */
F-21
ECE 477 Final Report Spring 2006
/* data location, command, device_id, p, designating char, type, size */ { (void*)&(ppt[0].in_voltage), {DC_COMMAND_REQUEST, DC_PPT0_IN_VOLTAGE, 0, 0}, DEVID_PPT0, 1, DC_PPT0_IN_VOLTAGE, TYPE_INT, 1 }, //0 { (void*)&(ppt[0].out_voltage), {DC_COMMAND_REQUEST, DC_PPT0_OUT_VOLTAGE, 0, 0}, DEVID_PPT0, 1, DC_PPT0_OUT_VOLTAGE, TYPE_INT, 1 }, //1 { (void*)&(ppt[0].in_current), {DC_COMMAND_REQUEST, DC_PPT0_IN_CURRENT, 0, 0}, DEVID_PPT0, 1, DC_PPT0_IN_CURRENT, TYPE_INT, 1 }, //2 { (void*)&(ppt[0].out_current), {DC_COMMAND_REQUEST, DC_PPT0_OUT_CURRENT, 0, 0}, DEVID_PPT0, 1, DC_PPT0_OUT_CURRENT, TYPE_INT, 1 }, //3 { (void*)&(ppt[0].temperature), {DC_COMMAND_REQUEST, DC_PPT0_TEMPERATURE, 0, 0}, DEVID_PPT0, 1, DC_PPT0_TEMPERATURE, TYPE_INT, 1 }, //4 { (void*)&(ppt[0].max_power), {DC_COMMAND_REQUEST, DC_PPT0_MAX_POWER, 0, 0}, DEVID_PPT0, 1, DC_PPT0_MAX_POWER, TYPE_INT, 1 }, //5 { (void*)&(ppt[0].reserved), {DC_COMMAND_REQUEST, DC_PPT0_RESERVED, 0, 0}, DEVID_PPT0, 1, DC_PPT0_RESERVED, TYPE_INT, 1 }, //6 { (void*)&(ppt[0].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 }, //7
{ (void*)&(ppt[1].in_voltage), {DC_COMMAND_REQUEST, DC_PPT1_IN_VOLTAGE, 0, 0}, DEVID_PPT1, 1, DC_PPT1_IN_VOLTAGE, TYPE_INT, 1 }, //8 { (void*)&(ppt[1].out_voltage), {DC_COMMAND_REQUEST, DC_PPT1_OUT_VOLTAGE, 0, 0}, DEVID_PPT1, 1, DC_PPT1_OUT_VOLTAGE, TYPE_INT, 1 }, //9 { (void*)&(ppt[1].in_current), {DC_COMMAND_REQUEST, DC_PPT1_IN_CURRENT, 0, 0}, DEVID_PPT1, 1, DC_PPT1_IN_CURRENT, TYPE_INT, 1 }, //10 { (void*)&(ppt[1].out_current), {DC_COMMAND_REQUEST, DC_PPT1_OUT_CURRENT, 0, 0}, DEVID_PPT1, 1, DC_PPT1_OUT_CURRENT, TYPE_INT, 1 }, //11 { (void*)&(ppt[1].temperature), {DC_COMMAND_REQUEST, DC_PPT1_TEMPERATURE, 0, 0}, DEVID_PPT1, 1, DC_PPT1_TEMPERATURE, TYPE_INT, 1 }, //12 { (void*)&(ppt[1].max_power), {DC_COMMAND_REQUEST, DC_PPT1_MAX_POWER, 0, 0}, DEVID_PPT1, 1, DC_PPT1_MAX_POWER, TYPE_INT, 1 }, //13 { (void*)&(ppt[1].reserved), {DC_COMMAND_REQUEST, DC_PPT1_RESERVED, 0, 0}, DEVID_PPT1, 1, DC_PPT1_RESERVED, TYPE_INT, 1 }, //14 { (void*)&(ppt[1].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 }, //15 { (void*)&(ppt[2].in_voltage), {DC_COMMAND_REQUEST, DC_PPT2_IN_VOLTAGE, 0, 0}, DEVID_PPT2, 1, DC_PPT2_IN_VOLTAGE, TYPE_INT, 1 }, //16 { (void*)&(ppt[2].out_voltage), {DC_COMMAND_REQUEST, DC_PPT2_OUT_VOLTAGE, 0, 0}, DEVID_PPT2, 1, DC_PPT2_OUT_VOLTAGE, TYPE_INT, 1 }, //17 { (void*)&(ppt[2].in_current), {DC_COMMAND_REQUEST, DC_PPT2_IN_CURRENT, 0, 0}, DEVID_PPT2, 1, DC_PPT2_IN_CURRENT, TYPE_INT, 1 }, //18 { (void*)&(ppt[2].out_current), {DC_COMMAND_REQUEST, DC_PPT2_OUT_CURRENT, 0, 0}, DEVID_PPT2, 1, DC_PPT2_OUT_CURRENT, TYPE_INT, 1 }, //19
F-22
ECE 477 Final Report Spring 2006
{ (void*)&(ppt[2].temperature), {DC_COMMAND_REQUEST, DC_PPT2_TEMPERATURE, 0, 0}, DEVID_PPT2, 1, DC_PPT2_TEMPERATURE, TYPE_INT, 1 }, //20 { (void*)&(ppt[2].max_power), {DC_COMMAND_REQUEST, DC_PPT2_MAX_POWER, 0, 0}, DEVID_PPT2, 1, DC_PPT2_MAX_POWER, TYPE_INT, 1 }, //21 { (void*)&(ppt[2].reserved), {DC_COMMAND_REQUEST, DC_PPT2_RESERVED, 0, 0}, DEVID_PPT2, 1, DC_PPT2_RESERVED, TYPE_INT, 1 }, //22 { (void*)&(ppt[2].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 }, //23 { (void*)&(ppt[3].in_voltage), {DC_COMMAND_REQUEST, DC_PPT3_IN_VOLTAGE, 0, 0}, DEVID_PPT3, 1, DC_PPT3_IN_VOLTAGE, TYPE_INT, 1 }, //24 { (void*)&(ppt[3].out_voltage), {DC_COMMAND_REQUEST, DC_PPT3_OUT_VOLTAGE, 0, 0}, DEVID_PPT3, 1, DC_PPT3_OUT_VOLTAGE, TYPE_INT, 1 }, //25 { (void*)&(ppt[3].in_current), {DC_COMMAND_REQUEST, DC_PPT3_IN_CURRENT, 0, 0}, DEVID_PPT3, 1, DC_PPT3_IN_CURRENT, TYPE_INT, 1 }, //26 { (void*)&(ppt[3].out_current), {DC_COMMAND_REQUEST, DC_PPT3_OUT_CURRENT, 0, 0}, DEVID_PPT3, 1, DC_PPT3_OUT_CURRENT, TYPE_INT, 1 }, //27 { (void*)&(ppt[3].temperature), {DC_COMMAND_REQUEST, DC_PPT3_TEMPERATURE, 0, 0}, DEVID_PPT3, 1, DC_PPT3_TEMPERATURE, TYPE_INT, 1 }, //28 { (void*)&(ppt[3].max_power), {DC_COMMAND_REQUEST, DC_PPT3_MAX_POWER, 0, 0}, DEVID_PPT3, 1, DC_PPT3_MAX_POWER, TYPE_INT, 1 }, //29 { (void*)&(ppt[3].reserved), {DC_COMMAND_REQUEST, DC_PPT3_RESERVED, 0, 0}, DEVID_PPT3, 1, DC_PPT3_RESERVED, TYPE_INT, 1 }, //30 { (void*)&(ppt[3].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 }, //31 { (void*)&(ppt[4].in_voltage), {DC_COMMAND_REQUEST, DC_PPT4_IN_VOLTAGE, 0, 0}, DEVID_PPT4, 1, DC_PPT4_IN_VOLTAGE, TYPE_INT, 1 }, //32 { (void*)&(ppt[4].out_voltage), {DC_COMMAND_REQUEST, DC_PPT4_OUT_VOLTAGE, 0, 0}, DEVID_PPT4, 1, DC_PPT4_OUT_VOLTAGE, TYPE_INT, 1 }, //33 { (void*)&(ppt[4].in_current), {DC_COMMAND_REQUEST, DC_PPT4_IN_CURRENT, 0, 0}, DEVID_PPT4, 1, DC_PPT4_IN_CURRENT, TYPE_INT, 1 }, //34 { (void*)&(ppt[4].out_current), {DC_COMMAND_REQUEST, DC_PPT4_OUT_CURRENT, 0, 0}, DEVID_PPT4, 1, DC_PPT4_OUT_CURRENT, TYPE_INT, 1 }, //35 { (void*)&(ppt[4].temperature), {DC_COMMAND_REQUEST, DC_PPT4_TEMPERATURE, 0, 0}, DEVID_PPT4, 1, DC_PPT4_TEMPERATURE, TYPE_INT, 1 }, //36 { (void*)&(ppt[4].max_power), {DC_COMMAND_REQUEST, DC_PPT4_MAX_POWER, 0, 0}, DEVID_PPT4, 1, DC_PPT4_MAX_POWER, TYPE_INT, 1 }, //37 { (void*)&(ppt[4].reserved), {DC_COMMAND_REQUEST, DC_PPT4_RESERVED, 0, 0}, DEVID_PPT4, 1, DC_PPT4_RESERVED, TYPE_INT, 1 }, //38 { (void*)&(ppt[4].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 }, //39 { (void*)&(ppt[5].in_voltage), {DC_COMMAND_REQUEST, DC_PPT5_IN_VOLTAGE, 0, 0}, DEVID_PPT5, 1, DC_PPT5_IN_VOLTAGE, TYPE_INT, 1 }, //40
F-23
ECE 477 Final Report Spring 2006
{ (void*)&(ppt[5].out_voltage), {DC_COMMAND_REQUEST, DC_PPT5_OUT_VOLTAGE, 0, 0}, DEVID_PPT5, 1, DC_PPT5_OUT_VOLTAGE, TYPE_INT, 1 }, //41 { (void*)&(ppt[5].in_current), {DC_COMMAND_REQUEST, DC_PPT5_IN_CURRENT, 0, 0}, DEVID_PPT5, 1, DC_PPT5_IN_CURRENT, TYPE_INT, 1 }, //42 { (void*)&(ppt[5].out_current), {DC_COMMAND_REQUEST, DC_PPT5_OUT_CURRENT, 0, 0}, DEVID_PPT5, 1, DC_PPT5_OUT_CURRENT, TYPE_INT, 1 }, //43 { (void*)&(ppt[5].temperature), {DC_COMMAND_REQUEST, DC_PPT5_TEMPERATURE, 0, 0}, DEVID_PPT5, 1, DC_PPT5_TEMPERATURE, TYPE_INT, 1 }, //44 { (void*)&(ppt[5].max_power), {DC_COMMAND_REQUEST, DC_PPT5_MAX_POWER, 0, 0}, DEVID_PPT5, 1, DC_PPT5_MAX_POWER, TYPE_INT, 1 }, //45 { (void*)&(ppt[5].reserved), {DC_COMMAND_REQUEST, DC_PPT5_RESERVED, 0, 0}, DEVID_PPT5, 1, DC_PPT5_RESERVED, TYPE_INT, 1 }, //46 { (void*)&(ppt[5].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 }, //47 /* data location, command, device_id, p, designating char, type, size */ { (void*)&(ppt[6].in_voltage), {DC_COMMAND_REQUEST, DC_PPT6_IN_VOLTAGE, 0, 0}, DEVID_PPT6, 1, DC_PPT6_IN_VOLTAGE, TYPE_INT, 1 },//48 { (void*)&(ppt[6].out_voltage), {DC_COMMAND_REQUEST, DC_PPT6_OUT_VOLTAGE, 0, 0}, DEVID_PPT6, 1, DC_PPT6_OUT_VOLTAGE, TYPE_INT, 1 },//49 { (void*)&(ppt[6].in_current), {DC_COMMAND_REQUEST, DC_PPT6_IN_CURRENT, 0, 0}, DEVID_PPT6, 1, DC_PPT6_IN_CURRENT, TYPE_INT, 1 },//50 { (void*)&(ppt[6].out_current), {DC_COMMAND_REQUEST, DC_PPT6_OUT_CURRENT, 0, 0}, DEVID_PPT6, 1, DC_PPT6_OUT_CURRENT, TYPE_INT, 1 },//51 { (void*)&(ppt[6].temperature), {DC_COMMAND_REQUEST, DC_PPT6_TEMPERATURE, 0, 0}, DEVID_PPT6, 1, DC_PPT6_TEMPERATURE, TYPE_INT, 1 },//52 { (void*)&(ppt[6].max_power), {DC_COMMAND_REQUEST, DC_PPT6_MAX_POWER, 0, 0}, DEVID_PPT6, 1, DC_PPT6_MAX_POWER, TYPE_INT, 1 },//53 { (void*)&(ppt[6].reserved), {DC_COMMAND_REQUEST, DC_PPT6_RESERVED, 0, 0}, DEVID_PPT6, 1, DC_PPT6_RESERVED, TYPE_INT, 1 },//54 { (void*)&(ppt[6].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 },//55 { (void*)&(ppt[7].in_voltage), {DC_COMMAND_REQUEST, DC_PPT7_IN_VOLTAGE, 0, 0}, DEVID_PPT7, 1, DC_PPT7_IN_VOLTAGE, TYPE_INT, 1 },//56 { (void*)&(ppt[7].out_voltage), {DC_COMMAND_REQUEST, DC_PPT7_OUT_VOLTAGE, 0, 0}, DEVID_PPT7, 1, DC_PPT7_OUT_VOLTAGE, TYPE_INT, 1 },//57 { (void*)&(ppt[7].in_current), {DC_COMMAND_REQUEST, DC_PPT7_IN_CURRENT, 0, 0}, DEVID_PPT7, 1, DC_PPT7_IN_CURRENT, TYPE_INT, 1 },//58 { (void*)&(ppt[7].out_current), {DC_COMMAND_REQUEST, DC_PPT7_OUT_CURRENT, 0, 0}, DEVID_PPT7, 1, DC_PPT7_OUT_CURRENT, TYPE_INT, 1 },//59 { (void*)&(ppt[7].temperature), {DC_COMMAND_REQUEST, DC_PPT7_TEMPERATURE, 0, 0}, DEVID_PPT7, 1, DC_PPT7_TEMPERATURE, TYPE_INT, 1 },//60
F-24
ECE 477 Final Report Spring 2006
{ (void*)&(ppt[7].max_power), {DC_COMMAND_REQUEST, DC_PPT7_MAX_POWER, 0, 0}, DEVID_PPT7, 1, DC_PPT7_MAX_POWER, TYPE_INT, 1 },//61 { (void*)&(ppt[7].reserved), {DC_COMMAND_REQUEST, DC_PPT7_RESERVED, 0, 0}, DEVID_PPT7, 1, DC_PPT7_RESERVED, TYPE_INT, 1 },//62 { (void*)&(ppt[7].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 },//63
{ (void*)&(ppt2[0].in_voltage), {DC_COMMAND_REQUEST, DC_PPT8_IN_VOLTAGE, 0, 0}, DEVID_PPT8, 1, DC_PPT8_IN_VOLTAGE, TYPE_INT, 1 },//64 { (void*)&(ppt2[0].out_voltage), {DC_COMMAND_REQUEST, DC_PPT8_OUT_VOLTAGE, 0, 0}, DEVID_PPT8, 1, DC_PPT8_OUT_VOLTAGE, TYPE_INT, 1 },//65 { (void*)&(ppt2[0].in_current), {DC_COMMAND_REQUEST, DC_PPT8_IN_CURRENT, 0, 0}, DEVID_PPT8, 1, DC_PPT8_IN_CURRENT, TYPE_INT, 1 },//66 { (void*)&(ppt2[0].out_current), {DC_COMMAND_REQUEST, DC_PPT8_OUT_CURRENT, 0, 0}, DEVID_PPT8, 1, DC_PPT8_OUT_CURRENT, TYPE_INT, 1 },//67 { (void*)&(ppt2[0].temperature), {DC_COMMAND_REQUEST, DC_PPT8_TEMPERATURE, 0, 0}, DEVID_PPT8, 1, DC_PPT8_TEMPERATURE, TYPE_INT, 1 },//68 { (void*)&(ppt2[0].max_power), {DC_COMMAND_REQUEST, DC_PPT8_MAX_POWER, 0, 0}, DEVID_PPT8, 1, DC_PPT8_MAX_POWER, TYPE_INT, 1 },//69 { (void*)&(ppt2[0].reserved), {DC_COMMAND_REQUEST, DC_PPT8_RESERVED, 0, 0}, DEVID_PPT8, 1, DC_PPT8_RESERVED, TYPE_INT, 1 },//70 { (void*)&(ppt2[0].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 },//71
{ (void*)&(ppt2[1].in_voltage), {DC_COMMAND_REQUEST, DC_PPT9_IN_VOLTAGE, 0, 0}, DEVID_PPT9, 1, DC_PPT9_IN_VOLTAGE, TYPE_INT, 1 },//72 { (void*)&(ppt2[1].out_voltage), {DC_COMMAND_REQUEST, DC_PPT9_OUT_VOLTAGE, 0, 0}, DEVID_PPT9, 1, DC_PPT9_OUT_VOLTAGE, TYPE_INT, 1 },//73 { (void*)&(ppt2[1].in_current), {DC_COMMAND_REQUEST, DC_PPT9_IN_CURRENT, 0, 0}, DEVID_PPT9, 1, DC_PPT9_IN_CURRENT, TYPE_INT, 1 },//74 { (void*)&(ppt2[1].out_current), {DC_COMMAND_REQUEST, DC_PPT9_OUT_CURRENT, 0, 0}, DEVID_PPT9, 1, DC_PPT9_OUT_CURRENT, TYPE_INT, 1 },//75 { (void*)&(ppt2[1].temperature), {DC_COMMAND_REQUEST, DC_PPT9_TEMPERATURE, 0, 0}, DEVID_PPT9, 1, DC_PPT9_TEMPERATURE, TYPE_INT, 1 },//76 { (void*)&(ppt2[1].max_power), {DC_COMMAND_REQUEST, DC_PPT9_MAX_POWER, 0, 0}, DEVID_PPT9, 1, DC_PPT9_MAX_POWER, TYPE_INT, 1 },//77 { (void*)&(ppt2[1].reserved), {DC_COMMAND_REQUEST, DC_PPT9_RESERVED, 0, 0}, DEVID_PPT9, 1, DC_PPT9_RESERVED, TYPE_INT, 1 },//78 { (void*)&(ppt2[1].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 },//79
{ (void*)&(ppt2[2].in_voltage), {DC_COMMAND_REQUEST, DC_PPT10_IN_VOLTAGE, 0, 0}, DEVID_PPT10, 1, DC_PPT10_IN_VOLTAGE, TYPE_INT, 1 },//80 { (void*)&(ppt2[2].out_voltage), {DC_COMMAND_REQUEST, DC_PPT10_OUT_VOLTAGE, 0, 0}, DEVID_PPT10, 1, DC_PPT10_OUT_VOLTAGE, TYPE_INT, 1 },//81
F-25
ECE 477 Final Report Spring 2006
{ (void*)&(ppt2[2].in_current), {DC_COMMAND_REQUEST, DC_PPT10_IN_CURRENT, 0, 0}, DEVID_PPT10, 1, DC_PPT10_IN_CURRENT, TYPE_INT, 1 },//82 { (void*)&(ppt2[2].out_current), {DC_COMMAND_REQUEST, DC_PPT10_OUT_CURRENT, 0, 0}, DEVID_PPT10, 1, DC_PPT10_OUT_CURRENT, TYPE_INT, 1 },//83 { (void*)&(ppt2[2].temperature), {DC_COMMAND_REQUEST, DC_PPT10_TEMPERATURE, 0, 0}, DEVID_PPT10, 1, DC_PPT10_TEMPERATURE, TYPE_INT, 1 },//84 { (void*)&(ppt2[2].max_power), {DC_COMMAND_REQUEST, DC_PPT10_MAX_POWER, 0, 0}, DEVID_PPT10, 1, DC_PPT10_MAX_POWER, TYPE_INT, 1 },//85 { (void*)&(ppt2[2].reserved), {DC_COMMAND_REQUEST, DC_PPT10_RESERVED, 0, 0}, DEVID_PPT10, 1, DC_PPT10_RESERVED, TYPE_INT, 1 },//86 { (void*)&(ppt2[2].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 },//87
/* data location, command, device_id, p, designating char, type, size */ { (void*)&(ppt2[3].in_voltage), {DC_COMMAND_REQUEST, DC_PPT11_IN_VOLTAGE, 0, 0}, DEVID_PPT11, 1, DC_PPT11_IN_VOLTAGE, TYPE_INT, 1 },//88 { (void*)&(ppt2[3].out_voltage), {DC_COMMAND_REQUEST, DC_PPT11_OUT_VOLTAGE, 0, 0}, DEVID_PPT11, 1, DC_PPT11_OUT_VOLTAGE, TYPE_INT, 1 },//89 { (void*)&(ppt2[3].in_current), {DC_COMMAND_REQUEST, DC_PPT11_IN_CURRENT, 0, 0}, DEVID_PPT11, 1, DC_PPT11_IN_CURRENT, TYPE_INT, 1 },//90 { (void*)&(ppt2[3].out_current), {DC_COMMAND_REQUEST, DC_PPT11_OUT_CURRENT, 0, 0}, DEVID_PPT11, 1, DC_PPT11_OUT_CURRENT, TYPE_INT, 1 },//91 { (void*)&(ppt2[3].temperature), {DC_COMMAND_REQUEST, DC_PPT11_TEMPERATURE, 0, 0}, DEVID_PPT11, 1, DC_PPT11_TEMPERATURE, TYPE_INT, 1 },//92 { (void*)&(ppt2[3].max_power), {DC_COMMAND_REQUEST, DC_PPT11_MAX_POWER, 0, 0}, DEVID_PPT11, 1, DC_PPT11_MAX_POWER, TYPE_INT, 1 },//93 { (void*)&(ppt2[3].reserved), {DC_COMMAND_REQUEST, DC_PPT11_RESERVED, 0, 0}, DEVID_PPT11, 1, DC_PPT11_RESERVED, TYPE_INT, 1 },//94 { (void*)&(ppt2[3].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 },//95
{ (void*)&(ppt2[4].in_voltage), {DC_COMMAND_REQUEST, DC_PPT12_IN_VOLTAGE, 0, 0}, DEVID_PPT12, 1, DC_PPT12_IN_VOLTAGE, TYPE_INT, 1 },//96 { (void*)&(ppt2[4].out_voltage), {DC_COMMAND_REQUEST, DC_PPT12_OUT_VOLTAGE, 0, 0}, DEVID_PPT12, 1, DC_PPT12_OUT_VOLTAGE, TYPE_INT, 1 },//97 { (void*)&(ppt2[4].in_current), {DC_COMMAND_REQUEST, DC_PPT12_IN_CURRENT, 0, 0}, DEVID_PPT12, 1, DC_PPT12_IN_CURRENT, TYPE_INT, 1 },//98 { (void*)&(ppt2[4].out_current), {DC_COMMAND_REQUEST, DC_PPT12_OUT_CURRENT, 0, 0}, DEVID_PPT12, 1, DC_PPT12_OUT_CURRENT, TYPE_INT, 1 },//99 { (void*)&(ppt2[4].temperature), {DC_COMMAND_REQUEST, DC_PPT12_TEMPERATURE, 0, 0}, DEVID_PPT12, 1, DC_PPT12_TEMPERATURE, TYPE_INT, 1 },//100 { (void*)&(ppt2[4].max_power), {DC_COMMAND_REQUEST, DC_PPT12_MAX_POWER, 0, 0}, DEVID_PPT12, 1, DC_PPT12_MAX_POWER, TYPE_INT, 1 },//101
F-26
ECE 477 Final Report Spring 2006
{ (void*)&(ppt2[4].reserved), {DC_COMMAND_REQUEST, DC_PPT12_RESERVED, 0, 0}, DEVID_PPT12, 1, DC_PPT12_RESERVED, TYPE_INT, 1 },//102 { (void*)&(ppt2[4].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 },//103
{ (void*)&(ppt2[5].in_voltage), {DC_COMMAND_REQUEST, DC_PPT13_IN_VOLTAGE, 0, 0}, DEVID_PPT13, 1, DC_PPT13_IN_VOLTAGE, TYPE_INT, 1 },//104 { (void*)&(ppt2[5].out_voltage), {DC_COMMAND_REQUEST, DC_PPT13_OUT_VOLTAGE, 0, 0}, DEVID_PPT13, 1, DC_PPT13_OUT_VOLTAGE, TYPE_INT, 1 },//105 { (void*)&(ppt2[5].in_current), {DC_COMMAND_REQUEST, DC_PPT13_IN_CURRENT, 0, 0}, DEVID_PPT13, 1, DC_PPT13_IN_CURRENT, TYPE_INT, 1 },//106 { (void*)&(ppt2[5].out_current), {DC_COMMAND_REQUEST, DC_PPT13_OUT_CURRENT, 0, 0}, DEVID_PPT13, 1, DC_PPT13_OUT_CURRENT, TYPE_INT, 1 },//107 { (void*)&(ppt2[5].temperature), {DC_COMMAND_REQUEST, DC_PPT13_TEMPERATURE, 0, 0}, DEVID_PPT13, 1, DC_PPT13_TEMPERATURE, TYPE_INT, 1 },//108 { (void*)&(ppt2[5].max_power), {DC_COMMAND_REQUEST, DC_PPT13_MAX_POWER, 0, 0}, DEVID_PPT13, 1, DC_PPT13_MAX_POWER, TYPE_INT, 1 },//109 { (void*)&(ppt2[5].reserved), {DC_COMMAND_REQUEST, DC_PPT13_RESERVED, 0, 0}, DEVID_PPT13, 1, DC_PPT13_RESERVED, TYPE_INT, 1 },//110 { (void*)&(ppt2[5].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 },//111
{ (void*)&(ppt2[6].in_voltage), {DC_COMMAND_REQUEST, DC_PPT14_IN_VOLTAGE, 0, 0}, DEVID_PPT14, 1, DC_PPT14_IN_VOLTAGE, TYPE_INT, 1 },//112 { (void*)&(ppt2[6].out_voltage), {DC_COMMAND_REQUEST, DC_PPT14_OUT_VOLTAGE, 0, 0}, DEVID_PPT14, 1, DC_PPT14_OUT_VOLTAGE, TYPE_INT, 1 },//113 { (void*)&(ppt2[6].in_current), {DC_COMMAND_REQUEST, DC_PPT14_IN_CURRENT, 0, 0}, DEVID_PPT14, 1, DC_PPT14_IN_CURRENT, TYPE_INT, 1 },//114 { (void*)&(ppt2[6].out_current), {DC_COMMAND_REQUEST, DC_PPT14_OUT_CURRENT, 0, 0}, DEVID_PPT14, 1, DC_PPT14_OUT_CURRENT, TYPE_INT, 1 },//115 { (void*)&(ppt2[6].temperature), {DC_COMMAND_REQUEST, DC_PPT14_TEMPERATURE, 0, 0}, DEVID_PPT14, 1, DC_PPT14_TEMPERATURE, TYPE_INT, 1 },//116 { (void*)&(ppt2[6].max_power), {DC_COMMAND_REQUEST, DC_PPT14_MAX_POWER, 0, 0}, DEVID_PPT14, 1, DC_PPT14_MAX_POWER, TYPE_INT, 1 },//117 { (void*)&(ppt2[6].reserved), {DC_COMMAND_REQUEST, DC_PPT14_RESERVED, 0, 0}, DEVID_PPT14, 1, DC_PPT14_RESERVED, TYPE_INT, 1 },//118 { (void*)&(ppt2[6].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 },//119
{ (void*)&(ppt2[7].in_voltage), {DC_COMMAND_REQUEST, DC_PPT15_IN_VOLTAGE, 0, 0}, DEVID_PPT15, 1, DC_PPT15_IN_VOLTAGE, TYPE_INT, 1 },//120 { (void*)&(ppt2[7].out_voltage), {DC_COMMAND_REQUEST, DC_PPT15_OUT_VOLTAGE, 0, 0}, DEVID_PPT15, 1, DC_PPT15_OUT_VOLTAGE, TYPE_INT, 1 },//121 { (void*)&(ppt2[7].in_current), {DC_COMMAND_REQUEST, DC_PPT15_IN_CURRENT, 0, 0}, DEVID_PPT15, 1, DC_PPT15_IN_CURRENT, TYPE_INT, 1 },//122
F-27
ECE 477 Final Report Spring 2006
{ (void*)&(ppt2[7].out_current), {DC_COMMAND_REQUEST, DC_PPT15_OUT_CURRENT, 0, 0}, DEVID_PPT15, 1, DC_PPT15_OUT_CURRENT, TYPE_INT, 1 },//123 { (void*)&(ppt2[7].temperature), {DC_COMMAND_REQUEST, DC_PPT15_TEMPERATURE, 0, 0}, DEVID_PPT15, 1, DC_PPT15_TEMPERATURE, TYPE_INT, 1 },//124 { (void*)&(ppt2[7].max_power), {DC_COMMAND_REQUEST, DC_PPT15_MAX_POWER, 0, 0}, DEVID_PPT15, 1, DC_PPT15_MAX_POWER, TYPE_INT, 1 },//125 { (void*)&(ppt2[7].reserved), {DC_COMMAND_REQUEST, DC_PPT15_RESERVED, 0, 0}, DEVID_PPT15, 1, DC_PPT15_RESERVED, TYPE_INT, 1 },//126 { (void*)&(ppt2[7].reserved), {0,0,0,0}, 0, 0, 0, 0, 0 },//127
/* ------------------------------------------------- MOTOR CONTROLLER --------------------------------------------------- */ /* data location, command, device_id, p, designating char, data_type, data_size */ { (void*)mc_rpm, {'0','C','?', CR}, DEVID_MOTOR, 1, DC_MC_RPM, TYPE_ASCII_DECIMAL, 5 },//128 { (void*)mc_throttle_input, {'1','7','?', CR}, DEVID_MOTOR, 1, DC_MC_THROTTLE_INPUT, TYPE_ASCII_DECIMAL, 5 },//129 { (void*)mc_regen_input, {'1','8','?', CR}, DEVID_MOTOR, 1, DC_MC_REGEN_INPUT, TYPE_ASCII_DECIMAL, 5 },//130 { (void*)mc_phase_current, {'6','1','?', CR}, DEVID_MOTOR, 1, DC_MC_PHASE_CURRENT, TYPE_ASCII_DECIMAL, 6 },//131 { (void*)mc_supply_voltage, {'6','4','?', CR}, DEVID_MOTOR, 1, DC_MC_SUPPLY_VOLTAGE, TYPE_ASCII_DECIMAL, 6 },//132 { (void*)mc_motor_temp, {'6','5','?', CR}, DEVID_MOTOR, 1, DC_MC_MOTOR_TEMP, TYPE_ASCII_DECIMAL, 6 },//133 { (void*)mc_heatsink_temp, {'6','6','?', CR}, DEVID_MOTOR, 1, DC_MC_HEATSINK_TEMP, TYPE_ASCII_DECIMAL, 6 },//134 { (void*)mc_operating_status, {'9','6','?', CR}, DEVID_MOTOR, 1, DC_MC_OPERATING_STATUS, TYPE_ASCII_DECIMAL, 3 },//135 { (void*)mc_observed_rotation_dir, {'9','7','?', CR}, DEVID_MOTOR, 1, DC_MC_OBSERVED_ROTATION_DIR, TYPE_ASCII_DECIMAL, 3 },//136 { (void*)mc_fault1, {'9','9','?', CR}, DEVID_MOTOR, 1, DC_MC_FAULT1, TYPE_ASCII_DECIMAL, 3 },//137 { (void*)mc_fault2, {'9','A','?', CR}, DEVID_MOTOR, 1, DC_MC_FAULT2, TYPE_ASCII_DECIMAL, 3 },//138 { (void*)mc_fault3, {'9','B','?', CR}, DEVID_MOTOR, 1, DC_MC_FAULT3, TYPE_ASCII_DECIMAL, 3 },//139 { (void*)mc_fault4, {'9','C','?', CR}, DEVID_MOTOR, 1, DC_MC_FAULT4, TYPE_ASCII_DECIMAL, 3 },//140 { (void*)mc_throttle_enable, {'9','F','?', CR}, DEVID_MOTOR, 1, DC_MC_THROTTLE_ENABLE, TYPE_ASCII_DECIMAL, 3 },//141 { (void*)mc_input_dir, {'A','0','?', CR}, DEVID_MOTOR, 1, DC_MC_INPUT_DIR, TYPE_ASCII_DECIMAL, 3 },//142
F-28
ECE 477 Final Report Spring 2006
{ (void*)mc_actual_dir, {'A','1','?', CR}, DEVID_MOTOR, 1, DC_MC_ACTUAL_DIR, TYPE_ASCII_DECIMAL, 3 },//143 { (void*)mc_speed_control, {'A','2','?', CR}, DEVID_MOTOR, 1, DC_MC_SPEED_CONTROL, TYPE_ASCII_DECIMAL, 3 },//144 { (void*)mc_digital_disable_state, {'A','A','?', CR}, DEVID_MOTOR, 1, DC_MC_DIGITAL_DISABLE_STATE, TYPE_ASCII_DECIMAL, 3 },//145 { (void*)mc_throttle_enable_state, {'A','B','?', CR}, DEVID_MOTOR, 1, DC_MC_THROTTLE_ENABLE_STATE, TYPE_ASCII_DECIMAL, 3 },//146 { (void*)mc_forward_input_state, {'A','C','?', CR}, DEVID_MOTOR, 1, DC_MC_FORWARD_INPUT_STATE, TYPE_ASCII_DECIMAL, 3 },//147 /* ------------------------------------------------- BATTERY!!!!!!!!! --------------------------------------------------- */ /* data location, command, device_id, p, designating char, data_type, data_size */ { (void*)&(cell_voltage[0]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_1_VOLTAGE, TYPE_ASCII_HEX, 3 },//148 { (void*)&(cell_voltage[1]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_2_VOLTAGE, TYPE_ASCII_HEX, 3 },//149 { (void*)&(cell_voltage[2]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_3_VOLTAGE, TYPE_ASCII_HEX, 3 },//150 { (void*)&(cell_voltage[3]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_4_VOLTAGE, TYPE_ASCII_HEX, 3 },//151 { (void*)&(cell_voltage[4]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_5_VOLTAGE, TYPE_ASCII_HEX, 3 },//152 { (void*)&(cell_voltage[5]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_6_VOLTAGE, TYPE_ASCII_HEX, 3 },//153 { (void*)&(cell_voltage[6]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_7_VOLTAGE, TYPE_ASCII_HEX, 3 },//154 { (void*)&(cell_voltage[7]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_8_VOLTAGE, TYPE_ASCII_HEX, 3 },//155 { (void*)&(cell_voltage[8]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_9_VOLTAGE, TYPE_ASCII_HEX, 3 },//156 { (void*)&(cell_voltage[9]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_10_VOLTAGE, TYPE_ASCII_HEX, 3 },//157 { (void*)&(cell_voltage[10]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_11_VOLTAGE, TYPE_ASCII_HEX, 3 },//158 { (void*)&(cell_voltage[11]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_12_VOLTAGE, TYPE_ASCII_HEX, 3 },//159 { (void*)&(cell_voltage[12]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_13_VOLTAGE, TYPE_ASCII_HEX, 3 },//160 { (void*)&(cell_voltage[13]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_14_VOLTAGE, TYPE_ASCII_HEX, 3 },//161 { (void*)&(cell_voltage[14]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_15_VOLTAGE, TYPE_ASCII_HEX, 3 },//162 { (void*)&(cell_temperature[0]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_1_TEMPERATURE, TYPE_ASCII_HEX, 3 },//163 { (void*)&(cell_temperature[1]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_2_TEMPERATURE, TYPE_ASCII_HEX, 3 },//164 { (void*)&(cell_temperature[2]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_3_TEMPERATURE, TYPE_ASCII_HEX, 3 },//165 { (void*)&(cell_temperature[3]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_4_TEMPERATURE, TYPE_ASCII_HEX, 3 },//166 { (void*)&(cell_temperature[4]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_5_TEMPERATURE, TYPE_ASCII_HEX, 3 },//167 { (void*)&(cell_temperature[5]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_6_TEMPERATURE, TYPE_ASCII_HEX, 3 },//168 { (void*)&(cell_temperature[6]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_7_TEMPERATURE, TYPE_ASCII_HEX, 3 },//169 { (void*)&(cell_temperature[7]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_8_TEMPERATURE, TYPE_ASCII_HEX, 3 },//170 { (void*)&(cell_temperature[8]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_9_TEMPERATURE, TYPE_ASCII_HEX, 3 },//171 { (void*)&(cell_temperature[9]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_10_TEMPERATURE, TYPE_ASCII_HEX, 3 },//172 { (void*)&(cell_temperature[10]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_11_TEMPERATURE, TYPE_ASCII_HEX, 3 },//173 { (void*)&(cell_temperature[11]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_12_TEMPERATURE, TYPE_ASCII_HEX, 3 },//174 { (void*)&(cell_temperature[12]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_13_TEMPERATURE, TYPE_ASCII_HEX, 3 },//175 { (void*)&(cell_temperature[13]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_14_TEMPERATURE, TYPE_ASCII_HEX, 3 },//176 { (void*)&(cell_temperature[14]), {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_15_TEMPERATURE, TYPE_ASCII_HEX, 3 },//177
F-29
ECE 477 Final Report Spring 2006
{ (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_1_BALANCING, TYPE_ASCII_HEX, 3 },//178 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_2_BALANCING, TYPE_ASCII_HEX, 3 },//179 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_3_BALANCING, TYPE_ASCII_HEX, 3 },//180 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_4_BALANCING, TYPE_ASCII_HEX, 3 },//181 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_5_BALANCING, TYPE_ASCII_HEX, 3 },//182 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_6_BALANCING, TYPE_ASCII_HEX, 3 },//183 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_7_BALANCING, TYPE_ASCII_HEX, 3 },//184 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_8_BALANCING, TYPE_ASCII_HEX, 3 },//185 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_9_BALANCING, TYPE_ASCII_HEX, 3 },//186 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_10_BALANCING, TYPE_ASCII_HEX, 3 },//187 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_11_BALANCING, TYPE_ASCII_HEX, 3 },//188 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_12_BALANCING, TYPE_ASCII_HEX, 3 },//189 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_13_BALANCING, TYPE_ASCII_HEX, 3 },//190 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_14_BALANCING, TYPE_ASCII_HEX, 3 },//191 { (void*)cell_balance, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_CELL_15_BALANCING, TYPE_ASCII_HEX, 3 },//192 { (void*)battery_current, {0,0,0,0}, DEVID_BPS, 0, DC_BPS_BATTERY_CURRENT, TYPE_ASCII_HEX, 3 },//193 { (void*)battery_current, {0,0,0,0}, 0, 0, DC_BPS_UNKNOWN1, 0, 0 },//194 { (void*)battery_current, {0,0,0,0}, 0, 0, DC_BPS_UNKNOWN2, 0, 0 },//195
/* ------------------------------------------------- DRIVER INTERFACE --------------------------------------------------- */ /* data location, command, device_id, p, designating char, data_type, data_size */ { (void*)di_text_message[0], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_0_6, TYPE_CHAR_POINTER, 7 }, //196 { (void*)di_text_message[1], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_7_13, TYPE_CHAR_POINTER, 7 }, //197 { (void*)di_text_message[2], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_14_20, TYPE_CHAR_POINTER, 7 }, //198 { (void*)di_text_message[3], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_21_27, TYPE_CHAR_POINTER, 7 }, //199 { (void*)di_text_message[4], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_28_34, TYPE_CHAR_POINTER, 7 }, //200 { (void*)di_text_message[5], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_35_41, TYPE_CHAR_POINTER, 7 }, //201 { (void*)di_text_message[6], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_42_48, TYPE_CHAR_POINTER, 7 }, //202 { (void*)di_text_message[7], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_49_55, TYPE_CHAR_POINTER, 7 }, //203 { (void*)di_text_message[8], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_56_62, TYPE_CHAR_POINTER, 7 }, //204
F-30
ECE 477 Final Report Spring 2006
{ (void*)di_text_message[9], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_63_69, TYPE_CHAR_POINTER, 7 }, //205 { (void*)di_text_message[10], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_70_76, TYPE_CHAR_POINTER, 7 }, //206 { (void*)di_text_message[11], {0,0,0,0}, DEVID_DI, 0, DC_DI_TEXT_MESSAGE_77_79, TYPE_CHAR_POINTER, 4 }, //207 /* ------------------------------------------------- TELEMETRY LOCALS --------------------------------------------------- */ /* data location, command, device_id, p, designating char, data_type, data_size */ { (void*)gps_time, {0,0,0,0}, DEVID_TELEM, 0, DC_TELEM_GPS_TIME, TYPE_ASCII_FLOAT, GPS_TIME_LENGTH }, //208 { (void*)gps_latitude, {0,0,0,0}, DEVID_TELEM, 0, DC_TELEM_GPS_LATITUDE, TYPE_ASCII_FLOAT, GPS_LATITUDE_LENGTH }, //209 { (void*)gps_longitude, {0,0,0,0}, DEVID_TELEM, 0, DC_TELEM_GPS_LONGITUDE, TYPE_ASCII_FLOAT, GPS_LONGITUDE_LENGTH }, //210 { (void*)gps_altitude, {0,0,0,0}, DEVID_TELEM, 0, DC_TELEM_GPS_ALTITUDE, TYPE_ASCII_FLOAT, GPS_ALTITUDE_LENGTH }, //211 { (void*)&(accel.x), {0,0,0,0}, DEVID_TELEM, 0, DC_TELEM_X_ACCELERATION, TYPE_INT, 1 }, //212 { (void*)&(accel.y), {0,0,0,0}, DEVID_TELEM, 0, DC_TELEM_Y_ACCELERATION, TYPE_INT, 1 }, //213 { (void*)&(accel.z), {0,0,0,0}, DEVID_TELEM, 0, DC_TELEM_Z_ACCELERATION, TYPE_INT, 1 }, //214 { (void*)¤t_temperature, {0,0,0,0}, DEVID_TELEM, 0, DC_TELEM_TEMPERATURE, TYPE_INT, 1 }, //215 { (void*)&temperature_alert, {0,0,0,0}, DEVID_TELEM, 0, DC_TELEM_TEMPERATURE_ALERT, TYPE_UCHAR, 0 } //216 };
// turn off the watch dog timer//#pragma config WDT = ON#pragma config WDT = ON, WDTPS = 32768//CLRWDT asm instruction clears watchdog//maybe reset_wdt() as well, not sure #endif
/* Compile options: -ml (Large code model) */
#include <stdio.h>
F-31
ECE 477 Final Report Spring 2006
#include <p18cxxx.h>#include <adc.h>#include <spi.h>#include <usart.h>#include <can2510.h>#include <delays.h>#include <stdlib.h>#include <string.h>#include "ECAN.h"#include "main.h"#include "main2.h"
int CANPOLL =0; //used to determine if we are currently polling //the PPT's, if so, then ignore the recieved CAN interrupt
// _ // ( )_ // _ _ _ _ _ __ | ,_)// ( ) ( ) /'_` )( '__)| | // | (_) |( (_| || | | |_ // `\___/'`\__,_)(_) `\__)
#pragma idata my_isection_3#pragma idata my_usection_3
void writecSPI_UART( unsigned char device, unsigned char addr, unsigned char data ){ disable_interrupts();
if(( device == SPI_A0 ) || ( device == SPI_A1 )) { LATAbits.LATA3 = 1; // negates chip select for SPIb LATAbits.LATA5 = 0; // enables chip select for SPIA putcSPI( ((addr&0x0F) << 3) | ((device == SPI_A1)?0x02:0) ); // select channel and addr putcSPI( data ); // write data to SPI LATAbits.LATA5 = 1; // negates chip select for SPIA
} else if(( device == SPI_B0 ) || ( device == SPI_B1 )) { LATAbits.LATA5 = 1; // negates chip select for SPIA LATAbits.LATA3 = 0; // enables chip select for SPIb putcSPI( ((addr&0x0F) << 3) | ((device == SPI_B1)?0x02:0) ); // select channel and addr putcSPI( data ); // write data to SPI LATAbits.LATA3 = 1; // negates chip select for SPIb
F-32
ECE 477 Final Report Spring 2006
}_asm clrwdt_endasm enable_interrupts(); }
char readcSPI_UART( unsigned char device, unsigned char addr ){ char data = 0;
disable_interrupts();
if(( device == SPI_A0 ) || ( device == SPI_A1 )) { LATAbits.LATA3 = 1; // negates chip select for SPIb LATAbits.LATA5 = 0; // enables chip select for SPIA putcSPI( ((addr&0x0F) << 3) | ((device == SPI_A1)?0x82:0x80) ); // select channel and addr data = getcSPI(); // recieve data from SPI LATAbits.LATA5 = 1; // negates chip select for SPIA
} else if(( device == SPI_B0 ) || ( device == SPI_B1 )) { LATAbits.LATA5 = 1; // negates chip select for SPIA LATAbits.LATA3 = 0; // enables chip select for SPIb putcSPI( ((addr&0x0F) << 3) | ((device == SPI_B1)?0x82:0x80) ); // select channel and addr data = getcSPI(); // recieve data from SPI LATAbits.LATA3 = 1; // negates chip select for SPIb }
enable_interrupts();
return data;}
void readsSPI_UART( unsigned char device, unsigned char addr, unsigned char *read_buffer_ptr, unsigned char buff_len ){ disable_interrupts();
if(( device == SPI_A0 ) || ( device == SPI_A1 )) { LATAbits.LATA3 = 1; // negates chip select for SPIb
F-33
ECE 477 Final Report Spring 2006
LATAbits.LATA5 = 0; // enables chip select for SPIA putcSPI( ((addr&0x0F) << 3) | ((device == SPI_A1)?0x82:0x80) ); // select channel and addr getsSPI(read_buffer_ptr, buff_len); // recieve data from SPI LATAbits.LATA5 = 1; // negates chip select for SPIA
} else if(( device == SPI_B0 ) || ( device == SPI_B1 )) { LATAbits.LATA5 = 1; // negates chip select for SPIA LATAbits.LATA3 = 0; // enables chip select for SPIb putcSPI( ((addr&0x0F) << 3) | ((device == SPI_B1)?0x82:0x80) ); // select channel and addr getsSPI(read_buffer_ptr, buff_len); // recieve data from SPI LATAbits.LATA3 = 1; // negates chip select for SPIb }
enable_interrupts();}
#pragma idata section_ipm#pragma udata section_upm
// write_byte_UART is for sending a single byte to UARTvoid write_byte_UART(unsigned char data){ while( BusyUSART() ); //disable_interrupts(); WriteUSART( data ); //enable_interrupts();}
// write_str_UART is for sending an array of bytes up to a max of 10 bytes to UARTvoid write_str_UART(unsigned char length){ unsigned char index = 0;
if(length < UART_ARR_LENGTH) { while(index < length) { write_byte_UART( write_UART[index] ); index++; } }}
F-34
ECE 477 Final Report Spring 2006
// write_array_UART is for sending an array of bytes that is user defined to UARTvoid write_array_UART(unsigned char byte_array[], unsigned char length){ unsigned char index = 0;
while(index < length) { write_byte_UART(byte_array[index]); index++; }}
void write_u16_UART( unsigned int write_me ){ unsigned char itoa_buf[6]; while( BusyUSART() ); putsUSART( itoa(write_me, itoa_buf) );}
void write_u32_UART( unsigned long write_me ){ unsigned char itoa_buf[11]; while( BusyUSART() ); putsUSART( itoa(write_me, itoa_buf) );}
void write_u8_UART( unsigned char write_me ){ unsigned char itoa_buf[3]; itoa_buf[0] = (write_me >> 4) + '0'; if( itoa_buf[0] > '9' ) { itoa_buf[0] = itoa_buf[0] + 7; } itoa_buf[1] = (write_me & 0x0F) + '0'; if( itoa_buf[1] > '9' ) { itoa_buf[1] = itoa_buf[1] + 7;
F-35
ECE 477 Final Report Spring 2006
}
itoa_buf[3] = 0; write_byte_UART( itoa_buf[0] ); write_byte_UART( itoa_buf[1] ); }
#pragma idata section_ispi#pragma udata section_uspi
unsigned char poll_SPI_UART( unsigned char device ){ unsigned char FIFO_buffer[MAX_BPS_BUFFER_LENGTH]; unsigned char FIFO_num_bytes = 0; unsigned char index = 0; unsigned char data_status = BUFFER_EMPTY; // check the status of the FIFO buffer to see if there is any data present switch( device ) { case SPI_GPS :
FIFO_num_bytes = readcSPI_UART( SPI_GPS, SPI_RXLVL ); // if data is present, read the string of chars in from the FIFO if(FIFO_num_bytes > 0) { readsSPI_UART(SPI_GPS, SPI_RHR, FIFO_buffer, FIFO_num_bytes);
// send the data in the FIFO to be parsed for GPS data_status = ParseGPS( FIFO_buffer, FIFO_num_bytes ); } break; case SPI_BPS :
FIFO_num_bytes = readcSPI_UART( SPI_BPS, SPI_RXLVL ); // if data is present, read the string of chars in from the FIFO if(FIFO_num_bytes > 0) { readsSPI_UART(SPI_BPS, SPI_RHR, FIFO_buffer, FIFO_num_bytes);
F-36
ECE 477 Final Report Spring 2006
// send the data in the FIFO to be parsed for BPS data_status = ParseBPS( FIFO_buffer, FIFO_num_bytes ); } break; default: break; }
// return GPS status return data_status;}
void send_MC (unsigned char index){ unsigned char i = 0;
// check for out of bounds on polled_data if( ( index < ALL_DATA_SIZE ) && ( index >= 0 ) ) { for(i = 0; i < MAX_COMMAND_SIZE; i++) { writecSPI_UART(SPI_MC, SPI_THR, polled_data[index].command[i]); } }}
unsigned char recv_MC (unsigned char index){ unsigned char FIFO_buffer[MAX_BPS_BUFFER_LENGTH]; unsigned char FIFO_num_bytes = 0; unsigned char i = 0; unsigned char status = RETURN_INCOMPLETE;
FIFO_num_bytes = readcSPI_UART( SPI_MC, SPI_RXLVL ); // if data is present, read the string of chars in from the FIFO if(FIFO_num_bytes > 0) { readsSPI_UART(SPI_MC, SPI_RHR, FIFO_buffer, FIFO_num_bytes); status = ParseMC(FIFO_buffer, FIFO_num_bytes, index); }
F-37
ECE 477 Final Report Spring 2006
return status;}
unsigned char ParseMC (unsigned char *MC_buffer, unsigned char buff_len, unsigned char index){ unsigned char i = 0; static unsigned char position = 0; unsigned char status = RETURN_INCOMPLETE;
if( ( buff_len >= MIN_BPS_BUFFER_LENGTH ) && ( buff_len <= MAX_BPS_BUFFER_LENGTH ) && ( index < ALL_DATA_SIZE ) && // check for valid polled_data index ( index >= 0 ) ) { for(i = 0; i < buff_len; i++) { if(MC_buffer[i] == LF) { position = 0; status = RETURN_COMPLETE; } else if(MC_buffer[i] == CR) { *((char *)(polled_data[index].data_location + position)) = 0; // put a null termination at the end of the data } else if( position < polled_data[index].data_length ) { *((char *)(polled_data[index].data_location + position)) = MC_buffer[i]; ++position; } } }
return status;}
#pragma idata section_ipm#pragma udata section_upm
unsigned char send_PM(void){ static unsigned char current_item = 0; unsigned char data_length = 0;
F-38
ECE 477 Final Report Spring 2006
unsigned char x = 0; unsigned char return_me = PM_TRANSMIT_INCOMPLETE; unsigned int temp_int; switch( pm_state ) { case PM_STATE_POLLED: if( current_item < POLLED_DATA_SIZE ) { if( current_item == 0 ) { write_byte_UART( PM_START_CHARACTER ); } if( polled_data[current_item].data_length != 0 ) { // determine the size of the response if ( polled_data[current_item].data_type == TYPE_INT ) { data_length = sizeof(int) * polled_data[current_item].data_length; } else { data_length = sizeof(char) * polled_data[current_item].data_length; } write_u8_UART( polled_data[current_item].designating_char ); if ( polled_data[current_item].data_type == TYPE_INT ) { write_u16_UART( *((int *)polled_data[current_item].data_location) ); } else { for( x = 0; x < data_length; ++x ) { if( *((char *)(polled_data[current_item].data_location + x)) != 0 ) { write_byte_UART( *((char *)(polled_data[current_item].data_location + x)) ); } else { break; } }
F-39
ECE 477 Final Report Spring 2006
} write_byte_UART( PM_DELIMITER ); } ++current_item; } else { current_item = 0; pm_state = PM_STATE_TEMP; } break; case PM_STATE_TEMP: write_u8_UART( DC_TELEM_TEMPERATURE ); write_u16_UART( current_temperature ); write_byte_UART( PM_DELIMITER ); if( temperature_alert == 1 ) { pm_state = PM_STATE_TEMP_ALERT; } else { pm_state = PM_STATE_GPS_TIME; }
break; case PM_STATE_TEMP_ALERT: write_u8_UART( DC_TELEM_TEMPERATURE_ALERT ); write_byte_UART( PM_DELIMITER ); pm_state = PM_STATE_GPS_TIME; break; case PM_STATE_GPS_TIME: write_u8_UART( DC_TELEM_GPS_TIME ); if( device_flags & GPS_ERR_STATUS ) { write_u32_UART( unreal_time_clock ); } else
F-40
ECE 477 Final Report Spring 2006
{ while( BusyUSART() ); putsUSART( gps_time ); } write_byte_UART( PM_DELIMITER ); pm_state = PM_STATE_ACCEL_X; break; case PM_STATE_ACCEL_X: write_u8_UART( DC_TELEM_X_ACCELERATION ); write_u16_UART( accel.x ); write_byte_UART( PM_DELIMITER ); pm_state = PM_STATE_ACCEL_Y; break; case PM_STATE_ACCEL_Y: write_u8_UART( DC_TELEM_Y_ACCELERATION ); write_u16_UART( accel.y ); write_byte_UART( PM_DELIMITER ); pm_state = PM_STATE_ACCEL_Z; break; case PM_STATE_ACCEL_Z: write_u8_UART( DC_TELEM_Z_ACCELERATION ); write_u16_UART( accel.z ); write_byte_UART( PM_DELIMITER ); pm_state = PM_STATE_GPS_LAT; break; case PM_STATE_GPS_LAT: write_u8_UART( DC_TELEM_GPS_LATITUDE ); while( BusyUSART() ); putsUSART( gps_latitude ); write_byte_UART( PM_DELIMITER ); pm_state = PM_STATE_GPS_LON; break; case PM_STATE_GPS_LON: write_u8_UART( DC_TELEM_GPS_LONGITUDE ); while( BusyUSART() );
F-41
ECE 477 Final Report Spring 2006
putsUSART( gps_longitude ); write_byte_UART( PM_DELIMITER ); pm_state = PM_STATE_GPS_ALT; break; case PM_STATE_GPS_ALT: write_u8_UART( DC_TELEM_GPS_ALTITUDE ); while( BusyUSART() ); putsUSART( gps_altitude ); write_byte_UART( PM_DELIMITER ); pm_state = PM_STATE_BPS_VOLTAGE; break; case PM_STATE_BPS_VOLTAGE: if( current_item < NUM_BATTERIES ) { write_u8_UART( DC_BPS_CELL_1_VOLTAGE + current_item ); write_byte_UART( cell_voltage[current_item][0] ); write_byte_UART( cell_voltage[current_item][1] ); write_byte_UART( cell_voltage[current_item][2] ); write_byte_UART( PM_DELIMITER ); ++current_item; } else { current_item = 0; pm_state = PM_STATE_BPS_TEMPERATURE; } break; case PM_STATE_BPS_TEMPERATURE: if( current_item < NUM_BATTERIES ) { write_u8_UART( DC_BPS_CELL_1_TEMPERATURE + current_item ); write_byte_UART( cell_temperature[current_item][0] ); write_byte_UART( cell_temperature[current_item][1] ); write_byte_UART( cell_temperature[current_item][2] ); write_byte_UART( PM_DELIMITER ); ++current_item; } else
F-42
ECE 477 Final Report Spring 2006
{ current_item = 0; pm_state = PM_STATE_BPS_BALANCE; } break; case PM_STATE_BPS_BALANCE: write_u8_UART( DC_BPS_CELL_1_BALANCING ); write_byte_UART( cell_balance[0] ); write_byte_UART( cell_balance[1] ); write_byte_UART( cell_balance[2] ); write_byte_UART( cell_balance[3] ); write_byte_UART( PM_DELIMITER ); pm_state = PM_STATE_BPS_CURRENT; break; case PM_STATE_BPS_CURRENT: write_u8_UART( DC_BPS_BATTERY_CURRENT ); write_byte_UART( battery_current[0] ); write_byte_UART( battery_current[1] ); write_byte_UART( battery_current[2] ); write_byte_UART( PM_END_CHARACTER ); pm_state = PM_STATE_POLLED; return_me = PM_TRANSMIT_COMPLETE; break; default: pm_state = PM_STATE_POLLED; current_item = 0; break; } return return_me;}
#pragma idata section_iint#pragma udata section_uint
// _ _ // _ ( )_ ( )_ // (_) ___ | ,_) __ _ __ _ __ _ _ _ _ | ,_) ___ // | |/' _ `\| | /'__`\( '__)( '__)( ) ( )( '_`\ | | /',__)
F-43
ECE 477 Final Report Spring 2006
// | || ( ) || |_ ( ___/| | | | | (_) || (_) )| |_ \__, \// (_)(_) (_)`\__)`\____)(_) (_) `\___/'| ,__/'`\__)(____/// | | // (_)
void disable_interrupts(void){ // disables interrupts INTCONbits.GIEH = 0; INTCONbits.GIEL = 0;}
void enable_interrupts(void){ // enables interrupts INTCONbits.GIEH = 1; INTCONbits.GIEL = 1;}
void high_ISR(void);void low_ISR(void);
#pragma code high_vector = 0x08void high_interrupt (void){ _asm goto high_ISR _endasm}
#pragma code low_vector = 0x18void low_interrupt (void){ _asm goto low_ISR _endasm}
#pragma code#pragma interrupt high_ISR#pragma idata section_imain#pragma idata section_umainvoid high_ISR (void){ static long timer_count_7ms = 0;
F-44
ECE 477 Final Report Spring 2006
static long timer_count_1000ms = 0; char crap; unsigned int id = (RXB0SIDH << 3) | (RXB0SIDL >> 5);
if( PIR1bits.TMR2IF ) { T2CON = 0x00; // close timer PIR1bits.TMR2IF = 0; // clear interrupt ++timer_count_7ms; ++timer_count_1000ms;
// 1 ms tasks // poll bps ++BPS_counter; if(BPS_counter >= COUNTER_TOO_BIG) // BPS is taking too long and probably not working { device_flags = device_flags | BPS_ERR_STATUS; BPS_counter = 0; } else { device_flags = device_flags | POLL_BPS_FLAG; }
if( mc_state == MC_STATE_RECV ) { ++MC_counter; } else { MC_counter = 0; } if( CAN_poll_state == CAN_POLL_STATE_RESPONSE ) { ++CAN_counter; } else { CAN_counter = 0; } if( MC_counter > MC_COUNTER_TOO_BIG )
F-45
ECE 477 Final Report Spring 2006
{ mc_state = MC_STATE_SEND; MC_counter = 0; }
if( timer_count_7ms % 7 == 0 ) { // 7 ms tasks // poll gps ++GPS_counter;
if(GPS_counter >= COUNTER_TOO_BIG) // GPS is taking too long and probably not working { device_flags = device_flags | GPS_ERR_STATUS; GPS_counter = 0; } else { device_flags = device_flags | POLL_GPS_FLAG; }
timer_count_7ms = 0; }
if( timer_count_1000ms % 500 == 0 ) { device_flags = device_flags | POLL_MC_FLAG; } if( timer_count_1000ms % 1000 == 0) { ++unreal_time_clock;
if( device_flags & GPS_ERR_STATUS ) { device_flags = device_flags | POLL_ADC_FLAG; } device_flags = device_flags | SEND_STATUS_FLAG | POLL_CAN_FLAG; }
#ifdef ROTATE_TEXT_MESSAGES // retry any errored ppts after 60s if( timer_count_1000ms % 5000 == 0 ) { device_flags = device_flags | ROTATE_TAGS_FLAG;
F-46
ECE 477 Final Report Spring 2006
} #endif // retry any errored ppts after 60s if( timer_count_1000ms % 60000 == 0 ) { ppt_status_flags = 0x0000; timer_count_1000ms = 0; }
T2CON = 0b01110111; // initialize and open timer .. 15 postscale, 16 prescale } if ((PIR3 & 0x01) || (PIR3 & 0x02)) //CAN Interrupt { PIR3bits.RXB0IF = 0; //clear the interrupt flag if( id == TELEM ) { device_flags = device_flags | SERVICE_CAN_INT; } else { RXB0CONbits.RXFUL = 0; } } if( PIR1 & 0x20 ) // UART Rx { PIR1bits.RCIF = 0; // clear interrupt flag
if( DataRdyUSART() ) { crap = ReadUSART();
if( RCSTAbits.OERR || RCSTAbits.FERR ) { RCSTAbits.CREN = 0; RCSTAbits.CREN = 1; } } } INTCON = 0b11000000; // (bit 7) enable high priority ints (bit 6) enable low priority ints (bit 4) enable INT0 external int INTCON2 = 0b00000000; // (bit 6) rising edge of int0 interrupt (bit 5) rising edge of int1 interrupt
F-47
ECE 477 Final Report Spring 2006
INTCON3 = 0b00000000; // (bit 3) enable int1 interrupt}
#pragma code
#pragma interruptlow low_ISRvoid low_ISR (void){
}
#pragma idata section_iad#pragma udata section_uad
// _ // ( )// _ _ ______ _| |// /'_` )(______)/'_` |// ( (_| | ( (_| |// `\__,_) `\__,_)
void readAccel(void){
OpenADC( ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_16_TAD, ADC_CH0 & ADC_CH1 & ADC_CH2 & ADC_CH5 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 9);
SetChanADC(ADC_CH0); ConvertADC(); while(BusyADC()); accel.z = ReadADC();
SetChanADC(ADC_CH2); ConvertADC(); while(BusyADC());
F-48
ECE 477 Final Report Spring 2006
accel.x = ReadADC();
SetChanADC(ADC_CH1); ConvertADC(); while(BusyADC()); accel.y = ReadADC();
CloseADC();
return;}
void readTemp(void){ // this code does not really apply.. the software was written assuming there was an // opamp circuit to scale the temperature voltage to the A/D range... so we need to // modify this to read 0.1-1.75v as -40 to 125 C //Found exact code in Pic Microcontroller: An Intro to software and hardware interfacing pg.594 OpenADC( ADC_FOSC_64 & ADC_RIGHT_JUST & ADC_16_TAD, ADC_CH0 & ADC_CH1 & ADC_CH2 & ADC_CH5 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS, 9); SetChanADC(ADC_CH5); ConvertADC();
while( BusyADC() ); current_temperature = ReadADC(); CloseADC();
if( current_temperature > TEMPERATURE_TOO_HIGH ) { temperature_alert = 1; } else { temperature_alert = 0;
F-49
ECE 477 Final Report Spring 2006
} return;}
// ___ _ _ ___ // /'___) /'_` )/' _ `\// ( (___ ( (_| || ( ) |// `\____)`\__,_)(_) (_)
#pragma idata my_section_6
/*************************************************************************** Function name: void initial_Can Despription: This function initializes the ECAN module to have a baud rate of 125kbps for a clock frequency of 40MHz and returns upon successful completion. Return value: None*****************************************************************************/ void initialize_CAN(void){ CANCON = 0x80; // enter configuration mode while (CANSTAT != 0x80); // wait until configuration mode is entered ECANCON = 0x00; // mode 0 BRGCON1 = 0x49; // Sync width = 2, Prescale = 9 BRGCON2 = 0xB1; // Phase Seg 1 = 7, Propegation Time = 2 BRGCON3 = 0x05; // Phase Seg 2 = 6 CIOCON = 0x30; // drive high bit... enable can capture // RXF0SIDH = 0xFF; // set to recieve identifier 0x7F8 - 11-bit only // RXF0SIDL = 0xE0; // RXM0SIDH = 0x00; // Set to look at entire identifier // RXM0SIDL = 0x00; RXF0SIDH = 0x02; // set to recieve identifier 0x7F8 - 11-bit only RXF0SIDL = 0x20; RXM0SIDH = 0xFF; // Set to look at entire identifier RXM0SIDL = 0xE0; RXB0SIDH = 0x00; RXB0SIDL = 0x00; RXB0CON = 0x20; RXB1CON = 0x20; RXFCON0 = 0x01; // enable filter 0 RXFBCON0 = 0x00; // filter 0 associated with RXB0 MSEL0 = 0x00; // acceptance mask 0?
F-50
ECE 477 Final Report Spring 2006
CANCON = 0x00; // return to normal mode while ((CANSTAT & 0xE0) == 0x00); // wait until normanl mode is entered}
/* UNUSEDvoid can_test(void){ unsigned long id; BYTE data[4]; BYTE dataLen; ECAN_RX_MSG_FLAGS flags;
while( !ECANSendMessage(0x123, data, 0, ECAN_TX_STD_FRAME) );
do { // Wait for a message to get received. while( !ECANReceiveMessage(&id, data, &dataLen, &flags) ); // Increment received id and echo it back. id++;
while( BusyUSART() ); WriteUSART( 'C' ); while( !ECANSendMessage(id, data, dataLen, flags) );
} while(1);}*/#pragma idata my_section_cannycannycanny
int hatoi(char *hexStg) {
/* stolen from http://bdn.borland.com/article/0,1410,17203,00.html */ unsigned char n = 0; // position in string unsigned char m = 0; // position in digit[] to shift unsigned char count; // loop index int digit[5]; // hold values to convert int intValue = 0; // integer value of hex string while (n < 4) { if (hexStg[n]=='\0') break; if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9 digit[n] = hexStg[n] & 0x0f; //convert to int
F-51
ECE 477 Final Report Spring 2006
else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int else break; n++; } count = n; m = n - 1; n = 0; while(n < count) { // digit[n] is value of hex digit at position n // (m << 2) is the number of positions to shift // OR the bits into return value intValue = intValue + (digit[n] << (m*4)); m--; // adjust the position to set n++; // next digit to process } return (intValue); }
void CANintrequest(void){ unsigned int id = (RXB0SIDH << 3) | (RXB0SIDL >> 5); unsigned char recieved_data[9] = {RXB0D0,RXB0D1,RXB0D2,RXB0D3,RXB0D4,RXB0D5,RXB0D6,RXB0D7,0}; unsigned char dataLen = 0; unsigned char x = 0; unsigned char *cpt = 0; int tmp_int = 0; float tmp_float = 0.0; // is the packet addressed to us? if so, copy it to our buffer // if( id == TELEM ) // { // is the packet a data request? if( recieved_data[0] == DC_COMMAND_REQUEST ) { // check for out of bounds on polled_data if( ( recieved_data[1] < ALL_DATA_SIZE ) && ( recieved_data[1] >= 0 ) ) { // determine the size of the response if ( polled_data[recieved_data[1]].data_type == 0 ) { dataLen = 0;
F-52
ECE 477 Final Report Spring 2006
} else if ( polled_data[recieved_data[1]].data_type == TYPE_INT ) { dataLen = sizeof(int) * polled_data[recieved_data[1]].data_length; } else if ( polled_data[recieved_data[1]].data_type == TYPE_ASCII_FLOAT ) { dataLen = sizeof(float); } else if ( ( polled_data[recieved_data[1]].data_type == TYPE_ASCII_DECIMAL ) || ( polled_data[recieved_data[1]].data_type == TYPE_ASCII_HEX ) ) { dataLen = sizeof(int); } else // uchar and char* both get caught here { dataLen = sizeof(char) * polled_data[recieved_data[1]].data_length; }
// put a cap on the length of a message if( dataLen > 7 ) { dataLen = 7; } // start filling the transmit buffer cpt = &TXB0D0; cpt[0] = recieved_data[1]; // the first byte will be the designating character requested // fill the transmit buffer with the data from memory if ( polled_data[recieved_data[1]].data_type == TYPE_ASCII_DECIMAL ) { tmp_int = atoi( (char *)(polled_data[recieved_data[1]].data_location) ); #ifdef CAN_BIG_ENDIAN for( x = 0; x < dataLen; ++x ) { cpt[dataLen-x] = *( ((char *)&(tmp_int)) +x); } #else for( x = 0; x < dataLen; ++x ) { cpt[x+1] = *( ((char *)&(tmp_int)) +x); } #endif
F-53
ECE 477 Final Report Spring 2006
} else if ( polled_data[recieved_data[1]].data_type == TYPE_ASCII_HEX ) { tmp_int = hatoi( (char *)(polled_data[recieved_data[1]].data_location) );
#ifdef CAN_BIG_ENDIAN for( x = 0; x < dataLen; ++x ) { cpt[dataLen-x] = *( ((char *)&(tmp_int)) +x); } #else for( x = 0; x < dataLen; ++x ) { cpt[x+1] = *( ((char *)&(tmp_int)) +x); } #endif } else if ( polled_data[recieved_data[1]].data_type == TYPE_ASCII_FLOAT ) { tmp_float = atof( (char *)(polled_data[recieved_data[1]].data_location) ); #ifdef CAN_BIG_ENDIAN for( x = 0; x < dataLen; ++x ) { cpt[dataLen-x] = *( ((char *)&(tmp_float)) +x); } #else for( x = 0; x < dataLen; ++x ) { cpt[x+1] = *( ((char *)&(tmp_float)) +x); } #endif } else /* direct memory copy */ { #ifdef CAN_BIG_ENDIAN for( x = 0; x < dataLen; ++x ) { cpt[dataLen-x] = *((char *)(polled_data[recieved_data[1]].data_location + x)); } #else for( x = 0; x < dataLen; ++x ) { cpt[x+1] = *((char *)(polled_data[recieved_data[1]].data_location + x)); }
F-54
ECE 477 Final Report Spring 2006
#endif } TXB0SIDH = 0b00000010; //send back to driver CAN ID TXB0SIDL = 0b00000000; TXB0DLC = dataLen+1; TXB0CON = 0x08; //initiate transmission } } else if ( CAN_poll_state == CAN_POLL_STATE_RESPONSE ) // the packet is a response from a CAN poll { // check for out of bounds on polled_data if( ( recieved_data[0] < ALL_DATA_SIZE ) && ( recieved_data[0] >= 0 ) ) { // determine the size of the response if ( polled_data[recieved_data[0]].data_type == 0 ) { dataLen = 0; } else if ( polled_data[recieved_data[0]].data_type == TYPE_INT ) { dataLen = sizeof(int) * polled_data[recieved_data[0]].data_length; } else if ( polled_data[recieved_data[0]].data_type == TYPE_ASCII_FLOAT ) { dataLen = sizeof(float); } else if ( ( polled_data[recieved_data[0]].data_type == TYPE_ASCII_DECIMAL ) || ( polled_data[recieved_data[0]].data_type == TYPE_ASCII_HEX ) ) { dataLen = sizeof(int); } else // uchar and char* both get caught here { dataLen = sizeof(char) * polled_data[recieved_data[0]].data_length; } // put a cap on the length of a message if( dataLen > 7 ) { dataLen = 7; }
F-55
ECE 477 Final Report Spring 2006
// update our memory with the new data for( x = 0; x < dataLen; ++x ) { #ifdef CAN_BIG_ENDIAN *((char *)(polled_data[recieved_data[0]].data_location + x)) = recieved_data[dataLen-x]; #else *((char *)(polled_data[recieved_data[0]].data_location + x)) = recieved_data[x+1]; #endif } } // update can poll's state CAN_poll_state = CAN_POLL_STATE_NEXT; } //clear RXFUL flag, since we are done with the recieved data RXB0CONbits.RXFUL = 0; //} /*else // data not for us { //clear RXFUL flag RXB0CONbits.RXFUL = 0; }*/}
unsigned char CANpollPPT(unsigned char pptID){ static unsigned char *cpt; static unsigned int dchar_offset; // designating character offset unsigned char return_me = CAN_POLL_INCOMPLETE; switch( CAN_poll_state ) { case CAN_POLL_STATE_IDLE: // initialize dchar_offset = 0; CAN_poll_state = CAN_POLL_STATE_REQUEST; break; case CAN_POLL_STATE_REQUEST: CANPOLL = 1; // start filling the transmit buffer
F-56
ECE 477 Final Report Spring 2006
cpt = &TXB0D0; cpt[0] = DC_COMMAND_REQUEST; // first character is a request cpt[1] = (pptID * 8) + dchar_offset; // fill the transmit ID buffers with the CAN ID to send to TXB0SIDH = ( pptID >> 3 ) & 0x00FF; TXB0SIDL = ( pptID << 5 ) & 0b11100000; // requests are 2 bytes TXB0DLC = 2; TXB0CON = 0x08; //initiate transmission CAN_poll_state = CAN_POLL_STATE_RESPONSE; break; case CAN_POLL_STATE_RESPONSE: // sit here until we get a recieve interrupt // the recieve interrupt will update our state to CAN_POLL_STATE_NEXT if( CAN_counter > 100 ) { ppt_status_flags = ppt_status_flags | ( 1 << pptID ); CAN_poll_state = CAN_POLL_STATE_IDLE; CAN_counter = 0; return_me = CAN_POLL_COMPLETED; } break; case CAN_POLL_STATE_NEXT: dchar_offset = dchar_offset + 1; // determine if the designating character offset is greater than the // number of designating characters PPTs respond to if( dchar_offset > DC_PPT0_RESERVED ) { CAN_poll_state = CAN_POLL_STATE_COMPLETE; } else { CAN_poll_state = CAN_POLL_STATE_REQUEST; }
F-57
ECE 477 Final Report Spring 2006
break; case CAN_POLL_STATE_COMPLETE: CAN_poll_state = CAN_POLL_STATE_IDLE; return_me = CAN_POLL_COMPLETED; break; default: CAN_poll_state = CAN_POLL_STATE_IDLE; break; } return return_me;}// _ // _ _ ( )_ // (_) ___ (_)| ,_)// | |/' _ `\| || | // | || ( ) || || |_ // (_)(_) (_)(_)`\__)
#pragma idata my_section_7
#define PIC_BAUD_9600 255#define PIC_BAUD_115200 21
#define SPI_BAUD_9600 12#define SPI_BAUD_115200 1
void init (void){ /****************************************/ // Setup interrupt registers. // This enables interrupts on the UART, // 2 of the interrupt input pins // and CAN recieve and send buffers /****************************************/
unsigned int delay_counter = 0;
F-58
ECE 477 Final Report Spring 2006
// 76543210 INTCON = 0b00000000; // (bit 7) enable high priority ints (bit 6) enable low priority ints (bit 4) enable INT0 external int INTCON2 = 0b00000000; // (bit 6) rising edge of int0 interrupt (bit 5) rising edge of int1 interrupt INTCON3 = 0b00000000; // (bit 3) enable int1 interrupt RCON = 0b10000000; // (bit 7, IPEN) enable priority based interrupts T2CON = 0b01110111; // initialize and open timer .. 15 postscale, 16 prescale PIR1 = 0b00000000; // clear int flags PIR2 = 0b00000000; // clear int flags PIR3 = 0b00000000; // clear int flags PIE1 = 0b00100010; // interrupt on UART Rx (bit 5), UART Tx (bit 4), timer 2 interrupt (bit 1) PIE2 = 0b00000000; PIE3 = 0b00000011; // enable interrupts on CAN recieve buffers 0 and 1 IPR1 = 0b11111111; // every interrupt is low priorty, except timer (bit 1) IPR2 = 0b11111111; // every interrupt is low priorty, except (bit 5) UART Rx IPR3 = 0b11111111; // every interrupt is low priorty TRISC = 0b10010000; // UART Rx is input (bit 7) SDI is input (bit 4)
TRISAbits.TRISA5 = 0; // set RA5 to be output for chip select on SPIA TRISAbits.TRISA3 = 0; // set RA3 to be output for chip select on SPIB TRISBbits.TRISB0 = 1; // set RB0 to be input TRISBbits.TRISB1 = 1; // set RB1 to be input PR2 = 41; // 1.008 ms (or 0.981 ms)
LATCbits.LATC0 = 0; // reset SPIs
/**********************************************/ // Setting intial stuff //OpenSPI(SPI_FOSC_4, MODE_00, SMPEND); /**********************************************/
OpenUSART( USART_TX_INT_OFF & USART_RX_INT_ON & USART_EIGHT_BIT & USART_ASYNCH_MODE & USART_BRGH_HIGH & USART_CONT_RX, PIC_BAUD_115200);
// need to set an3 and ra5 to be digital i/o for chip selects for spi OpenSPI( SPI_FOSC_64, MODE_00, SMPMID ); LATCbits.LATC0 = 1; // sets SPIA out of reset
F-59
ECE 477 Final Report Spring 2006
for( delay_counter = 0; delay_counter < 30000; ++delay_counter ); // delay after spi-uart pulled out of reset
//writecSPI_UART( SPI_A0, SPI_IODir, 0xFF ); // make all I/O pins outputs writecSPI_UART( SPI_A0, SPI_LCR, 0b10000011 ); // enable baud rate setting for A0 writecSPI_UART( SPI_A1, SPI_LCR, 0b10000011 ); // enable baud rate setting for A0 writecSPI_UART( SPI_A0, SPI_DLL, SPI_BAUD_9600 ); // set A0 low divisor to 12 (for 9600 baud for MC) writecSPI_UART( SPI_A1, SPI_DLL, SPI_BAUD_9600 ); // set A1 low divisor to 12 (for 9600 baud for GPS) writecSPI_UART( SPI_A0, SPI_DLH, 0 ); // set A0 high divisor to 0 (for 9600 baud) writecSPI_UART( SPI_A1, SPI_DLH, 0 ); // set A1 high divisor to 0 (for 9600 baud) writecSPI_UART( SPI_A0, SPI_LCR, 0b00000011 ); // disable baud rate setting for A0 writecSPI_UART( SPI_A1, SPI_LCR, 0b00000011 ); // disable baud rate setting for A0 writecSPI_UART( SPI_A0, SPI_FCR, 0b00000111 ); // enable FIFO writecSPI_UART( SPI_A1, SPI_FCR, 0b00000111 ); // enable FIFO writecSPI_UART( SPI_A0, SPI_IER, 0b00000001 ); // enable Rx interrupt writecSPI_UART( SPI_A1, SPI_IER, 0b00000001 ); // enable Rx interrupt
//writecSPI_UART( SPI_B0, SPI_IODir, 0xFF ); // make all I/O pins outputs writecSPI_UART( SPI_B0, SPI_LCR, 0b10000011 ); // enable baud rate setting for B0 writecSPI_UART( SPI_B1, SPI_LCR, 0b10000011 ); // enable baud rate setting for B0 writecSPI_UART( SPI_B0, SPI_DLL, SPI_BAUD_115200 ); // set B0 low divisor to 1 (for 115,200 baud) writecSPI_UART( SPI_B1, SPI_DLL, SPI_BAUD_115200 ); // set B1 low divisor to 1 (for 115,200 baud for BPS) writecSPI_UART( SPI_B0, SPI_DLH, 0 ); // set B0 high divisor to 0 (for 9600 baud) writecSPI_UART( SPI_B1, SPI_DLH, 0 ); // set B1 high divisor to 0 (for 9600 baud) writecSPI_UART( SPI_B0, SPI_LCR, 0b00000011 ); // enable baud rate setting for B0 writecSPI_UART( SPI_B1, SPI_LCR, 0b00000011 ); // enable baud rate setting for B0 writecSPI_UART( SPI_B0, SPI_FCR, 0b00000111 ); // enable FIFO writecSPI_UART( SPI_B1, SPI_FCR, 0b00000111 ); // enable FIFO writecSPI_UART( SPI_B0, SPI_IER, 0b00000001 ); // enable Rx interrupt writecSPI_UART( SPI_B1, SPI_IER, 0b00000001 ); // enable Rx interrupt _asm clrwdt_endasm } // _ _ _ _ _ __ ___ __ // ( '_`\ /'_` )( '__)/',__) /'__`\// | (_) )( (_| || | \__, \( ___/// | ,__/'`\__,_)(_) (____/`\____)// | | // (_)
/* -----------------------------------------------------------------------------
F-60
ECE 477 Final Report Spring 2006
Function: ParseGPS()
Inputs: (char*) gps_buffer - a char pointer to the partial gps string to be parsed (int) length - the size of the gps_buffer, can range from 1 to 64 chars
Outputs: Returns GPS_PARSING_COMPLETE when the end of a sentence has been reached, and the data from that sentence is contained in the globals: (char[]) gps_latitude - the latitide string in ddmm.mmmm format (char[]) gps_longitude - the longitude string in dddmm.mmmm format (char[]) gps_altitude - the altitude string in mm.m format (char[]) gps_time - the UTC time string in hhmmss.sss format (char) gps_ew - whether longitude is E or W (char) gps_ns - whether latitude is N or S (char) gps_alt_unit - units on altitude string (M is meters)
Otherwise, returns GPS_PARSING_INCOMPLETE if a complete sentence has not been found yet, and GPS_PARSE_ERROR on non syntax related errors. On sentence syntax errors, all characters are ignored until the start of a new sentence ('$')---------------------------------------------------------------------------- */#pragma idata my_section_8
unsigned char ParseGPS( unsigned char* gps_buffer, unsigned char length ){ unsigned char x = 0; unsigned char return_me = GPS_PARSING_INCOMPLETE; static unsigned char gps_state = GPSS_START; static unsigned char gps_latitude_position = 0; static unsigned char gps_longitude_position = 0; static unsigned char gps_altitude_position = 0; static unsigned char gps_time_position = 0;
if(( length >= MIN_GPS_BUFFER_LENGTH ) && ( length <= MAX_GPS_BUFFER_LENGTH ) ) { device_flags = device_flags & ~GPS_ERR_STATUS;
for( x = 0; x < length; ++x ) { // check for the beginning of a new sentence at any time if( gps_buffer[x] == '$' ) { gps_latitude_position = 0; gps_longitude_position = 0;
F-61
ECE 477 Final Report Spring 2006
gps_altitude_position = 0; gps_time_position = 0; gps_state = GPSS_START; } /* Ignore null terminations.. probably undesirable if( gps_buffer[x] == 0 ) { break; } */
switch( gps_state ) { case GPSS_START: if( gps_buffer[x] == '$' ) { gps_state = GPSS_SENTENCE_ID; } break;
// ------------------------ // SENTENCE ID // determine whether the sentence is GPGGA or GPGLL // ------------------------
case GPSS_SENTENCE_ID: if( gps_buffer[x] == 'G' ) { gps_state = GPSS_SENTENCE_ID_G; } else { gps_state = GPSS_START; } break;
case GPSS_SENTENCE_ID_G: if( gps_buffer[x] == 'P' ) { gps_state = GPSS_SENTENCE_ID_GP; } else { gps_state = GPSS_START; } break;
case GPSS_SENTENCE_ID_GP: if( gps_buffer[x] == 'G' ) { gps_state = GPSS_SENTENCE_ID_GPG; } else { gps_state = GPSS_START; } break;
case GPSS_SENTENCE_ID_GPG: if( gps_buffer[x] == 'G' ) { gps_state = GPSS_SENTENCE_ID_GPGG; } else if( gps_buffer[x] == 'L' ) { gps_state = GPSS_SENTENCE_ID_GPGL; } else { gps_state = GPSS_START; } break;
case GPSS_SENTENCE_ID_GPGG:
F-62
ECE 477 Final Report Spring 2006
if( gps_buffer[x] == 'A' ) { gps_state = GPSS_SENTENCE_ID_GPGGA; } else { gps_state = GPSS_START; } break;
/* case GPSS_SENTENCE_ID_GPGL: if( gps_buffer[x] == 'L' ) { gps_state = GPSS_SENTENCE_ID_GPGLL; } else { gps_state = GPSS_START; } break; */
case GPSS_SENTENCE_ID_GPGGA: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGGA_TIME; } else { gps_state = GPSS_START; } break;
/* case GPSS_SENTENCE_ID_GPGLL: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGLL_LAT; } else { gps_state = GPSS_START; } break; */
// ------------------------ // PARSE GPGGA // ------------------------
case GPSS_GPGGA_TIME: if(( gps_buffer[x] == ',' ) || ( gps_time_position > GPS_TIME_LENGTH )) { gps_state = GPSS_GPGGA_LAT; gps_time_position = 0; } else { gps_time[ gps_time_position ] = gps_buffer[x]; ++gps_time_position; } break;
case GPSS_GPGGA_LAT: if(( gps_buffer[x] == ',' ) || ( gps_latitude_position > GPS_LATITUDE_LENGTH )) { gps_state = GPSS_GPGGA_NS; gps_latitude_position = 0;
F-63
ECE 477 Final Report Spring 2006
} else { gps_latitude[ gps_latitude_position ] = gps_buffer[x]; ++gps_latitude_position; } break;
case GPSS_GPGGA_NS: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGGA_LONG; } else { gps_ns = gps_buffer[x]; } break;
case GPSS_GPGGA_LONG: if(( gps_buffer[x] == ',' ) || ( gps_longitude_position > GPS_LONGITUDE_LENGTH )) { gps_state = GPSS_GPGGA_EW; gps_longitude_position = 0; } else { gps_longitude[ gps_longitude_position ] = gps_buffer[x]; ++gps_longitude_position; } break;
case GPSS_GPGGA_EW: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGGA_POS_FIX; } else { gps_ew = gps_buffer[x]; } break;
case GPSS_GPGGA_POS_FIX: if( gps_buffer[x] == ',' )
F-64
ECE 477 Final Report Spring 2006
{ gps_state = GPSS_GPGGA_SATS; } break;
case GPSS_GPGGA_SATS: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGGA_HDOP; } break;
case GPSS_GPGGA_HDOP: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGGA_ALT; } break;
case GPSS_GPGGA_ALT: if(( gps_buffer[x] == ',' ) || ( gps_altitude_position > GPS_ALTITUDE_LENGTH )) { gps_state = GPSS_GPGGA_ALT_UNIT; gps_altitude_position = 0; } else { gps_altitude[ gps_altitude_position ] = gps_buffer[x]; ++gps_altitude_position; } break;
case GPSS_GPGGA_ALT_UNIT: if( gps_buffer[x] == ',' ) { gps_state = GPSS_START; // use GPSS_GPGGA_GEOID if any additional data is needed, see below return_me = GPS_PARSING_COMPLETE; } else { gps_alt_unit = gps_buffer[x]; } break;
/* These states are here for completeness. If any of this data was
F-65
ECE 477 Final Report Spring 2006
needed, uncomment these states and insert the correct code. But since our needs end at altitude unit, we stop parsing there.
case GPSS_GPGGA_GEOID: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGGA_GEOID_UNIT; } break;
case GPSS_GPGGA_GEOID_UNIT: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGGA_AGE; } break;
case GPSS_GPGGA_AGE: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGGA_STATION_ID; } break;
case GPSS_GPGGA_STATION_ID: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGGA_CHECKSUM; } break;
case GPSS_GPGGA_CHECKSUM: if( gps_buffer[x] == LF ) { gps_state = GPSS_START; } break; */
// ------------------------ // PARSE GPGLL // ------------------------
/* This sentence is extraneous case GPSS_GPGLL_LAT:
F-66
ECE 477 Final Report Spring 2006
if(( gps_buffer[x] == ',' ) || ( gps_latitude_position > GPS_LATITUDE_LENGTH )) { gps_state = GPSS_GPGLL_NS; gps_latitude_position = 0; } else { gps_latitude[ gps_latitude_position ] = gps_buffer[x]; ++gps_latitude_position; } break;
case GPSS_GPGLL_NS: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGLL_LONG; } else { gps_ns = gps_buffer[x]; } break;
case GPSS_GPGLL_LONG: if(( gps_buffer[x] == ',' ) || ( gps_longitude_position > GPS_LONGITUDE_LENGTH )) { gps_state = GPSS_GPGLL_EW; gps_longitude_position = 0; } else { gps_longitude[ gps_longitude_position ] = gps_buffer[x]; ++gps_longitude_position; } break;
case GPSS_GPGLL_EW: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGLL_TIME; } else { gps_ew = gps_buffer[x]; }
F-67
ECE 477 Final Report Spring 2006
break;
case GPSS_GPGLL_TIME: if(( gps_buffer[x] == ',' ) || ( gps_time_position > GPS_TIME_LENGTH )) { gps_state = GPSS_START; // use GPSS_GPGLL_POS_FIX if any additional data is needed, see below return_me = GPS_PARSING_COMPLETE; gps_time_position = 0; } else { gps_time[ gps_time_position ] = gps_buffer[x]; ++gps_time_position; } break; */
/* These states are here for completeness. If any of this data was needed, uncomment these states and insert the correct code. But since our needs end at altitude unit, we stop parsing there.
case GPSS_GPGLL_POS_FIX: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGLL_SATS; } break;
case GPSS_GPGLL_SATS: if( gps_buffer[x] == ',' ) { gps_state = GPSS_GPGLL_HDOP; } break; */
default: // invalid state gps_latitude_position = 0; gps_longitude_position = 0; gps_altitude_position = 0; gps_time_position = 0; gps_state = GPSS_START; return_me = GPS_PARSE_ERROR; break; }
F-68
ECE 477 Final Report Spring 2006
} } else // length out of bounds { return GPS_PARSE_ERROR; } return return_me;}
/* -------------------------------------------------------------------------------Function: parseBPS()
Inputs: (char*) BPS_buffer - a char pointer to the partial gps string to be parsed (int) buff_len - the size of the gps_buffer, can range from 1 to 64 chars
Outputs: returns a status based on whether the parse is completed or not---------------------------------------------------------------------------------- */unsigned char ParseBPS( unsigned char *BPS_buffer, unsigned char buff_len){ unsigned char index = 0; unsigned char status_return = BPS_PARSING_INCOMPLETE; static unsigned char BPS_state = BPSS_START; static unsigned char battery_num = 0; static unsigned char data_field = 0;
if( (buff_len >= MIN_BPS_BUFFER_LENGTH) && (buff_len <= MAX_BPS_BUFFER_LENGTH)) { device_flags = device_flags & ~BPS_ERR_STATUS;
for(index = 0; index < buff_len; index++) { if(BPS_buffer[index] == BPS_START_CHAR) { battery_num = 0; data_field = 0; BPS_state = BPSS_START; }
switch(BPS_state) { case BPSS_START : if(BPS_buffer[index] == BPS_START_CHAR) {
F-69
ECE 477 Final Report Spring 2006
BPS_state = BPSS_CELL_VOLTAGE; } break;
case BPSS_CELL_VOLTAGE : if(BPS_buffer[index] == TAB) { if(battery_num == (NUM_BATTERIES - 1)) { battery_num = 0; BPS_state = BPSS_CELL_TEMP; } else { ++battery_num; } } else { cell_voltage[battery_num][data_field] = BPS_buffer[index]; if(data_field == 2) { data_field = 0; } else { ++data_field; } } break;
case BPSS_CELL_TEMP : if(BPS_buffer[index] == TAB) { if(battery_num == (NUM_BATTERIES - 1)) { battery_num = 0; BPS_state = BPSS_CELL_BALANCE; } else { ++battery_num; } } else
F-70
ECE 477 Final Report Spring 2006
{ cell_temperature[battery_num][data_field] = BPS_buffer[index]; if(data_field == 2) { data_field = 0; } else { ++data_field; } } break;
case BPSS_CELL_BALANCE : if(BPS_buffer[index] == TAB) { BPS_state = BPSS_BATTERY_CURRENT; } else { cell_balance[data_field] = BPS_buffer[index]; if(data_field == 3) { data_field = 0; } else { ++data_field; } } break;
case BPSS_BATTERY_CURRENT : if(BPS_buffer[index] == CR) { BPS_state = BPSS_START; status_return = BPS_PARSING_COMPLETE; } else { battery_current[data_field] = BPS_buffer[index]; if(data_field == 2) { data_field = 0; }
F-71
ECE 477 Final Report Spring 2006
else { ++data_field; } } break;
default : BPS_state = BPSS_CELL_VOLTAGE; status_return = BPS_PARSE_ERROR; } } } else { return BPS_PARSE_ERROR; }
return status_return;} // _ // ___ ___ _ _ (_) ___ // /' _ ` _ `\ /'_` )| |/' _ `\// | ( ) ( ) |( (_| || || ( ) |// (_) (_) (_)`\__,_)(_)(_) (_)
#pragma idata section_imain#pragma idata section_umain
void main (void){ unsigned char i = 0; unsigned char j = 0; unsigned char dc = 0; unsigned char FIFO_buffer[MAX_GPS_BUFFER_LENGTH]; unsigned char FIFO_num_bytes = 0; unsigned char result = BUFFER_EMPTY; unsigned int delay_counter = 0; unsigned char current_ppt = 0; unsigned char gps_state = GPS_STATE_MEASURE_ADC; unsigned char current_tag = TAG_BXR; init(); initialize_CAN();
F-72
ECE 477 Final Report Spring 2006
enable_interrupts(); T2CON = 0b01110111; // initialize and open timer .. 15 postscale, 16 prescale
dc = DC_MC_RPM; // initialize motor controller "loop" var_asm clrwdt_endasm while( HASSELHOFF_IS_COOL ) {
// did we get a can interrupt? if( device_flags & SERVICE_CAN_INT ) { CANintrequest();
device_flags = device_flags & ~SERVICE_CAN_INT; } _asm clrwdt_endasm // BATTERY if( device_flags & POLL_BPS_FLAG ) { if( poll_SPI_UART(SPI_BPS) == BPS_PARSING_COMPLETE ) { //write_byte_UART( 'b' ); device_flags = device_flags & ~POLL_BPS_FLAG; BPS_counter = 0; } } // did we get a can interrupt? if( device_flags & SERVICE_CAN_INT ) { CANintrequest();
device_flags = device_flags & ~SERVICE_CAN_INT; }_asm clrwdt_endasm // GLOBAL PANCAKE SYSTEM if(device_flags & POLL_GPS_FLAG) {
F-73
ECE 477 Final Report Spring 2006
if( gps_state == GPS_STATE_MEASURE_ADC ) { device_flags = device_flags | POLL_ADC_FLAG; gps_state = GPS_STATE_INCOMPLETE; } if( poll_SPI_UART(SPI_GPS) == GPS_PARSING_COMPLETE ) { //write_byte_UART( 'g' ); device_flags = device_flags & ~POLL_GPS_FLAG; GPS_counter = 0; gps_state = GPS_STATE_MEASURE_ADC; } } // did we get a can interrupt? if( device_flags & SERVICE_CAN_INT ) { CANintrequest();
device_flags = device_flags & ~SERVICE_CAN_INT; }_asm clrwdt_endasm // MO-TOR COMPUTER if(device_flags & POLL_MC_FLAG) { if( mc_state == MC_STATE_SEND ) { send_MC( dc ); mc_state = MC_STATE_RECV; } else if( mc_state == MC_STATE_RECV ) { if( recv_MC( dc ) == RETURN_COMPLETE ) { //write_byte_UART( 'm' ); MC_counter = 0; mc_state = MC_STATE_SEND; dc++; if( dc > DC_MC_FORWARD_INPUT_STATE ) { dc = DC_MC_RPM;
F-74
ECE 477 Final Report Spring 2006
device_flags = device_flags & ~POLL_MC_FLAG; } } } } // did we get a can interrupt? if( device_flags & SERVICE_CAN_INT ) { CANintrequest();
device_flags = device_flags & ~SERVICE_CAN_INT; } _asm clrwdt_endasm // CANALOPE? if( device_flags & POLL_CAN_FLAG ) { if( ppt_status_flags & ( 1 << current_ppt ) ) { // skip this PPT since it is not connected ++current_ppt; if( current_ppt >= NUM_PPTS ) { current_ppt = 0; device_flags = device_flags & ~POLL_CAN_FLAG; } } else { if( CANpollPPT( current_ppt ) == CAN_POLL_COMPLETED ) { //write_byte_UART( 'c' ); ++current_ppt; if( current_ppt >= NUM_PPTS ) { current_ppt = 0; device_flags = device_flags & ~POLL_CAN_FLAG; } } } } // did we get a can interrupt?
F-75
ECE 477 Final Report Spring 2006
if( device_flags & SERVICE_CAN_INT ) { CANintrequest(); device_flags = device_flags & ~SERVICE_CAN_INT; } _asm clrwdt_endasm // MANALOG CIRCUITS if(device_flags & POLL_ADC_FLAG) { //write_byte_UART( 'a' ); readAccel(); readTemp(); device_flags = device_flags & ~POLL_ADC_FLAG; } // did we get a can interrupt? if( device_flags & SERVICE_CAN_INT ) { CANintrequest(); device_flags = device_flags & ~SERVICE_CAN_INT; } _asm clrwdt_endasm // PACKET MODEM --- this needs to change and accomodate for a value // ---------------- halfway updating while I want to transmit it if( device_flags & SEND_STATUS_FLAG ) { if( send_PM() == PM_TRANSMIT_COMPLETE ) { device_flags = device_flags & ~SEND_STATUS_FLAG; } } #ifdef ROTATE_TEXT_MESSAGES if( device_flags & ROTATE_TAGS_FLAG ) { if( current_tag == TAG_ECE ) { for( i = 0; i < 7; ++i ) { for( j = 0; j < 12; ++j ) {
F-76
ECE 477 Final Report Spring 2006
di_text_message[j][i] = ece_tag[j][i]; } } current_tag = TAG_SD; device_flags = device_flags & ~ROTATE_TAGS_FLAG; } else if( current_tag == TAG_SD ) { for( i = 0; i < 7; ++i ) { for( j = 0; j < 12; ++j ) { di_text_message[j][i] = sd_tag[j][i]; } } current_tag = TAG_HG; device_flags = device_flags & ~ROTATE_TAGS_FLAG; } else if( current_tag == TAG_HG ) { for( i = 0; i < 7; ++i ) { for( j = 0; j < 12; ++j ) { di_text_message[j][i] = hg_tag[j][i]; } } current_tag = TAG_BXR; device_flags = device_flags & ~ROTATE_TAGS_FLAG; } else if( current_tag == TAG_BXR ) { for( i = 0; i < 7; ++i ) { for( j = 0; j < 12; ++j ) { di_text_message[j][i] = bxr_tag[j][i]; } } current_tag = TAG_ECE; device_flags = device_flags & ~ROTATE_TAGS_FLAG;
F-77
ECE 477 Final Report Spring 2006
} } #endif } // infinite loop}
F-78
ECE 477 Final Report Spring 2006
Appendix G: FMECA Worksheet
Failure No.
Failure Mode Possible Causes Failure Effects Method of Detection
Criticality Remarks
A1 VDD5v = 0v Switching regulator circuit component failures, internal or external shorts, under voltage or disconnect on voltage supply line
Telemetry System cannot operate. Possibility of overheating and fire if the cause is a short.
Observation High Risk of fire and damage can be mitigated with a fuse
A2 0v < VDD5v < 4.2v Switching regulator circuit component failures, internal or external shorts, under voltage on supply line
Microcontroller has an under-spec voltage supply for the operating frequency. The Telemetry System may not operate.
Observation Low
A3 4.2v < VDD5v < 4.5v
Switching regulator circuit component failures, internal or external shorts, under voltage on supply line
RS232 Transceiver and CAN Transceiver under voltage spec and may not operate, Accelerometer out of calibrated range.
Observation Low
G-1
ECE 477 Final Report Spring 2006
A4 VDD5v > 5.5v Switching regulator circuit component failures (except bypass caps), internal or external shorts, over-voltage on supply line
All 5 volt components are over voltage spec, possible failure to operate, hardware damage, excess heating or fire.
Observation High Risk of fire and damage can be mitigated with a fuse
B1 VDD3.3v = 0v Linear regulator failure, internal or external shorts, under voltage or disconnect on VDD5v
SPI-to-UART chips cannot operate, Telemetry system will be unable to communicate with the Battery, Motor, and GPS. Possibility of overheating and fire if the cause is a short.
Observation High Risk of fire and damage can be mitigated with a fuse
B2 0v < VDD3.3v < 3.0v Linear regulator circuit failures, internal or external shorts, under voltage on VDD5v
SPI-to-UART chips are under voltage spec, Telemetry system may be unable to communicate with the Battery, Motor, and GPS.
Observation Low
B3 VDD3.3v > 3.6v Linear regulator circuit failures (except bypass caps), internal or external shorts, over-voltage on VDD5v
SPI-to-UART chips are over voltage, Telemetry system may be unable to communicate with the Battery, Motor, and GPS, as well as possible hardware damage, excess heating or fire.
Observation High Risk of fire and damage can be mitigated with a fuse
C1 No data received by chase car (PIC UART transmit error)
Packet modem out of range or unoperational, UART module of microcontroller unable to transmit, RS232 transceiver circuit failure (block C), power circuit failure (block A), software bug
The Telemetry System cannot report data to the chase car.
Observation Low
C2 Failure to enter Packet modem out of range or Diagnostic mode is Observation Low
G-2
ECE 477 Final Report Spring 2006
diagnostic mode (PIC UART receive error)
unoperational, UART module of microcontroller unable to receive, RS232 transceiver circuit failure (block C), power circuit failure (block A), software bug
unavailable, but the major part of the Telemetry System is functional.
D1 Invalid or missing data from Battery
SPI-to-UART circuit failure (block D), SPI-to-UART chip select stuck high or low, RS232 transceiver circuit failure (block C), SPI module of microcontroller failure, cable disconnect, power circuit failure (block A), software bug
Driver unable to read and manage battery levels. Possible battery over-charge.
Communication tested during self-test
Low The Battery Protection System has an automated over-charge protection circuit, which should prevent damage.
D2 Invalid or missing data from Motor
SPI-to-UART circuit failure (block D), SPI-to-UART chip select stuck high or low, RS232 transceiver circuit failure (block C), SPI module of microcontroller failure, cable disconnect, power circuit failure (block A), software bug
Unable to log motor data for performance analysis.
Communication tested during self-test
Low
D3 Invalid or missing data from GPS
SPI-to-UART circuit failure (block D), SPI-to-UART chip select stuck high or low, RS232 transceiver circuit failure (block C), SPI module of microcontroller failure, cable disconnect, power circuit failure (block A), software bug
Unable to log GPS data for aerodynamic analysis.
Communication tested during self-test
Low
G-3
ECE 477 Final Report Spring 2006
E1 Invalid or missing data from Accelerometers
Accelerometer failure, A/D module of microcontroller failure, improper alignment of telemetry system, power circuit failure (block A), software bug.
Unable to log acceleration data for aerodynamic analysis.
Operation and validity tested during self-test
Low
E2 Invalid or missing data from Temperature Sensor
Temperature sensor failure, A/D module of microcontroller failure, power circuit failure (block A), software bug.
Unable to log internal car temperature for analysis.
Operation and validity tested during self-test
Low
F1 Microcontroller does not operate
Bypass capacitor failure, crystal circuit failure, microcontroller failure, power circuit failure (block A), software bug
The Telemetry System cannot report data to the chase car.
Observation Low All other microcontroller failure modes are caught in other blocks.
G1 CAN module cannot transmit
CAN transceiver circuit failure (block G), CAN module failure on microcontroller, power circuit failure (block A), cable disconnect, software bug.
Driver interface unable to update. Driver unable to read and manage battery levels. Possible battery over-charge.
Communication tested during self-test
Low The Battery Protection System has an automated over-charge protection circuit, which should prevent damage.
G2 CAN module cannot receive
CAN transceiver circuit failure (block G), CAN module failure on microcontroller, power circuit failure (block A), cable disconnect, software bug.
Unable to log maximum power point tracker data for performance analysis.
Communication tested during self-test
Low
G-4