cet360smartcar
TRANSCRIPT
California University of Pennsylvania
Department of Applied Engineering & Technology
CET 360: Microprocessor Engineering
Spring 2014
Final Project Report:
Team: Kicking Asphalt
Matt Bonaddio ______________________ Date: 5/2/14
Michael Bichsel ______________________ Date: 5/2/14
Ryan Dempsey ______________________ Date: 5/2/14
John Donofrio ______________________ Date: 5/2/14
Jordan Severo ______________________ Date: 5/2/14
Date: 5/2/2014
Instructor Comments
Contents 1 Project Introduction .....................................................................................................................1
2 Project Description ......................................................................................................................1
2.1 Overview ............................................................................................................................1
2.2.1 Hardware: ........................................................................................................................2
2.2.2 Pololu QTR IR Sensor Array .........................................................................................2
2.2.3 Pololu 1212 Motor Drive ..............................................................................................3
2.3.4 Power System...............................................................................................................4
2.3.5 GP1A75 OPIC Photointerrupter.....................................................................................5
2.3.6 XBee RF Module & TXS0104e Level Translator ............................................................6
2.3.7 Firebird 32 MCF51JM128 MCU ...................................................................................7
2.4 Bill of Materials...................................................................................................................9
2.5 Software Design ................................................................................................................ 10
2.5.1 Project Analysis ......................................................................................................... 10
2.5.2 Line Sensing .............................................................................................................. 10
2.5.3 Steering ..................................................................................................................... 11
2.5.4 Motor Driver .............................................................................................................. 12
2.5.5 Line Tracking............................................................................................................. 13
2.5.6 Speed Sensing ............................................................................................................ 14
2.5.7 Motor PID.................................................................................................................. 15
2.5.8 Wireless Data ............................................................................................................. 15
2.6 Engineering Design Specifics ............................................................................................. 16
2.7 Summary........................................................................................................................... 16
2.8 Modules Used.................................................................................................................... 19
3 Project Journal .......................................................................................................................... 19
4 Project Evaluation ..................................................................................................................... 24
4.1 Typical Processing Time: ................................................................................................... 24
5 References: ............................................................................................................................... 25
6 Appendix A: Schematic ............................................................................................................. 27
7 Appendix B: Code ..................................................................................................................... 29
7.1 Main Code ........................................................................................................................ 29
7.2 Header Files ...................................................................................................................... 40
7.2.1 Derivative.h ............................................................................................................... 40
7.2.2 Exceptions.h............................................................................................................... 40
7.2.3 LCD.h........................................................................................................................ 41
7.2.4 Macros.h .................................................................................................................... 42
7.2.5 PID.h ......................................................................................................................... 43
7.2.6 SCI2.h ....................................................................................................................... 44
7.2.7 stdtypes.h ................................................................................................................... 47
8 Appendix C: Contribution Documents ........................................................................................ 51
Figures
Figure 1: SmarCar Block Diagram .........................................................................................................2
Figure 2: Pololu QTR IR sensor array ....................................................................................................3
Figure 3: Pololu 1212 Motor Driver ......................................................................................................3
Figure 4: LM-2940 5V regulator………………… .........................................................................................4
Figure 5: MCP1702 3.3Volt regulator ...................................................................................................4
Figure 6: Mounting of Photointerupter ................................................................................................5
Figure 7: TXS0104e and XBee ..............................................................................................................6
Figure 8: In circuit picture of the Firebird32..........................................................................................7
Figure 9: Firebird32 Block Diagram ......................................................................................................8
Figure 10: Line Sensing DFD............................................................................................................... 10
Figure 11: Line Sensing Flowchart ...................................................................................................... 11
Figure 12: Steering DFD..................................................................................................................... 11
Figure 13: Steering flowchart............................................................................................................ 12
Figure 14: Motor Control Flow-Chart ................................................................................................. 13
Figure 15: Line Tracking DFD ............................................................................................................. 13
Figure 16: Speed Sensing Flowchart ................................................................................................... 14
Figure 17: Motor PID......................................................................................................................... 15
Figure 18: main() flow-chart……………………… ....................................................................................... 17
Figure 19: rtc_ISR() flow-chart………………….. ....................................................................................... 17
Figure 20: Call Graph........................................................................................................................ 18
Figure 21: Gant Chart ........................................................................................................................ 20
1
1 Project Introduction
The “SmartCar” is the term project for CET360. The main objective is to create an embedded system that enables the car to drive autonomously around a track. The SmartCar
project combines hardware and software features to create a car that is capable of driving itself. The hardware solution is implemented by the engineering team’s hardware expert and assistant. This subgroup is in charge of all on-board manipulation. This includes (but is not limited to)
circuit building, component handling, hardware troubleshooting, and related documentation. The software solution is directed by software expert and assistant. These team members design and
produce the code that makes the system “smart”. The team leader is responsible for guiding the team towards a winning solution, bringing both sides of the project together, and helping to create the finished product. The SmartCar project requires collaboration, cooperation, and focus
from every member of the group.
2 Project Description
2.1 Overview
The purpose of the project is to provide an engineering team experience. Once students graduate and enter the workforce, they will likely be placed into engineering teams with defined
roles and responsibilities. The experience gained from this project ensures preparation for success in future careers. This project is also likely to be the students’ first assignment that results in a large-scale embedded system. Embedded systems are in high demand, and any
exposure to their design and creation is sure to be highly valued by any employer. The SmartCar project brings together the skill-sets that students have been building since their freshman year in
the engineering technology program. This project will become another addition to their “toolbox”, and another leap towards success. Completion of the SmartCar demonstrates the capability to handle a project of this magnitude.
The SmartCar project utilizes the top-down approach to engineering design. It begins
with understanding each and every problem at hand. A high-level design follows. This
addresses each problem at the most basic level, allowing the engineering team to design solutions that are sure to work, before becoming bogged down with specific details. Lower-level
system design comes afterwards. This is where the team begins evaluating how to implement the design using the specific programming language, processor and hardware components. Once the design is completed, it is applied and tested.
At the bottom of it all, the SmartCar must meet certain functionality requirements.
The reason the car is considered smart is because it has the ability to drive itself on a specific track. The track itself has an all-white background, with a black line (similar in size to electrical tape) for the car to follow. The exact path and length of a lap is assumed to be unknown, so the
car must be designed to intelligently make its own decisions. In order to qualify a time, the car must complete two laps around the track.
2
The final solution brought to race day was not quite what we expected. Individually, every feature that was embedded into the project worked, but we had some issues that were not
resolved before race-day. The car did not initially succeed in completing two laps, but by the end of the day it was successfully maneuvering around the track. However, our car moved very
slowly and still needed work to be considered an optimal solution.
2.2.1 Hardware
Numerous components were used in the construction of the Smartcar. The most
important component of all is the FireBird32 processor. It is essentially the “brain” of the car and works with all the other components to make the car run. When designing the circuit for the car, space had to be taken into consideration since there was only ample room on the mounted
breadboard on the car to place components. The circuit was built on a week to week basis, and at times trouble-shooting was needed to ensure that everything was working properly.
Figure 1: SmarCar Block Diagram
2.2.2 Pololu QTR IR Sensor Array
3
The Pololu QTR-8RC infrared (IR) sensor array is the major component used in sensing the line that the Smartcar must follow. The IR sensor operates from the 5V supply and uses
eight IR emitters and eight phototransistors that are paired together to determine the line’s position. The outputs of the emitters (1-8) are then wired using a 16 pin ribbon cable to the
FireBird32 MCU’s 8 PORTB bits (PTB7-PTB0) in bit reverse order. The outputs of the QTR-RC sensor can be seen in the Figure below (Figure 2). There is a mount on the front of the car where the sensor is attached. The sensor can detect the line at a maximum distance of 9.5 mm
but hangs approximately 3mm over the ¾ inch line. Additional padding was added to the front of the sensor for protection in operation do to its very vulnerable position (3).
Figure 2: Pololu QTR IR sensor array
2.2.3 Pololu 1212 Motor Drive
The Pololu 1212 is the board that carries the MC33926 H-bridge and serves in motor
driving application. Located on the right side of the board when looking at Figure 3, are the four terminals that connect to the voltage source and the 7.2 battery source. Software using ISR-assisted PWM drives the motor at a certain speed. Along with driving the motor the 1212 is the
gateway at which the 7.2 volts is distributed to the power system circuit (4).
Figure 3: Pololu 1212 Motor Driver
4
2.3.4 Power System
One of the main hardware challenges of the Smartcar project is to take the 7.2 volt battery supply and regulate it down to the 5 volts at which a majority of the circuit’s components use. The supply voltage is wired to the LM-2940 5 volt regulator (Figure 4), which in return
outputs 5 volt to the circuits main supply rails. The MCP1702 3.3 volt regulator (Figure 5) is also necessary for the wireless communication. The 7.2 supply is also wired to a ½ ratio voltage
divider so a reasonable voltage can be monitored by the FireBird32 MCU. Software can then read the voltage level to determine when the battery is running dry. An on-board LED indicator will then glow red when charging is required.
Figure 4: LM-2940 5V regulator Figure 5: MCP1702 3. 3Volt regulator
5
2.3.5 GP1A75 OPIC Photointerrupter
The GP1A75 is the main component used in speed sensing. It is mounted on the rear of the car and is supplied 5 volts from the supply rail. On the rear axle is a gear with eight evenly spaced holes. As the motor turns the photointerrupter reads highs (hole) and lows (solid) which
are then sent to the FireBird32 MCU. The 8 rising edges are then used in software for determining current speed. The Photointerrupter and mounting can be seen in the Figure below.
Figure 6: Mounting of Photointerupter
6
2.3.6 XBee RF Module & TXS0104e Level Translator
The XBee is a wireless communication module that is connected to the FireBird32
MCU’s SCI pins so Smartcar operation values can be monitored through the LabVIEW software. The XBee has a 2 milimeter pin spacing so a carrier board is necessary to adapt to the 1inch spaced holes on the breadboard. The XBee is limited to a 3.3volt supply so the TXS0104e level
translator is necessary to accomadate for the FireBird32 MCU’s 5 volt operating value. The TXS0104e and XBee circuit can be seen in the Figure below.
Figure 7: TXS0104e and XBee
7
2.3.7 Firebird 32 MCF51JM128 MCU
The Firebird32 is a 32-bit processor and is essentially the “brain” of the Smartcar circuit. It is important for reading and sending data to all the other components. It operates from the 5
volt supply rail. It is the 64-pin version on a 40-pin dual inline package (DIP) module. Below is the block diagram and an in circuit picture of the Firebird32.
Figure 8: In circuit picture of the Firebird32
8
Figure 9: Firebird32 Block Diagram
9
2.4 Bill of Materials
This project used more than just the hardware listed above, and every piece was crucial to
the completion of the project. Below is a complete list of all the parts used:
Name Description Quantity
QTR-8RC Sensor Array IR Line Sensor 1
Firebird 32-Nano Microcontroller 1
Tx0104c Voltage Converter Chip 1
XBee Wireless Transmitter 1
S3010 Servo Steering Servo 1
GP1A75 Speed Sensor 1
MC33926 3V Regulator 1
LM2940 5V Regulator 1
Resistor 12K Ohm 2
Resistor 10K Ohm 1
Capacitor 0. 1µF 2
Capacitor 100µF 2
Capacitor 220µF 1
Capacitor 22µF 1
Capacitor 1µF 1
Potentiometer 5K Ohm 1
Push Button Switch PB1 1
Battery 7. 2V NiCd 1
10
2.5 Software Design
2.5.1 Project Analysis
The first step in the software design process is the analysis phase. We began by evaluating the requirements of the system itself. The outcome of our SmartCar project is evaluated during the final race. The race has specific guidelines to follow. At the start of the
race, the car must be started by pressing an on-board button (11). Once the car is started, it must complete two consecutive laps around the track to qualify a time (11). These requirements
provided our team with an ultimate goal for the project, in addition to winning the race. High-level design is used to describe how major components of the system are connected
and how they interact. For each module, we produced a data flow diagram (DFD) and a flow chart to depict the operation of each module. Each module is explained in detail in the program
description section. For the engineering design phase, we depicted the connections of all the software procedures. A call-graph was prepared to depict how the system calls flow throughout the operation of the software (Figure 20) Our solution utilizes the RTC_isr() to flag the
operations to execute in main(). This method allows for each function to operate in a periodic fashion, occurring in specific intervals.
2.5.2 Line Sensing
To address the first topic of line-sensing, we used a byte of data to store the result of reading the IR sensor array. This byte is named “irdata” and it retains the value that it reads from
the sensor for future use. The DFD for line sensing (Figure 10) depicts the flow of data from the line sensor through the function and then being stored in irdata. This data is then made available
to the project for later use in the line tracking feature.
Figure 10: Line Sensing DFD
To acquire data from the IR sensor array, the device uses an RC circuit to light the LEDs. Then the IR LEDs are turned off and after a specific delay the sensor is read. The line sensing
flow chart (Figure 11) depicts our solution to the operation of the line sensor and how it is manipulated.
11
Figure 11: Line Sensing Flowchart
2.5.3 Steering
The next software module controls the steering of the car. The steering linkage is connected to a Futaba S3010 servo motor. The servo motor is controlled using PWM and
requires a positive pulse width between 1-2 milliseconds to control the position of the servo motor. Our solution to the problem was to use the Colfire32 TPM module to control the width of
the output pulse by varying only the value of one register. Since this module is one of the critical functions, the data flow diagram (Figure 12) and flowchart (Figure 13) are also provided.
Figure 12: Steering DFD
read IR
sensor array
return array data
turn on
all IR LEDs
turn off
all IR LEDs
wait
20uS
wait
600uS
12
Figure 13: Steering flowchart
2.5.4 Motor Driver
The third module concerns the drive motor for the SmartCar. This module controls the
power to the drive motor and the power to the wheels of the car, and is controlled by interrupt
events. Since the TPM1 is shared with the steering servo, it was necessary to manually toggle, set, or clear the state of the TPM channel. To address this problem it was necessary to use output
compare mode to control when the next interrupt is to occur. This was solved by recording a count when the last edge occurred and calculating the time the next edge should occur. A flow-chart for our solution to the SmartCar shows how the motor driver is updated and the line sensor
data is acquired and processed (Figure 14).
update
steering
read
IR Sensor
Array
calculate
the centroid
update
steering
servo
return
13
Figure 14: Motor Control Flow-Chart
2.5.5 Line Tracking
The next module was responsible for handling the problem of tracking the line on the
race track. The module is to handle interpreting the data read from the IR sensor array and providing the appropriate PWM signal to steer the wheels. This problem is a more complex
issue which has many various registers. The data flow diagram (Figure 15) shows how the line sensing module eventually connects to the steering servo.
Figure 15: Line Tracking DFD
update
motor
return
calculate
speed error =
PID(currentSpeed,desiredSpeed)
update
motor duty
cycle
calculate
new motor
duty cycle
14
2.5.6 Speed Sensing
The fifth module of the SmartCar concerned sensing the speed of the car. This module received data from an optical sensor in the form of a tachometer pulse. This pulse was fed into the FireBird32 TPM module where the software initialized the port to operate as a high-speed
counter. This mode of operation is called input compare mode and allows for each rising edge of the tachometer to generate an interrupt event and the appropriate ISR is completed. The function
that handles this operations is called do_speed(), and a flow chart of its operation (Figure 16) is below.
Figure 16: Speed Sensing Flowchart
get
car speed
currentSpeed=
tach/distance
is
tach = 0
?
currentSpeed
= 0
return
YES
NO
15
2.5.7 Motor PID
The sixth module was to address the problem of creating a real-time system to control the car’s speed and steering with a PID based algorithm. The motor control system’s data flow (Figure 17) shows the many registers and procedures which are accessed during the motor PID
calculations and updates.
Figure 17: Motor PID
2.5.8 Wireless Data
The final module of concern was to prepare and send wireless data from the SmartCar to
a remote terminal. This problem consisted of utilizing the FireBird32 SCI module. The packet also required the calculation of a checksum value for proper communications. This problem was addressed using some library functions provided in SCI. h and SCI. c files. The data packet is
prepared as a string and sent through the FireBird32 to an Xbee wireless transceiver. The packet must be sent at a baud rate of 9600 bits/second and contain the valid checksum for proper
communications.
16
2.6 Engineering Design Specifics
During the process of low-level design, we looked into the constraints of the system. One constraint is found within the A/D converter module of the FireBird32 MCU. The A/D converter module can operate in either 8-bit or 10-bit resolution mode. When operating at a 10
bit resolution, there are 1,024 possible steps giving a resolution of 0. 00488V / step. With an error on the LSB, this would give an accuracy of 0. 098%. Another constraint is the response
time of the output devices, especially those of the steering motor and drive motor. Since the steering is controlled by PWM another constraint is the steering can only be updated at a frequency at which the device can respond. In the case of the steering servo we can only update
the steering at a rate below the PWM frequency. Since the car will be powered using a battery during the race another constraint is the battery capacity. The software should make every effort
to programmatically conserve battery power.
2.7 Summary
Once the individual modules were designed, the final source code was available to perform all operations of the vehicle. The final layout of the software design described how each
of the modules interact, and how they respond in real-time. The two routines that handle the real-time operation of the SmartCar are RTC_isr() and main(). The program flow of main is quite straightforward and allows for the software designer to easily turn on and off features
(Figure 18). The flags used in main are set by the RTC_isr() interrupt. The RTC_isr() interrupt flowchart (Figure 19) shows a simple counter, and when the counter hits its limiting value it
allows for a function to be called in main rather than from the SR. This limits the overhead on the ISR and allows the MCU to return to normal operation in a timely fashion.
17
Figure 18: main() flow-chart Figure 19: rtc_ISR() flow-chart
smartCar
is
button
pressed
?
NO
initialize
update
steering
update
drive motor
update
LCD
get the
speed
send serial
data
is it
time to
steer?
is it
time to
update
motor?
is it
time to
update
LCD?
is
it time
to send
wireless
data?
YES
YES
NO
YES
NO
YES
NO
YES
NO
RTC
Interrupt
increment
counters
is
mCtr
> mTime
?
is
sCtr
> steerTime
?
is
lcdCtr
> lcdTime
?
is
sciCtr
> sciTime
?
is
battCtr
> battTime
?
set mFlag
= TRUE
set sFlag
= TRUE
set lcdFlag
= TRUE
set sciFlag
= TRUE
set battFlag
= TRUE
return
18
Figure 20: Call Graph
19
2.8 Modules Used
Below is a table listing all of the Firebird32 peripheral modules we used during the extent of this project.
Modules used Purpose
Timer Pulse Width modulator
(TPM1 channel 5, port F pin 3) Motor driving with variable pulse width
Timer Pulse Width modulator
(TPM2 channel 0, port F pin 4) Pulse width for Steering servo
I/O port B
(pins 0 – 7) Read in IR sensor array data
ADC channel 1
(port D pin 3) Battery voltage reader
ADC channel 2
(port D pin 4) Set the max speed via potentiometer
Timer Pulse Width modulator
(TPM1 channel 4, port F pin 2)
Interrupt driven subroutine for speed
calculation
Serial Communication interface
(Transmission, Port E pin 0) Used to send data wirelessly
Serial Communication interface
(Receiving, Port E pin 1) Used to receive wireless data
3 Project Journal
The design of the SmartCar was implemented in a way where every week our team was
reaching milestones. We were continually improving and adding code and hardware onto the project during lab times. Because of this, our weekly milestones served as encouragement to continue with the project. When the deadline was approaching and our group had moved into
the testing phase, the big break through didn’t happen right away. We were able to look back at our accomplishments to help us push forward and finish the project at hand.
20
Our proposed time table is represented in Figure 21. This was our initial schedule from the beginning of the project. Overall, we stuck to it pretty well, and only deviated towards the
end of the project.
Figure 21: Gant Chart
Week 1 (2/10 - 2/16)
o The first week was an introduction to the Firebird2 and the software we were using to run it. It went over smooth and was a good starting point for the project.
Week 2 (2/17 – 2/23) o Week 2 was the first week of actual SmartCar work. The first task was getting
the car to sense the line. It was a large first step because it has to be right in order to effectively steer the car. This lab went over with no trouble. Our group
connected an oscilloscope to the output of the IR sensors to verify that they were working and discharging correctly. We also had to make sure that the IR sensors were read at the correct time to return highs when the line was under neither it. If
the sensors were checked to soon, they would always report a high because there was insufficient time allotted for the discharge cycle. The solution was to delay a
short amount of time to allow for the discharge but still read the sensors in time to catch the logic high’s from the specific sensors that had the line in their sights. We determined our time to be a delay of 200 milliseconds.
Week 3 (2/24 – 3/2) o The next problem that was tackled was steering. This lab required that the
Firebird32 and servo run off of the bench power supply. We learned that it is best to use an adjustable 6 volts for this rather than the full load of 30 volts because it
Line Sensing
Steering
Motor Drive
Power System
Spring Break
Line tracking
Speed Sensing
PID Control
Wireless Communications
Trouble shooting
Testing
Start and End Dates
Top
ics
Co
vere
d Days
Spent
21
is easier to gauge the correct voltage and harder to input excess voltage into the system. The steering servo itself was run off of the Pulse-Width Modulation
feature of the Firebird32. For successful completion of the lab, our group found which pulse width would result in setting our wheels perfectly straight, and what
our maximum and minimum pulse widths could be before our wheels would bind to one side. Our center turned out to be 1500, with our min being 1100 and max being 1900.
Week 4 (3/3 – 3/9) o The motor driver section of the project was relatively easy to implement. The
motor was driven using an H bridge motor driver board that was run off of the Firebird32’s port F, pin 3. By driving a variable 1 kilohertz signal, we were able
to change the speed. We successfully managed to drive the motor with no issues.
Week 5 (3/10 – 3/16)
o With the motor driver set up on the bread board from last week, the power system was able to be laid out on the rest of the bread board. The team double and triple checked the wires as we went along by using multiple pairs of eyes. We found a
few misplaced wires, and one backwards component, but at the end of the week there we had a working power system that would supply power to all the modules
on the board.
Week 6 (3/17 – 3/23)
o Spring Break, no improvements.
Week 7 (3/24 – 3/30)
o Tracking the line with the SmartCar was a complex problem. Our team had issues implementing the pseudo code given to us as a guide. To test our car, we made a working version of the code given to us by team Geek--. This code
worked but did not account for noise. We agreed to keep working on an improved version of the line tracking code so we could implement it for race day.
o The team wanted to test the car with line tracking, steering, and motor driving all ready, but we ran into a problem with the power switch and bread board. The main switch had gone bad and needed to be replaced. A new switch was soldered
and mounted onto the car. As for the bread board, it had begun to lift off of the cars flat surface that it was mounted to. It was only attached at either end with
Velcro. As a result of years of use, the bread board had been pushed down to often in the middle and pins/wires were being pushed right through the board. We needed to remount the board in a better way. It was decided that carpet tape
would be the most effective solution.
22
o This week we also started working on our presentation for the speed sensing problem. Hardware and software duties were given out to get the ball rolling.
Week 8 (3/31 – 4/6) o Speed sensing proved to be straight forward. The confusing part was converting
from micro seconds to seconds because the tach pulses were generated in microseconds. We used a constant defined as CMPUS to convert the time to
seconds. The other issue was dividing by zero when our tach ISR returned a tach period of zero if it missed a reading. We added an if loop to account for this issue.
o The team also had to rewire our car onto two new bread boards today because of an issue with the mounting to the old ones. When the rewiring was complete, we
used a large binder clip to temporarily attach the bread boards to the car.
Week 9 (4/7 – 4/13)
o The implementation of PID control into our car was the most challenging part of the project. It took our team weeks to effectively be able to control our car with PID gains; however, we struggled to find gains that properly controlled our car.
There may have been problems with other aspects of the code, but our group believed it to be PID issues, and we spent many hours troubleshooting these
routines and gains. o The car needed to be rewired for the last time this week because the carpet tape
had proved effective and the old bread boards were back attached to the car.
o At the beginning of our PID implementation, our car’s motor switch broke. It reached the end of its switch cycle life and also had to be replaced by a new one.
The new switch was successfully soldered and fixed on to the car. o We had a problem with reading the voltage from the battery and implementing
our batter check function. During trouble shooting of our batter voltage check we
determined the voltage divider resisters were not connected correctly, and we were receiving a constant zero volts to the pin. The wiring was corrected.
Week 10 (4/14 – 4/20) o The wireless communication aspect of the smart car had important hardware to
wire because the Xbee communication device ran off of 3. 3 volts instead of the 5 volts like the rest of the system. Everything between the Xbee and the rest of the system had to be ran through a level translator to manipulate the voltage from 5
volts to 3. 3. o Our software was successful at building and sending the packets of information to
the Xbee for transmission, but we had trouble receiving the packets at the labview station. For some reason our packets were getting lost or not transmitted, and our team decided to focus on other areas of the project at this time.
23
o We began to fine tune the PID gains for the car and adjusting the maximum desired speed that would work on the track. At the end of the week, progress was
made toward having a stable system across the entirety of the track.
Weeks 11 (4/21 – 4/27) and 12 (4/28 – 5/1)
o With race day coming up on May 1st, the team we tirelessly trouble shooting the remaining aspects of the code. We first added the push button start to comply
with race standards, and to help the PID controller. The push button allowed for the code to start running when the car was on the track, rather than once the code was compiled and ran from the CodeWarrior debug window. Code running in
this fashion would not gather unnecessary error for the PID system. o During testing, the car repeatedly veered to the right directly after starting. After
examining the IR sensor array, it was found to be missing a transistor. This transistor controlled the option of turning the IR LED’s on and off between readings to save battery. The missing transistor did not allow for the LED’s to
turn on. With help from Professor Sumey, a wire was soldered to connect two pins to bypass this section of the circuitry.
o It was also noted that the steering system would mechanical bind to one side if the servo moved to far in either direction. It lacked the power to unbind itself, so the wheels had to be manually reset to the center. We did not encounter this issue
earlier in the year because there were values in place to constrain the range of the servo. The reason for this binding is unknown, so it was manually corrected and
no other instances were documented. o Issues existed with the smart car steering lagging when ran at even slow rates.
The problem was the RTC was running at a period of 1milisecond per interrupt.
When timing the steering functions, testing showed the refresh rate of steering at 200 miliseconds, which was intended to occur every 20 miliseconds. After a code
review, the modulo register of the RTC was set to 0x09 making the interrupts occur every 10mS. This was causing the car to operate much slower than intended with the defined timing periods. This was corrected by reducing the
times by a factor of 10. o During practice runs, it was noticed that the car was generating incorrect tach
pulses and readings. Our tach period was coming back with values ranging from 50 into the thousands of centimeters per second. These values at the upper end were very inaccurate. Unfortunately no solution to this problem was found.
o We dug further into the PID and its gains, our max speed, and implemented other safety features and exceptions. Unfortunately we were unable to get a truly
effective solution.
24
4 Project Evaluation
At the beginning of the semester, our team developed a chart that estimated the dates of when we would complete certain tasks. When constructing our project proposal, it was very
easy for us to predict these dates. This was a result of having a known class schedule, and because of the early access we had to future lab assignments. As a result, we were able to follow our projected time-line very closely. There were times here and there when things were not quite
working, but we never fell more than a week behind. We were allowed access to the lab at many times outside of our scheduled lab hours, so we never fell behind, and we were usually ahead of
the game. Time was never a concern with our team. We stayed on track and worked together.
Time was not an issue, and neither was space. Firebird32MCF51JM microcontroller
limited us to specific amounts of random access memory (RAM) and flash memory. They can hardly be called limits though; we did not even come close to running out of room. We used
exactly 4,270 bytes of flash memory. This was clearly not an issue as we had 128k bytes to work with. Therefore, we used up only 3. 26% of the available flash memory. For RAM, we only used 380 bytes of the available 16k. This consumed only 2. 32% of what was available in
the microcontroller unit (MCU).
A typical concern when developing embedded systems is how much time the system spends doing specific tasks. Measuring the battery voltage, tracking the line, and transmitting data all takes time. Here is how much time, exactly.
4.1 Typical Processing Time:
(Unfortunately, our floppy disk could not be read by any computer. Different machines were tried and could not open any of the scope shots. We will include the floppy disk. )
IR array data acquisition: 200 microseconds A/D conversion of battery voltage: 20 microseconds
Drive motor update: 100 microseconds Data Transmission: 1 ms
25
5 References:
1.) Jeff Sumey’s Virtual Resource Center
http://www.aet.calu.edu/~jsumey/
2.) QTR-8A and QTR-8RC Reflectance Sensor Array User's Guide
http://www.aet.calu.edu/~jsumey/CET360/smartcar/datasheets/Pololu-qtr-8x-reflectance-sensor-array-
user-guide.pdf
3.) Pololu QTR Reflectance Sensor Application Note
http://www.aet.calu.edu/~jsumey/CET360/smartcar/datasheets/Pololu-qtr-8x-reflectance-sensor-array-
application-notes.pdf
4.) MC33926 Motor Driver Carrier
http://www.aet.calu.edu/~jsumey/CET360/smartcar/datasheets/Pololu-1212.pdf
5.) A Throttle Control H-Bridge
http://www.aet.calu.edu/~jsumey/CET360/smartcar/datasheets/MC33926.pdf
6.) LM2940/LM2940C 5V Regulator
http://www.aet.calu.edu/~jsumey/CET360/smartcar/datasheets/LM2940_LDOreg.pdf
7.) MCP1702 3.3V Regulator
http://www.aet.calu.edu/~jsumey/CET360/smartcar/datasheets/MCP1702_LDOreg.pdf
8.) GP1A75EJ000F OPIC Photointerrupter
http://www.aet.calu.edu/~jsumey/CET360/smartcar/datasheets/GP1A75E.pdf
9.) Xbee RF Module User Manual
http://www.aet.calu.edu/~jsumey/CET360/smartcar/datasheets/xbee-user-manual.pdf
10.) TXS0104e Level Translator
http://www.aet.calu.edu/~jsumey/CET360/smartcar/datasheets/TXS0104E.pdf
11.) Race event rules
http://www.aet.calu.edu/~jsumey/CET360/smartcar/racerules.html
26
12.) Sevo Information
http://www.futaba-rc.com/servos/analog.html
13.) MCF51JM128 FireBird32® Integrated Microcontroller Reference Manual
http://www.aet.calu.edu/ftp/cet/360/resources/FireBird32/MCF51JM128-RefManual-v2.pdf
14.) Picture for the LM2940 LDO regulator
http://www.reuk.co.uk/LM2940-12V-1A-Low-Dropout-Regulator.htm
15.) Picture for the MCP1702 LDo regulator
www.octopart.com
27
6 Appendix A: Schematic
28
29
7 Appendix B: Code
7.1 Main Code/* 1 * Smart Car 2 * Version: 012 3 * Team Kicking Asphalt 4 5 * Authors: 6 * Matthew Bonaddio, Michael Bichsel, Ryan Dempsey, 7 * John Donofrio, and Jordan Severo 8 * 9 * Date: 4/30/2014 10 * Copyright 2014 - All rights reserved 11 * 12 * Description: 13 * SmartCar Final Project 14 * 15 * Outputs: 16 * Motor PWM output - PTF3 - TPM1C5 17 * Steering Servo - PTF4 - TPM2C0 18 * 19 * Inputs: 20 * IR Sensor Array - PTBD - Port B p0-7 21 * Battery Voltage - PTD3 - AD10 - adch = 0b01010 22 * Max Speed Voltage - PTD4 - AD11 - adch = 0b01011 23 * Tach (Speed Sens.)- PTF2 - TPM1C4 24 * PB1 - Start PB - PTD0 - Active Low 25 * 26 * I/O: 27 * Xbee - Wireless - PTE0 - TX - to CPU 28 * Xbee - Wireless - PTE1 - RX - to MCU 29 */ 30 31 //<Compiler Options> 32 #pragma c99 on // enable C99 features 33 #pragma require_prototypes off 34 35 //<Included Files> 36 #include <stdio.h> // for printf() & friends 37 #include <stdTypes.h> 38 #include <hidef.h> // for EnableInterrupts macro 39 #include "derivative.h" // derivative information 40 #include "macros.h" // useful macros 41 #include "LCD.h" // LCD header 42 #include "PID.h" // PID header 43 #include <string.h> // String header 44 #include "SCI2.h" // SCI header 45 #include "math.h" // Math header 46 47 //<Constant Definitions> 48 #define battADC 0b01010 // the ADCH for the battery 49 #define speedADC 0b01011 // the ADCH for the max speed pot 50 #define MOTOR_BIT PTFD_PTFD3 // on PF3 (TPM1CH5) 51 #define CMPUS 2150000 // 2.15 cm per reading, multiplied by 52 1e6 to convert to second 53 #define SERVO_CENTER 1500 // servo center value 54 #define PB1 PTDD_PTDD0 // on PD0 - Start Push Button 55 #define HEARTBEAT PTFD_PTFD0 // heartbeat debug output pin (PF0) 56 #define BID 0xff // Xbee broadcast ID 57
30
#define EOP "\r\n" // Xbee end-of-packet string 58 59 //<RTC timing functions> 60 #define LCDTIME 25 // 4 LCD updates per second 61 #define MOTORTIME 8 // Interval Time in mS to run the motor PID 62 #define STEERTIME 4 // Interval Time in mS to run the steering PID 63 #define SCITIME 100 // 4Hz Update of SCI 64 #define BATTTIME 50 // 4 Battery Checks per second 65 #define SPEEDTIME 20 // Speed readings 66 67 //<Compiler options> 68 #define PBSTART //comment out if PB is not fitted 69 #define MAXSC //comment out if Max Speed Pot not fitted 70 71 const byte MyID = 6; // my car ID (match license number) 72 73 //<global variables> 74 //--steering related variables 75 Spid SteerPID; // steering PID controller data structure 76 byte irdata; // IR data read from sensor array 77 int CurrentSteer = 0; // car's current steering 78 int DesiredSteer = 0; // desired speed steering 79 int Vbatt; // Battery Voltage X 10 ex.Vbatt 66 = 80 6.6V 81 int centroid; // centroid global var 82 int newCent; // averaged centroid value 83 word steerpw; 84 85 // <safety variables> 86 Bool eStop = FALSE; // Emergency stop! 87 int MaxSpeed = 50; // Max allowed speed in cm/s 88 unsigned int RunTime = 0; // run time in ms. 89 unsigned int LastLineTime = 0; // time of line last seen 90 unsigned int LastTachTime = 0; // time of last tach pulse received 91 92 // drive speed related vars 93 Spid MotorPID; // drive motor PID controller data structure 94 int DtSpeed = 10; // delta-T period for speed control 95 word TachPeriod = 0; // speed sensor (tachometer) period in us 96 int CurrentSpeed = 0; // current measured speed in cm/s 97 int DesiredSpeed = 0; // desired speed in cm/s 98 word MotorDC = 0; // drive motor Duty Cycle setpoint (0..100) 99 100 // RTC Flags 101 Bool battFlag = TRUE; // Used to only check the battery 2x per 102 second 103 Bool steerFlag = FALSE; // doSteering Flag Bit (PID Control) 104 Bool motorFlag = FALSE; // doMotor Drive Flag Bit (PID Control) 105 Bool lcdFlag = FALSE; // Flag to update LCD 106 Bool sciFlag = FALSE; // Flag to send serial data 107 Bool speedFlag = FALSE; 108 109 void MCGinit() 110 { 111 MCGC1 = 0x1c; // set RDIV = 12MHz/8 = 1.5MHz 112 MCGC2 = 0x64; // BDIV=2, enable ExtRef and Hi Range 113 MCGC3 = 0x48; // select PLL source and VDIV= x32 114 115 // VCO is now going to 48 MHz 116 MCGC1_IREFS = 0; // turn off IREFS 117 while (!MCGSC_LOCK) {} // wait for OSC initialization to complete 118 // MCGOUT=24Mhz, Busclk=12MHz 119 } 120
31
121 // MCU-specific initialization 122 void initializeMCU() 123 { 124 SOPT1_COPT = 0; // disable COP 125 MCGinit(); // call MCGinit to initialize the 126 FireBird32 clock 127 128 FB_RGB_ON; // Enable the RGB LED 129 PTFDD = 7; // make PTF2-0 output ports 130 131 // ADC initialization 132 ADCCFG = (0b10 << ADCCFG_ADIV_BITNUM) // select Busclk/4 (3MHz) 133 + (0b10 << ADCCFG_MODE_BITNUM); // 10-bit mode 134 APCTL2 |= APCTL2_ADPC10; // disable PTD3 as GPIO 135 APCTL2 |= APCTL2_ADPC11; // disable PTD4 as GPIO 136 137 // Real-Time Counter initialization 138 RTCSC = 0x18; // enable RTC, select 1ms period from 139 1kHz 140 RTCMOD = 9; // RTIF every 1ms 141 142 // TPM1 initialization 143 TPM1SC = TPM1SC_CLKSA_MASK // select bus clock for timer clock !!!-> from 144 BUS 145 + 2; // divby-4 prescaler (12MHz / 4 = 3MHz 146 Timer clock) 147 148 // TPM1C4 initialization for speed sensor input 149 TPM1C4SC = TPM1C4SC_CH4IE_MASK // enable channel interrupts 150 + TPM1C4SC_ELS4A_MASK; // select rising edge input capture 151 mode 152 153 // TPM1C5 for motorDC output on PF3 154 TPM1C5SC = TPM1C5SC_CH5IE_MASK // enable channel interrupts 155 + TPM1C5SC_MS5A_MASK; // select output compare mode 0x02 156 157 // TPM2 initialization 158 // configure TPM2 for steering servo output pulse 159 TPM2SC = 10 ; // select bus clock for timer clock 160 TPM2MOD = 3*20000 - 1; // set TPM's period to 20ms (50Hz) 161 TPM2C0SC = 0x28; // PWM mode // high-true output pulse 162 TPM2C0V = 3 * 1500; // 1500us = servo "center" pulse width 163 164 #ifdef PBSTART 165 PTDDD_PTDDD0 = 0; //make pd0 as input 166 #else 167 PTDDD_PTDDD0 = 1; //make PD0 an output 168 #endif 169 170 // SCI initialization 171 SCI1BD_SBR = 78; //select 9600 baud rate for SCI 172 SCI1C1 = 0; 173 SCI1C2 = 0x0C; // enable Tx & Rx 174 175 EnableInterrupts; // turn on global interrupts 176 } 177 178 // function constrain() - set a min and max limit on any integer 179 int constrain(int x, int min, int max) 180 { 181 if (x < min) return min; 182 if (x > max) return max; 183
32
return x; 184 }//end constrain() 185 186 // sub do_speed() - calculate the CurrentSpeed 187 void do_speed() //TachPeriod is an input argument 188 { 189 // gone too long without seeing a tach pulse? 190 if (RunTime - LastTachTime >= 100) // 0.25 sec 191 TachPeriod = 0; // fix tachPeriod 192 193 // gone too long without seeing any line? 194 if (RunTime - LastLineTime > 250) // 0.25 sec 195 { 196 MotorDC = 0; // immediately stop motor 197 DesiredSpeed = 0; // set PID desired to 0 198 eStop = TRUE; // set emergency stop flag 199 LCD_line(0,"NO CAR " ); // display error msg l1 200 LCD_line(1,"IR DATA"); // display error msg l2 201 } 202 203 if(TachPeriod != 0) // only if TachPeriod is positive 204 CurrentSpeed = (CMPUS/TachPeriod); //calculate speed in cm per 205 second 206 else 207 CurrentSpeed = 0; // else no tach pulse or stopped 208 209 }//end do_speed() 210 211 //new sub procedure for PID motor control 212 void doMotorPID() 213 { 214 HEARTBEAT = 1; 215 float speedError; 216 //if(TachPeriod !=0) 217 // do_speed(); 218 //else 219 // CurrentSpeed = 0; 220 DesiredSpeed = constrain(DesiredSpeed,0,MaxSpeed); 221 speedError = PID_Update(&MotorPID, CurrentSpeed, DesiredSpeed); 222 MotorDC =constrain((MotorDC +speedError),0,100); 223 HEARTBEAT = 0; 224 } 225 226 // function read_irarray() - get a reading from the IR Sensor Array 227 byte read_irarray() 228 { 229 //HEARTBEAT = 1; 230 PTBD = 0xff; // make Port B all highs 231 PTBDD = 0xff; // make Port B all outputs 232 usDelay(20); // allow sensor caps to charge 233 PTBDD = 0; // switch to all inputs 234 usDelay(200); // delay for discharge 235 // HEARTBEAT = 0; 236 return PTBD; // read & return sensor array results 237 }// end read_irarray() 238 239 int find_centroid(byte data) 240 { 241 int maxlen = 0; 242 int maxsum = 0; 243 Bool inrun = FALSE; 244 int pos = 0; //start at bit 7 245 int wsum = 0; 246
33
int runlen = 0; 247 int maxwsum = 0; 248 249 for(pos=0;pos<8;pos++) 250 { 251 //test bit 252 if(BITTST(pos,data)) //test the bit 253 { //if the bit was set 254 if(inrun == FALSE) 255 { 256 wsum = 0; 257 runlen = 0; 258 inrun = TRUE; 259 } 260 wsum += (8-pos); 261 runlen += 1; 262 } 263 else //if the bit was not set 264 { 265 if(inrun) 266 { 267 if(runlen > maxlen) 268 { 269 maxlen = runlen; 270 maxwsum = wsum; 271 } 272 inrun = FALSE; 273 } 274 } 275 } 276 277 if((inrun>maxlen) && (runlen > maxlen)) 278 { 279 maxlen = runlen; 280 maxwsum = wsum; 281 } 282 283 if (maxlen == 0) 284 return 0; 285 else 286 return 10 * maxwsum / maxlen; 287 288 } 289 290 //new sub procedure for PID steering control 291 void doSteerPID() 292 { 293 int centError = 0; 294 byte irdata; 295 static int lost = 0; 296 static int lifted = 0; 297 static int oldCent = 0; 298 float steerFactor = 0; 299 int temp=0; 300 301 irdata = read_irarray(); // read sensor array 302 303 if(irdata == 0x00) 304 { 305 //lost++; 306 lost = 0; 307 308 if(lost >4)//number under review!!!!! 309
34
{ 310 MotorDC= 0; 311 DesiredSpeed = 0; 312 steerpw = SERVO_CENTER; 313 TPM2C0V = steerpw*3; 314 eStop = TRUE; 315 LCD_line(0,"CAR LOST" ); 316 LCD_line(1,"LINE "); 317 } 318 } 319 else if(irdata == 0xff) 320 { 321 //lifted+'; 322 lifted = 0; 323 324 if(lifted >5)//number under review!!!!! 325 { 326 MotorDC= 0; 327 DesiredSpeed = 0; 328 steerpw = SERVO_CENTER; 329 TPM2C0V = steerpw*3; 330 eStop = TRUE; 331 LCD_line(0,"NO CAR " ); 332 LCD_line(1,"IR DATA"); 333 } 334 } 335 else 336 { 337 eStop = FALSE; 338 lost = 0; 339 lifted = 0; 340 LastLineTime = RunTime; 341 centroid = find_centroid(irdata); 342 newCent = (oldCent *.5 )+ (centroid *.5); 343 centError = (45-newCent); 344 oldCent = newCent; 345 temp = SERVO_CENTER - steerpw; 346 if(temp<0) 347 temp *= -1; 348 //steerFactor = 1 - (temp / (2*300)); 349 //DesiredSpeed = (int)(MaxSpeed * steerFactor); 350 DesiredSpeed = (int)(MaxSpeed); 351 steerpw = constrain(SERVO_CENTER - (10*centError),1100,1900); 352 TPM2C0V = steerpw*3; 353 } 354 } 355 356 // usDelay(): delay given number of microseconds using Timer/Pulse Modulator module 357 void usDelay(unsigned short n) 358 { 359 //PTFD_PTFD2 = 1; // set PTF2 high for "usDelay() 360 heartbeat" output 361 word timerticks = 3*(n-1); // x3 because Timer is clocked at 3MHz 362 word startcnt = TPM1CNT; 363 while ((word)(TPM1CNT-startcnt) < timerticks) {} 364 //PTFD_PTFD2 = 0; // complete heartbeat output 365 } 366 367 // msDelay(): delay given number of milliseconds using usDelay() rtn. 368 void msDelay(unsigned short n) 369 { 370 while (n-- > 0) usDelay(1000); 371 } 372
35
373 void set_maxSpeed() 374 { 375 ADCSC1 = speedADC; // start conversion PTD3 376 WAITFOR(ADCSC1_COCO); // always wait for coco 377 MaxSpeed = (ADCR*500 / 1024); // 378 } 379 380 //lab 7 code 381 382 /* 383 *** checksum8(): compute & return 1's complement checksum of specified byte array 384 * in: p=pointer to beginning of byte array 385 * len=length of array in bytes 386 * out: 8-bit 1's comp.checksum 387 */ 388 byte checksum8(void *p, int len) 389 { 390 byte *q = p; // this is so p can be of any type 391 byte sum = 0; // running sum of array bytes 392 for (; len>0; --len) // iterate over each byte in array 393 sum += *q++; // add byte value to running sum 394 return (byte)~sum; // return 1's complement of sum 395 } 396 397 /* 398 * sendData(): function to periodically transmit status data "packet" 399 * from global variables 400 */ 401 void sendData() 402 { 403 char s[40]; // packet string to be sent 404 byte cksum; // 8-bit 1's complement checksum 405 406 //HEARTBEAT = 1; 407 408 // create broadcast packet string 409 sprintf(s, "$SC%d,%d,%d,%d,%d,%d,%d", 410 MyID, BID, Vbatt, irdata, steerpw, CurrentSpeed, MotorDC); 411 // calculate checksum 412 cksum = checksum8(s, strlen(s)); 413 // and append it to string 414 sprintf(s+strlen(s), ":%02x", cksum); 415 // add end-of-packet marker 416 strcat(s, EOP); 417 // send status packet 418 419 SCI0_puts(s); 420 421 //HEARTBEAT = 0; 422 } 423 424 // does battery check and displays the color on the RGB LED 425 void do_batt() 426 { 427 //HEARTBEAT = 1; 428 429 ADCSC1 = battADC; // select ADC Channel for battery 430 WAITFOR(ADCSC1_COCO); // wait for conversion complete 431 Vbatt = (ADCR/20) * 2; // calculate vBatt from A/D result 432 433 //HEARTBEAT = 0; 434 if(Vbatt > 72) // if higher than 7.2V 435
36
{ 436 //LED - green 437 FB_RGB_RED = 1; 438 FB_RGB_GREEN = 0; 439 FB_RGB_BLUE = 1; 440 441 }else if(Vbatt < 66) // if less than 6.6V 442 { 443 //LED - red 444 FB_RGB_RED = 0; 445 FB_RGB_GREEN = 1; 446 FB_RGB_BLUE = 1; 447 //MotorDC = 0; 448 //DesiredSpeed = 0; 449 LCD_line(0, "LOW BATT"); 450 LCD_line(1,"SHUTDOWN"); 451 }else // else its between 7.2V & 6.6V 452 { 453 //LED - yellow 454 FB_RGB_RED = 0; 455 FB_RGB_GREEN = 0; 456 FB_RGB_BLUE = 1; 457 } 458 battFlag = FALSE; // reset the batt flag 459 460 //HEARTBEAT = 0; 461 } 462 463 void do_LCD() 464 { 465 char s[50]; //define output string 466 lcdFlag = FALSE; //reset the flag 467 LCD_clear(); //clear the current LCD 468 sprintf(s, "%d,%d", Vbatt, MaxSpeed); //create line 1 string 469 LCD_line(0, s); //write line 1 of LCD 470 sprintf(s, "%d,%d", CurrentSpeed, MotorDC); //create line 2 string 471 LCD_line(1, s); //write line 2 string 472 } 473 474 void main(void) 475 { 476 477 PID_Init(&SteerPID, .7, 0.02, 90, -5, 5); 478 PID_Init(&MotorPID, 1, 20, .2, -100, 100); 479 480 initializeMCU(); // 1-time MCU initialization 481 482 int cc = 0; 483 int nsf2 = 0; 484 485 FB_YLED_ENABLE; 486 FB_YLED = 1; 487 488 FB_RGB_ENABLE; 489 FB_RGB_RED = 1; 490 FB_RGB_GREEN = 1; 491 FB_RGB_BLUE = 1; 492 FB_RGB_ON; 493 494 msDelay(100); // start-up delay to allow hardware to stabilize 495 496 LCD_init(); // initialize LCD 497 LCD_clear(); // clear LCD garbage 498
37
499 500 LCD_line(0, "Press PB"); 501 LCD_line(1, "to Start"); 502 503 504 #ifdef PBSTART 505 //new code for push button start 506 while(PB1)//active low 507 { 508 FB_RGB_RED = 0; 509 msDelay(5); 510 FB_RGB_RED = 1; 511 } 512 #endif 513 514 #ifdef MAXSC 515 set_maxSpeed(); //function for setting max speed via pot 516 #endif 517 518 SCI0_init(12000000, 9600, 'N'); // serial comms initialization 519 520 FOREVER { 521 do_speed(); 522 if(steerFlag) 523 { 524 steerFlag = FALSE; 525 doSteerPID(); 526 } 527 528 if(motorFlag && eStop ==FALSE) 529 { 530 motorFlag = FALSE; 531 //do_speed(); 532 doMotorPID(); 533 } 534 535 if(lcdFlag && eStop ==FALSE) 536 { 537 lcdFlag = FALSE; 538 do_LCD(); 539 } 540 541 if(speedFlag) 542 { 543 speedFlag = FALSE; 544 //do_speed(); 545 } 546 547 if(sciFlag) 548 { 549 sciFlag = FALSE; 550 sendData(); 551 } 552 553 if(battFlag) 554 { 555 battFlag = FALSE; 556 do_batt(); 557 } 558 559 }//end forever loop 560 }//end main 561
38
562 //motor ISR reads motorDC value - 0-100 563 // then outputs on TPM1C5 - the required PWM signal scaled to 1000 - 2000 ppw 564 interrupt 76 void MotorISR(void) 565 { 566 word nextedge = 1000; // time in us till next edge 567 TPM1C5SC &= 0x7F; // Acknowledge and reset interrupt flag 568 TPM1C5SC_CH5IE = 1; // Enable TPM1C5 Interrupts 569 if (MotorDC == 0) // If set to 0% 570 TPM1C5SC_ELS5x = 0b10; // Put TPM1C5 in clear mode 571 else if(MotorDC >= 100) // If set to 100% 572 TPM1C5SC_ELS5x = 0b11; // Put TPM1C5 in set mode 573 else // If between 0-100% 574 { 575 TPM1C5SC_ELS5x = 0b01; // Put TPM1C5 in toggle mode 576 if(MOTOR_BIT) // If the last value was high 577 nextedge = MotorDC * 10; //the next edge needs to occur 578 else // if the last value was low 579 nextedge = (100-MotorDC) *10 ;//the next edge should occur 580 } 581 TPM1C5V = TPM1C5V+( nextedge *3); //update the TPM1C5 value to interrupt on 582 time 583 }//end MotorISR() 584 585 //RTC interrupt ISR - running at 1kHz = 1mS per interrupt entry 586 interrupt 91 void RTC_isr() 587 { 588 static int mPID,sPID; // PID counters 589 static int sciCnt; // SCI counter 590 static int lcdCnt; // LCD counter 591 static int battCnt; // Battery Check counter 592 static int speedCnt; // Calculate speed counter 593 594 RunTime++; // update global ms.runtime counter 595 RTCSC |= 0x80; // Acknowledge 596 RTCSC |= 0x10; // RTC interrupt enable 597 598 //new PID update checks 599 if(++mPID >= MOTORTIME) // if its time to run motor PID 600 { 601 mPID = 0; // clear the mPID counter 602 motorFlag = TRUE; // set motorFlag to call do_motor() in main 603 } 604 if(++sPID >= STEERTIME) // if its time to do steering 605 { 606 sPID = 0; // clear the sPID counter 607 steerFlag = TRUE; // set the steeringFlag to call do_steer() in main 608 //HEARTBEAT = ~HEARTBEAT; 609 } 610 if(++sciCnt >= SCITIME) // if its time to do SCI communications 611 { 612 sciFlag = TRUE; 613 sciCnt = 0; 614 } 615 if(++lcdCnt >= LCDTIME) // if its time to update the LCD 616 { 617 lcdFlag = TRUE; 618 lcdCnt = 0; 619 } 620 if(++battCnt >= BATTTIME) // if its time to check the battery 621 { 622 battFlag = TRUE; 623 battCnt = 0; 624
39
} 625 if(++speedCnt >= SPEEDTIME) // if its time to check the battery 626 { 627 speedFlag = TRUE; 628 speedCnt = 0; 629 } 630 631 632 }//end RTC_isr() 633 634 //ISR to determine the current period of the car speed 635 //using PTF2 - TPM1C4 636 interrupt 75 void Tach_isr(void) 637 { 638 static int spokeCount = 0; 639 //HEARTBEAT = ~HEARTBEAT; 640 static int lastcnt = 0; // Previous count at last 641 tach reading 642 int currentcnt = 0; // Initialize current 643 count 644 currentcnt = TPM1C4V; // take current readings from 645 value register 646 TPM1C4SC &= 0x7F; // acknowledge the 647 interrupt 648 TachPeriod=(word)(currentcnt-lastcnt)/3;// Calculate period between tac 649 readings 650 // 3 651 accounts for the 3 megahertz bus clock 652 lastcnt = currentcnt; // update the last count 653 to the most recent reading 654 LastTachTime = RunTime; 655 }//end Tach_isr()656
40
7.2 Header Files 7.2.1 Derivative.h
/* 1 * Note: This file is recreated by the project wizard whenever the MCU is 2 * changed and should not be edited by hand 3 */ 4 5 /* Include the derivative-specific header file */ 6 #include <mcf51jm128.h> 7 8 #define _Stop asm ( mov3q #4,d0; bclr.b d0,SOPT1; stop #0x2000; ) 9 /*!< Macro to enter stop modes, STOPE bit in SOPT1 register must be set prior to 10 executing this macro */ 11 12 #define _Wait asm ( mov3q #4,d0; bset.b d0,SOPT1; nop; stop #0x2000; ) 13 /*!< Macro to enter wait mode */ 14
7.2.2 Exceptions.h
/* 1 * File: exceptions.h 2 * Purpose: Generic exception handling for ColdFire processors 3 * 4 * Notes: 5 */ 6 7 #ifndef _MCF_EXCEPTIONS_H 8 #define _MCF_EXCEPTIONS_H 9 10 #ifdef __cplusplus 11 extern "C" { 12 #endif 13 14 /***********************************************************************/ 15 /* 16 * Dummy routine for initializing hardware.For user's custom systems, you 17 * can create your own routine of the same name that will perform HW 18 * initialization.The linker will do the right thing to ignore this 19 * definition and use the version in your file. 20 * 21 */ 22 23 void __initialize_hardware(void); 24 25 /***********************************************************************/ 26 /* 27 * This is the handler for all exceptions which are not common to all 28 * ColdFire Chips. 29 * 30 * Called by mcf_exception_handler 31 * 32 */ 33 void derivative_interrupt(unsigned long vector); 34 35 /***********************************************************************/ 36 /* 37 * This is the exception handler for all exceptions common to all 38 * chips ColdFire.Most exceptions do nothing, but some of the more 39 * important ones are handled to some extent. 40
41
* 41 * Called by asm_exception_handler 42 */ 43 void mcf_exception_handler(void *framepointer); 44 45 46 /***********************************************************************/ 47 /* 48 * This is the assembly exception handler defined in the vector table. 49 * This function is in assembler so that the frame pointer can be read 50 * from the stack. 51 * Note that the way to give the stack frame as argument to the c handler 52 * depends on the used ABI (Register, Compact or Standard). 53 * 54 */ 55 asm __declspec(register_abi) void asm_exception_handler(void); 56 57 /***********************************************************************/ 58 /* 59 * printf() TRAP #14 handler 60 * 61 */ 62 #if CONSOLE_IO_SUPPORT == 1 63 asm __declspec(register_abi) void TrapHandler_printf(void); 64 #endif 65 66 #ifdef __cplusplus 67 } 68 #endif 69 70 #endif /* _MCF_EXCEPTIONS_H */ 71
7.2.3 LCD.h /* 1 * LCD.h: interface for LCD driver module 2 * written by J.Sumey <[email protected]> 3 * February 2009 4 */ 5 6 #pragma warning off (10107) // identifier expected 7 8 #define LINES 2 9 #define COLS 40 10 11 extern void msDelay(unsigned short n); 12 extern void usDelay(unsigned short n); 13 14 15 void LCD_init(void); 16 17 void LCD_clear(void); 18 19 // LCD_goto: move cursor to zero-based row & col. 20 // The BotBoard (mini) LCD supports row=0..1, col=0..7 21 void LCD_goto(byte row, byte col); 22 23 void LCD_putc(char c); 24 25 void LCD_puts(const char *s); 26 27
42
void LCD_line(byte line, const char *s); 28 29 void LCD_puth2(byte b); 30 31 void LCD_puth4(word w); 32 33 34 /////////////////////////////////////////////////////////////////////// 35 // e x p e r i m e n t a l // 36 37 /* 38 * list of commands (1st arg.to lcd()) accepted 39 * NAA = Number of Additional Args 40 * AAT = Additional Arg Types 41 * / 42 enum cmds 43 { // COMMAND NAA AATs DESCRIPTION 44 LC_INIT, // 0 initialize display 45 LC_CLEAR, // 0 clear display & home cursor 46 LC_HOME, // 0 send cursor to home 47 LC_CTRL, // 1 int change display control options 48 LC_SHIFT, // 1 int shift cursor or display, L or R 49 LC_GOTO, // 2 int l,int c move cursor to line,col (1-based) 50 LC_PUTC, // 1 int c output character c 51 LC_PUTS, // 1 char *s output null-terminated string 52 LC_PUTD, // 2 int n,int w output n as decimal, field width=w 53 LC_PUTH2, // 1 int n output n as 2 hex digits 54 LC_PUTH4, // 1 int n output n as 4 hex digits 55 LC_DELAY, // 1 int n set character output delay 56 LC_PUTCGRAM, // 3 UINT8 *udcTbl put data to CG RAM 57 // int udcCharNum - user def'd char no. 58 // int lcdCharNum - LCD char no. 59 LC_GETAC, // 0 get current Address Counter value 60 // LC_PBAR, ProgressBar(u16 progress, u16 maxprogress, u08 length) 61 }; 62 63 // lcd() is a variadic function 64 int lcd(enum cmds cmd, ...); 65 /**/ 66
7.2.4 Macros.h /* 1 * macros.h: miscellaneous definitions and utility macros 2 * written by J.Sumey <[email protected]> 3 * February 2009 4 */ 5 6 // Bit manipulation convenience macros: 7 // BITMSK - convert bit number to equivalent logic mask 8 #define BITMSK(bit) (1 << (bit)) 9 // Test, Set, Clear, & Complement a given bit of a given location 10 #define BITTST(bit,loc) (loc & BITMSK(bit)) 11 #define BITSET(bit,loc) loc |= BITMSK(bit) 12 #define BITCLR(bit,loc) loc &= ~BITMSK(bit) 13 #define BITCOM(bit,loc) loc ^= BITMSK(bit) 14 15 // some handy macros 16 #define FALSE 0 17 #define TRUE 1 18 #define HIBYTE(w) (w>>8 & 0xff) // extract most significant byte of a word 19
43
#define LOBYTE(w) (w & 0xff) // extract least significant byte of a word 20 #define SWAPBYTES(w) (HIBYTE(w) + (LOBYTE(w)<<8)) 21 #define MIN(a,b) ((a)<(b) ? (a) : (b)) 22 #define MAX(a,b) ((a)>(b) ? (a) : (b)) 23 24 #define FOREVER for(;;) 25 #define WAITFOR(condition) do {} while (!(condition)) 26 27 28 /*** Firebird32-specific macros ***/ 29 30 // Firebird32 I/O port definitions 31 #define FB_SW2 PTGD_PTGD0 // S2 (user switch) 32 #define FB_SPEAKER PTFD_PTFD5 // speaker 33 #define FB_YLED PTED_PTED6 // D13 'L' LED 34 #define FB_RGB_RED PTED_PTED3 // RGB LED Red cathode 35 #define FB_RGB_GREEN PTED_PTED2 // RGB LED Green cathode 36 #define FB_RGB_BLUE PTFD_PTFD1 // RGB LED Blue cathode 37 #define FB_RGB_ANODE PTGD_PTGD1 // RGB LED common anode 38 39 // Firebird32 "i/o action" macros 40 #define FB_YLED_ENABLE PTEDD_PTEDD6=1 // set yellow LED port to output 41 #define FB_YLED_DISABLE PTEDD_PTEDD6=0 // set yellow LED port to input 42 // set RGB LED Anode & Cathode port pins to be outputs 43 #define FB_RGB_ENABLE PTEDD_PTEDD3=1; PTEDD_PTEDD2=1; PTFDD_PTFDD1=1; 44 PTGDD_PTGDD1=1 45 // set RGB LED Anode & Cathode port pins to be inputs 46 #define FB_RGB_DISABLE PTEDD_PTEDD3=0; PTEDD_PTEDD2=0; PTFDD_PTFDD1=0; 47 PTGDD_PTGDD1=0 48 #define FB_RGB_ON FB_RGB_ANODE=1 49 #define FB_RGB_OFF FB_RGB_ANODE=0 50 51 #define RGB_MASK_R 4 52 #define RGB_MASK_G 2 53 #define RGB_MASK_B 1 54 #define RGB(r,g,b) ((r&0xff)<<16 | (g&0xff)<<8 | (b&0xff)) 55
7.2.5 PID.h /* 1 * pid.h: interface for PID controller 2 * 3 */ 4 5 #ifndef PID_H_ 6 #define PID_H_ 7 8 9 /* 10 * Abstraction of a PID controller as a C structure 11 */ 12 typedef struct { 13 // gain factors 14 float pGain, // proportional 15 iGain, // integral 16 dGain; // derivative 17 // allowable range of integrator state values to prevent windup 18 float iMax, // max allowed 19 iMin; // min allowed 20 // running state variables 21 float iState; // integrator state 22
44
float dState; // derivative state 23 } Spid; 24 25 26 void PID_Init(Spid *pid, float Kp, float Ki, float Kd, float iMin, float iMax); 27 28 void PID_SetGains(Spid *pid, float Kp, float Ki, float Kd); 29 30 void PID_Reset(Spid *pid); 31 32 float PID_Update(Spid *pid, float current, float desired); 33 34 #endif /* PID_H_ */ 35
7.2.6 SCI2.h
/* 1 * sci2.h: SCI driver interface header 2 * written by J.Sumey <[email protected]> 3 * 4 * This "second version" of the SCI driver performs all the same functions 5 * as the original version but additionally supports multiple SCI modules. 6 * All SCI_xxx routines accept a "port" value as the first argument; valid 7 * values are 0 thru (NUM_SCIS)-1 for invoking SCI0 thru SCI(n-1) respectively. 8 * 9 * History: 10 * 15-Mar-2010: original release 11 * 24-Mar-2011: added parity support to SCI_init() 12 */ 13 14 #ifndef _SCI_H 15 #define _SCI_H 16 17 #define NUM_SCIS 2 // number of SCI modules supported 18 19 #include "stdtypes.h" // for Byte, Word, uchar, Bool, etc. 20 21 22 /*** control & status functions ***/ 23 24 // initialize SCI with specified bus clock and baud rate 25 // parity = 'N'/'E'/'O' 26 int SCI_init(Byte port, int busClk, int baud, char parity); 27 28 // check receive buffer: 0=empty, 1=not 29 int SCI_rxCheck(Byte port); 30 31 // return number of buffered chars 32 int SCI_rxCount(Byte port); 33 34 // flush away receive buffer contents 35 int SCI_rxFlush(Byte port); 36 37 // wait for current transmission to complete 38 int SCI_txWait(Byte port); 39 40 // check for RxD idle line 41 int SCI_getIdleFlag(Byte port); 42 43 // reset idle line flag 44 void SCI_clearIdleFlag(Byte port); 45
45
46 47 /*** low-level I/O routines ***/ 48 49 // read & return a single input byte 50 int SCI_read(Byte port); 51 52 // read upto 'maxLen' input bytes or until 'endFlag' received 53 int SCI_readn(Byte port, void *ptr, int maxLen, int endFlag); 54 55 // send a single output byte 56 int SCI_write(Byte port, Byte b); 57 58 // send 'count' output bytes from given buffer 59 int SCI_writen(Byte port, void *ptr, int count); 60 61 62 /*** high-level I/O routines ***/ 63 64 // read & return a single input character 65 int SCI_getc(Byte port); 66 67 // input a line of upto 'maxLen' characters 68 char *SCI_gets(Byte port, char *s, int maxLen); 69 70 // input a line of upto 'maxLen' characters with echo & line editing features 71 char *SCI_getse(Byte port, char *s, int maxLen); 72 73 // send a single output character 74 int SCI_putc(Byte port, char c); 75 76 // send null-terminated C string 77 int SCI_puts(Byte port, char *s); 78 79 80 // macro function aliases for SCI0 81 #define SCI0_init(busclk, baud, parity) SCI_init(0, busclk, baud, parity) 82 #define SCI0_rxCheck() SCI_rxCheck(0) 83 #define SCI0_rxCount() SCI_rxCount(0) 84 #define SCI0_rxFlush() SCI_rxFlush(0) 85 #define SCI0_txWait() SCI_txWait(0) 86 #define SCI0_getIdleFlag() SCI_getIdleFlag(0) 87 #define SCI0_clearIdleFlag() SCI_clearIdleFlag(0) 88 #define SCI0_read() SCI_read(0) 89 #define SCI0_readn(ptr, maxLen, endFlag) SCI_readn(0, ptr, maxLen, endFlag) 90 #define SCI0_write(b) SCI_write(0, b) 91 #define SCI0_writen(ptr, count) SCI_writen(0, ptr, count) 92 #define SCI0_getc() SCI_getc(0) 93 #define SCI0_gets(s, maxLen) SCI_gets(0, s, maxLen) 94 #define SCI0_getse(s, maxLen) SCI_getse(0, s, maxLen) 95 #define SCI0_putc(c) SCI_putc(0, c) 96 #define SCI0_puts(s) SCI_puts(0, s) 97 98 #if NUM_SCIS > 1 99 // macro function aliases for SCI1 100 #define SCI1_init(busclk, baud, parity) SCI_init(1, busclk, baud, parity) 101 #define SCI1_rxCheck() SCI_rxCheck(1) 102 #define SCI1_rxCount() SCI_rxCount(1) 103 #define SCI1_rxFlush() SCI_rxFlush(1) 104 #define SCI1_txWait() SCI_txWait(1) 105 #define SCI1_getIdleFlag() SCI_getIdleFlag(1) 106 #define SCI1_clearIdleFlag() SCI_clearIdleFlag(1) 107 #define SCI1_read() SCI_read(1) 108
46
#define SCI1_readn(ptr, maxLen, endFlag) SCI_readn(1, ptr, maxLen, endFlag) 109 #define SCI1_write(b) SCI_write(1, b) 110 #define SCI1_writen(ptr, count) SCI_writen(1, ptr, count) 111 #define SCI1_getc() SCI_getc(1) 112 #define SCI1_gets(s, maxLen) SCI_gets(1, s, maxLen) 113 #define SCI1_getse(s, maxLen) SCI_getse(1, s, maxLen) 114 #define SCI1_putc(c) SCI_putc(1, c) 115 #define SCI1_puts(s) SCI_puts(1, s) 116 #endif 117 118 #if NUM_SCIS > 2 119 // macro function aliases for SCI2 120 #define SCI2_init(busclk, baud, parity) SCI_init(2, busclk, baud, parity) 121 #define SCI2_rxCheck() SCI_rxCheck(2) 122 #define SCI2_rxCount() SCI_rxCount(2) 123 #define SCI2_rxFlush() SCI_rxFlush(2) 124 #define SCI2_txWait() SCI_txWait(2) 125 #define SCI2_getIdleFlag() SCI_getIdleFlag(2) 126 #define SCI2_clearIdleFlag() SCI_clearIdleFlag(2) 127 #define SCI2_read() SCI_read(2) 128 #define SCI2_readn(ptr, maxLen, endFlag) SCI_readn(2, ptr, maxLen, endFlag) 129 #define SCI2_write(b) SCI_write(2, b) 130 #define SCI2_writen(ptr, count) SCI_writen(2, ptr, count) 131 #define SCI2_getc() SCI_getc(2) 132 #define SCI2_gets(s, maxLen) SCI_gets(2, s, maxLen) 133 #define SCI2_getse(s, maxLen) SCI_getse(2, s, maxLen) 134 #define SCI2_putc(c) SCI_putc(2, c) 135 #define SCI2_puts(s) SCI_puts(2, s) 136 #endif 137 138 #if NUM_SCIS > 3 139 // macro function aliases for SCI3 140 #define SCI3_init(busclk, baud, parity) SCI_init(3, busclk, baud, parity) 141 #define SCI3_rxCheck() SCI_rxCheck(3) 142 #define SCI3_rxCount() SCI_rxCount(3) 143 #define SCI3_rxFlush() SCI_rxFlush(3) 144 #define SCI3_txWait() SCI_txWait(3) 145 #define SCI3_getIdleFlag() SCI_getIdleFlag(3) 146 #define SCI3_clearIdleFlag() SCI_clearIdleFlag(3) 147 #define SCI3_read() SCI_read(3) 148 #define SCI3_readn(ptr, maxLen, endFlag) SCI_readn(3, ptr, maxLen, endFlag) 149 #define SCI3_write(b) SCI_write(3, b) 150 #define SCI3_writen(ptr, count) SCI_writen(3, ptr, count) 151 #define SCI3_getc() SCI_getc(3) 152 #define SCI3_gets(s, maxLen) SCI_gets(3, s, maxLen) 153 #define SCI3_getse(s, maxLen) SCI_getse(3, s, maxLen) 154 #define SCI3_putc(c) SCI_putc(3, c) 155 #define SCI3_puts(s) SCI_puts(3, s) 156 #endif 157 158 #if NUM_SCIS > 4 159 // macro function aliases for SCI4 160 #define SCI4_init(busclk, baud, parity) SCI_init(4, busclk, baud, parity) 161 #define SCI4_rxCheck() SCI_rxCheck(4) 162 #define SCI4_rxCount() SCI_rxCount(4) 163 #define SCI4_rxFlush() SCI_rxFlush(4) 164 #define SCI4_txWait() SCI_txWait(4) 165 #define SCI4_getIdleFlag() SCI_getIdleFlag(4) 166 #define SCI4_clearIdleFlag() SCI_clearIdleFlag(4) 167 #define SCI4_read() SCI_read(4) 168 #define SCI4_readn(ptr, maxLen, endFlag) SCI_readn(4, ptr, maxLen, endFlag) 169 #define SCI4_write(b) SCI_write(4, b) 170 #define SCI4_writen(ptr, count) SCI_writen(4, ptr, count) 171
47
#define SCI4_getc() SCI_getc(4) 172 #define SCI4_gets(s, maxLen) SCI_gets(4, s, maxLen) 173 #define SCI4_getse(s, maxLen) SCI_getse(4, s, maxLen) 174 #define SCI4_putc(c) SCI_putc(4, c) 175 #define SCI4_puts(s) SCI_puts(4, s) 176 #endif 177 178 #if NUM_SCIS > 5 179 // macro function aliases for SCI5 180 #define SCI5_init(busclk, baud, parity) SCI_init(5, busclk, baud, parity) 181 #define SCI5_rxCheck() SCI_rxCheck(5) 182 #define SCI5_rxCount() SCI_rxCount(5) 183 #define SCI5_rxFlush() SCI_rxFlush(5) 184 #define SCI5_txWait() SCI_txWait(5) 185 #define SCI5_getIdleFlag() SCI_getIdleFlag(5) 186 #define SCI5_clearIdleFlag() SCI_clearIdleFlag(5) 187 #define SCI5_read() SCI_read(5) 188 #define SCI5_readn(ptr, maxLen, endFlag) SCI_readn(5, ptr, maxLen, endFlag) 189 #define SCI5_write(b) SCI_write(5, b) 190 #define SCI5_writen(ptr, count) SCI_writen(5, ptr, count) 191 #define SCI5_getc() SCI_getc(5) 192 #define SCI5_gets(s, maxLen) SCI_gets(5, s, maxLen) 193 #define SCI5_getse(s, maxLen) SCI_getse(5, s, maxLen) 194 #define SCI5_putc(c) SCI_putc(5, c) 195 #define SCI5_puts(s) SCI_puts(5, s) 196 #endif 197 198 #endif // _SCI_H 199
7.2.7 stdtypes.h
/*****************************************************/ 1 /** 2 * @file stdtypes.h 3 * ANSI-C library: standard type typedefs 4 * defines some usefull stuff not in the 5 * official ANSI library 6 */ 7 /*---------------------------------------------------- 8 Copyright (c) Metrowerks, Basel, Switzerland 9 All rights reserved 10 Do not modify! 11 *****************************************************/ 12 13 #ifndef _H_STDTYPES_ 14 #define _H_STDTYPES_ 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 20 #if defined(__HIWARE__) 21 #define __CAN_HANDLE_LONG_LONG__ 22 /*!< We accept 'long long' types.*/ 23 #endif 24 25 typedef void (*PROC)(void); 26 /*!< Parameterless function pointer (Procedure variable) */ 27 28 #if defined(__CHAR_IS_8BIT__) 29 typedef unsigned char Byte; 30
48
typedef signed char sByte; 31 #elif defined(__SHORT_IS_8BIT__) 32 typedef unsigned short Byte; 33 typedef signed short sByte; 34 #elif defined(__INT_IS_8BIT__) 35 typedef unsigned int Byte; 36 typedef signed int sByte; 37 #elif defined(__LONG_IS_8BIT__) 38 typedef unsigned long Byte; 39 typedef signed long sByte; 40 #elif defined(__LONG_LONG_IS_8BIT__) 41 typedef unsigned long long Byte; 42 typedef signed long long sByte; 43 #else /* default */ 44 typedef unsigned char Byte; 45 typedef signed char sByte; 46 #endif 47 /*! \typedef Byte 48 Byte is a unsigned integral 8 bit type (typically unsigned char) */ 49 /*! \typedef sByte 50 sByte is a signed integral 8 bit type (typically signed char) */ 51 52 53 #if defined(__CHAR_IS_16BIT__) 54 typedef unsigned char Word; 55 typedef signed char sWord; 56 #elif defined(__SHORT_IS_16BIT__) && !defined(__INT_IS_16BIT__) 57 typedef unsigned short Word; 58 typedef signed short sWord; 59 #elif defined(__INT_IS_16BIT__) 60 typedef unsigned int Word; 61 typedef signed int sWord; 62 #elif defined(__LONG_IS_16BIT__) 63 typedef unsigned long Word; 64 typedef signed long sWord; 65 #elif defined(__LONG_LONG_IS_16BIT__) 66 typedef unsigned long long Word; 67 typedef signed long long sWord; 68 #else 69 typedef unsigned short Word; 70 typedef signed short sWord; 71 #endif 72 /*! \typedef Word 73 Word is a unsigned integral 16 bit type (typically unsigned short) */ 74 /*! \typedef sWord 75 sWord is a signed integral 16 bit type (typically signed short) */ 76 77 #if defined(__CHAR_IS_32BIT__) 78 typedef unsigned char LWord; 79 typedef signed char sLWord; 80 #elif defined(__SHORT_IS_32BIT__) 81 typedef unsigned short LWord; 82 typedef signed short sLWord; 83 #elif defined(__INT_IS_32BIT__) 84 typedef unsigned int LWord; 85 typedef signed int sLWord; 86 #elif defined(__LONG_IS_32BIT__) 87 typedef unsigned long LWord; 88 typedef signed long sLWord; 89 #elif defined(__LONG_LONG_IS_32BIT__) 90 typedef unsigned long long LWord; 91 typedef signed long long sLWord; 92 #else /* default */ 93
49
typedef unsigned long LWord; 94 typedef signed long sLWord; 95 #endif 96 /*! \typedef LWord 97 LWord is a unsigned integral 32 bit type (typically unsigned int or unsigned long) 98 */ 99 /*! \typedef sLWord 100 sLWord is a signed integral 32 bit type (typically signed int or signed long) */ 101 102 typedef unsigned char uchar; 103 /*!< Definition for an unsigned char.*/ 104 typedef unsigned int uint; 105 /*!< Definition for an unsigned int.*/ 106 typedef unsigned long ulong; 107 /*!< Definition for an unsigned long.*/ 108 #ifdef __CAN_HANDLE_LONG_LONG__ 109 typedef unsigned long long ullong; 110 /*!< Definition for an unsigned long long.*/ 111 #endif 112 113 typedef signed char schar; 114 /*!< Definition for an signed char.*/ 115 typedef signed int sint; 116 /*!< Definition for an signed int.*/ 117 typedef signed long slong; 118 /*!< Definition for an signed long.*/ 119 #ifdef __CAN_HANDLE_LONG_LONG__ 120 typedef signed long long sllong; 121 /*!< Definition for an signed long long.*/ 122 #endif 123 124 /** Defines the enum_t type.*/ 125 #if defined(__ENUM_IS_8BIT__) 126 #if defined(__ENUM_IS_UNSIGNED__) 127 typedef Byte enum_t; 128 #elif defined(__ENUM_IS_SIGNED__) 129 typedef sByte enum_t; 130 #else 131 #error "illegal sign of enum" 132 #endif 133 #elif defined(__ENUM_IS_16BIT__) 134 #if defined(__ENUM_IS_UNSIGNED__) 135 typedef Word enum_t; 136 #elif defined(__ENUM_IS_SIGNED__) 137 typedef sWord enum_t; 138 #else 139 #error "illegal sign of enum" 140 #endif 141 #elif defined(__ENUM_IS_32BIT__) 142 #if defined(__ENUM_IS_UNSIGNED__) 143 typedef LWord enum_t; 144 #elif defined(__ENUM_IS_SIGNED__) 145 typedef sLWord enum_t; 146 #else 147 #error "illegal sign of enum" 148 #endif 149 #else /* default */ 150 typedef sWord enum_t; 151 #endif 152 153 typedef int Bool; 154 /*!< Definition for boolean type.*/ 155 #ifdef __MISRA__ /* MISRA rule #18 */ 156
50
#define TRUE 1u 157 /*!< Definitioni for TRUE.*/ 158 #define FALSE 0u 159 /*!< Definition for FALSE.*/ 160 #else 161 #define TRUE 1 162 /*!< Definitioni for TRUE.*/ 163 #define FALSE 0 164 /*!< Definition for FALSE.*/ 165 #endif 166 167 #ifdef __cplusplus 168 } 169 #endif 170 171 #endif 172 /*****************************************************/ 173 /* end stdtypes.h */ 174
51
8 Appendix C: Contribution Documents
Matthew K Bonaddio ·· 13 Bam ford Street
Monon gahel a, PA
15063
May2,2014
Professor Sumey:
As the software specialist, I was responsible for the design and implementation ofthe source code.Troubleshooting the software was my responsibility along with having an overall view of the software to handle the task.Throughout the project, I was troubleshooting each feature to verity proper operation of the software.Some commented out HEARTBEAT statements are viewable where they were placed.Some were removed in the last code cleanup.I was responsible for the code development throughout the project.The software revision history was my responsibility and any major software changes were made with my approval.Most
documentation such as flow-charts and software design elements were my tasks.
There were many times throughout the course, where I felt that I achieved in great ways.During the project we seemed to have large setbacks and it seemed at times we were falling far behind.In the end, I feel I put forth the effort to make up for the lost time and nearly complete all aspects of the software side of the project.Throughout the hardware failures and many hours lost.to simple bug fixes, we were able to get most of the system running in good fashion.The project was successful as it showed all of us how much time and work it does take to get a system fully functiona l even given all the individual.parts are working.
Now that the competition is over, it is quite clear on some of the areas I could have improved
upon.One area of improvement would concern reading the lab materials carefully.Another area I may have been able to improve upon would be the proper handling of code updates and documenting when and why specific changes were made.Another issue of concern, was my own confidence in the software.Given some time to explain some of the current issues, we would have come to a great solution for the SmartCar.Also, I wish-1 would have stayed with the conventions provided in the provided lab source code.
One issue I encountered, was our confidence in the software.Given another good lab period with the
team members would have helped us in the end.The code maintenance and performance were my responsibility, and I wish I would have been more persistent about leaving the code in its working condition before allowing attempts at last minute improvements.In our pre and post demonstration trials, the car was operating in a manner to complete 5 laps safely.With only a few minutes remainiii.g before the trial, I insisted that we leave the code and max speed settings where they were set and run the first trial with.the tested software.Withottt a full-trial I was unsure of the last-minute changes that were made.It seemed the problem was the most recent change where we decreased the "tach timeout" value to 50mS.When the car got up to speed (above 50mS tach pulses) the car reverts to 0 speed since the timeout set the speed to 0 sending the car to max speed.Another bug was found in the fmal run code where we had added a statement to deal with the motor if the speed was zero.It was also a problem in the end which would prevent our car from mnning properly.Afte r the trials I located and loaded the correct firmware and the car ran as expected.
In the end I would have to say this was one of the most challenging projects to date.From an
outsider's perspective, this project would seem quite simple.To anyone involved in the project this is a large-
52
scale problem which we had to solve.Controlling all the connected peripherais in reaT-time is like jhggling b.\.lt in code.I would have to say, I gained much experience in this class and I would recommend tl;tis class toanyone who is up to the challenge.Thank you for your time and efforts with the class.
Sincerely,
Matthew K Bonaddio Electrical Engineering Technology CET-360 Fall2014
53
To: Professor Sumey
From: Michael W.Bichsel
Date: 2 May 2014
Subject: Smart Car Participation
My name is Michael Bichsel.I was chosen to be the software assistant for team Kickin’ Asphalt to
complete this year’s CET 360 term project.The goal of the project was to complete a working SmartCar
that could follow a line around a track, autonomously.Our engineering team was divided into specific
roles that defined what each person would be responsible for contributing.My role as software assistant
was to aid in the development of programming solutions for the project.
The SmartCar problem was to be solved by building an embedded system, which entailed both
hardware and software solutions.My job as software assistant was to design, implement, and improve the
algorithms and codes that we used to we program the SmartCar.From week to week, our lab group was
assigned various laboratory assignments that required us to design and install various features into the
car.We used a top-down approach to engineering, so we had to start with higher-level solutions to be sure
that our logic and approach was sound before moving forward.
Every week we were presented the ground work for an additional SmartCar feature.This meant
that the high-level design was presented in a way that could be translated into our final C-code
implementation.Matt Bonnadio (our software expert) and I worked together to take the high-level designs
we were given, and translate them into source code to put the car in working order.This transition from
high-level to detailed design required that I put my resourcefulness into action.This is where I contributed
the most.I was in charge of delving into the MCU specifics.This meant looking through reference
manuals and devising ways to initialize the features that we intended to use.I went through the
“Everything but the kitchen sink” manual on a daily basis to find status control registers, to explore how
to use its many features, and explain how to connect the software we were coding with the hardware.This
enabled our team to create detailed designs that worked, and could be used in the final product.
Debugging was another issue that I was consistently involved with.Matt was our software expert,
so he was usually the one writing the final code.This is a difficult task for one person to take on, so I was
always there to be his second pair of eyes.I helped him every day by offering my advice, and making sure
his logic was correct.This made our jobs, as software experts, much easier.Debugging and
troubleshooting went much smoother.If something wouldn’t compile, or wasn’t quite working, we always
had two eyes on the prize, and cut our down time in half.
My contributions we not limited to the software side of the project.There were many times when
we had issues with the hardware.When features weren’t quite working, I helped the team by looking into
the on-board circuit and making sure everything was wired correctly.I looked through datasheets for the
components we were using and found various problems that others in my team had missed.Being an
assistant for the team meant that I was not limited to simple staring at code.I was always in the action, and
helping our team move forward in any way that I could.
54
As for the final project report, I wrote and revised the introduction to the SmartCar project.I
explained to the reader exactly what our project was about, and how we progressively created a final
solution.I also wrote the project evaluation portion of our report.This required me to compare how our
projected timeline matched up to what actually took place.I also put together the screenshots that
explained the length of time that it took for various features to compete, such as the battery voltage
readings.I looked into how much flash and RAM was used, and how that compared to what was available.
During the semester, I learned how an engineering team differs from a study group.With the
engineering team build we used for this project, each member had specific responsibilities.The software
and hardware sides were constantly integrated, requiring the team member to communicate efficiently and
respectfully.As software assistant, it was nearly impossible for me to overrule a decision that the software
expert made.So, when Matt had the problem covered, I found other ways to make myself useful.I worked
with the hardware team, or documented our progress as we moved forwards.I learned that just because I
am a assigned a specific job, does not mean that I am limited to only being an assistant.I learned about the
importance of documentation.I found that having everyone’s participation is the key to solving problems
quickly and correctly.
Overall, I feel that I did my part to help build our SmartCar.But, if I could do it all over again, I
would never choose to be the software assistant.It was a frustrating experience because I felt that I had
very little say over what code we actually used.I always did my best to provide guidance and suggestions
to how our car could be improved.But, as the software assistant, my input was mainly disregarded.This
resulted in a car that didn’t finish the race.The role titles seemed to be taken too seriously, and this
resulted in an unbalanced team.On a lighter note, it was a fun project and I’m glad to have done my part.
Michael W Bichsel _______________________________________
55
To: Professor Sumey
From: John Donofrio
Date: May 1, 2014
Subject: Smart Car Participation
I was selected to the position of team hardware assistant at the beginning of the spring 2014
semester.Being that my software skills are lacking this was one of the best positions for me.My main
responsibility was to help Jordan with the hardware, but I had to be ready for anything.Another
responsibility I decided to take on was to be the car’s mechanic.I attached parts and tried to keep it in
working order.There was many times where I was called upon to help troubleshoot problems that we had
with the car.When there were no problems or no papers to write it was usually just getting parts together,
making sure the battery was charged, or other random tasks that were asked of me.
I was not responsible for writing any of the code, but I was constantly kept updated so that the
team was in sync.Communication was one of the biggest parts of this project.Jordan and I had to
constantly make sure that we were on the same page as Matt and Mike.Any time one of us finished
anything we were double checking with each other and trying to not screw anything up.There was a few
times where we came in after class, and many times where we stayed late in the lab.All that
communication and extra effort was the reason we had any measure of success on race day.
Despite our best efforts we did not perform as well as we wanted.We had quite a few problems
with components and parts all throughout the semester.The biggest problem with our hardware was that
our breadboard was coming up off the car body.This made it very hard to troubleshoot any problems with
the circuit because some parts were pushing down through the board and losing connection.Another
major problem was when our switch died on us.Once all the broken components were repaired or
replaced the car ran exceptionally.
One of my busiest times was whenever any of the phases were assigned.While working on phase
one I was responsible for part four, system integration and testing.Phase two was a little bit more involved
since we had a report and a presentation to do.I was responsible for the mechanics and the constraints
portions of that.I had to attach the speed sensor and I had to take measurements of the wheel and gear.I
used those measurements to get the distance traveled by the car, which was later used to find
speed.Another contribution I made for phase two was that I was the one who took the pictures we put on
the power point.For phase three of the project all I had to do was to help Jordan with the schematic.Then
for phase five I typed the project introduction and project description.
Throughout this project I felt like I was learning a lot.It has been a few years since I took
technical writing so I am very glad I could brush up on that.Also, building team skills and communication
56
skills are always a good thing, which I felt like I did throughout the semester.Whether we were
troubleshooting or implementing more parts, I tried to take as much as I could and learn from it.The class
may have been dull at times, but there was always something to do in lab.I may not have been the most
valuable person on the team, but I tried my best to contribute wherever I could.
John Donofrio _________________________________________________________________
57
To: Professor Sumey, Course Instructor
From: Ryan Dempsey, Team Leader
Date: May 2, 2014
Subject: Project Contribution
Professor Sumey,
During the Spring 2014 semester here at California University of Pennsylvania, I was the team
leader of team Kicking Asphalt for our SmartCar project.As the team leader, I had to oversee the
hardware and software development of the project.I worked closely with every member of the group to
make sure all deadlines and tasks were being completed correctly and efficiently .From the hardware
side of things, I help check the cars wiring and construction, as well as trouble shoot problems when
they were raised.From the software side, I helped implement code that would effectively accomplish
each task of the SmartCar.I brainstormed solutions to bugs in our program as well as software to
hardware issues.I was also responsible for compiling the written assignments for this semester.Everyone
helped out with these assignments, but I received the information required, made sure it was done on
time, and compiled and read through the finished reports.
The biggest hardware problem we had this semester was our bread boards getting worn out.Our
wires and pins began poking through the bread boards because of the way it was attached to the
car.This resulted in rewiring the whole circuit twice.Software issues were minimal until the end of the
project, when we needed everything to work in tandem.I helped the software guys brainstorm ideas on
what to change to see improved results.
As team leader, I tried to take a more hands off approach for two reasons.The first being we had
a large team of five individuals.This made it tough for three people to all work on the same task.The
second reason is because I believed our team was very competent in the areas that were assigned to
each individual.As team leader, I did not want to be controlling of the project and take over everyone
else job.I encourage software and hardware sides to work together and come to me with issues or
questions.Looking back on this, I think I could have improved by being more involved with the hardware
side of things, and reading over the code more often to improve my ove rall understanding of its
workings.
For the final report, I compiled the report together after I received typed sections from
individual team members.I also typed up the project journal, parts of the evaluation, parts of the
project introduction, as well as proof reading and formatting of the document.
A benefit of being team leader was working on both sides of the project.I learned new code
techniques such as pointers, #ifdefs, implementing structures, typing up title blocks and correct
comments through our the document, and about vector interrupt service routines.From the hardware
side of things, I gained knowledge and competence on large wiring systems, schematics, troubleshooting
58
wiring, using capacitors to reduce noise, soldering techniques, and modules used on the FireBird32 32
MCU.
As a team, I am very pleased with our effort and determination for completing this project .Matt
Bonaddio worked tirelessly on getting the code working for this project.He worked on it during off hours
and came in to lab for extended periods of time to work with the car on the track.Mike Bichsel was a great
asset to Matt and was by his side whenever he was needed.Mike did a great job when it came to our
project presentation with speed sensing.The hardware guys Jordan Severo and John Donofrio both
worked hand in hand to make sure we had the best hardware possible for our car.they did a great job
wiring the car and handling the hardware issues we were handed.I was also very happy with the effort
everyone gave for writing the reports, doing the diagrams, and meeting in off hours.All in all, I was happy
with the work our group put into the project, and I think we deserved a better result than we presented on
race day.
Ryan Dempsey ____________________________________________________________________
59
TO: Jeff Sumey, Course Instructor
FROM: Jordan Severo, Hardware Specialist
DATE: May 1, 2014
Subject: Project Contribution
Professor Sumey,
I am a member of team Kicking Asphalt in this year’s smartcar project. It was a group effort in the development of the project and everyone put in their fair share of work .As the hardware specialist I was responsible for all of the components and the high and low level design of the hardware side of the project. It was my responsibility to maintain communication with our team via email and to also show up to every lab and class. I also met with the rest of the group anytime I could when they had meetings outside of lab time .Even though I’m the hardware specialist it was very important to review the code as it
was updated from the software specialist.
At the start of the lab a component box was presented to me with bare smartcar body. As the labs progressed I had to asses and learn all the specifications for each individual part and add them to the circuit. The components include the Firebird32 module, steering servo, photointerrupter, motor driver, XBee, and the Pololu sensor array .Many other components were also used to give us a finished product.In Phase II of the project I gained knowledge on the GP1A75 OPIC Photointerrupter. With my group I compiled information on hardware that I wanted to include in our PowerPoint presentation. Some of the information I provided included, the block diagram, specifications, wiring diagram, filtering suggestions, and pictures. I had the responsibility of practicing my part of the presentation to ensure the information was properly delivered to the class .For Phase III of the project I built a schematic that was up to date, and received some feedback on how I can improve it which I later implemented in to Phase V of the project. During Phase V I compiled all of my references for the hardware report of the document.I then wrote descriptions on the parts and sent them to Ryan for review. I also completed a well-organized finalized schematic and emailed it along with my list of references to the group for review. I also helped by turning in my lab journal for the timeline.
During the project I ran into a couple of road bumps and had to implement my knowledge of troubleshooting to come up with a solution. During the construction of the power distribution part of the circuit where we were using the regulators, we were getting a short somewhere and improper voltage levels were being read. I was able to narrow it down to the 3.3V regulator and by referencing to manual discovered that I had it hooked into the circuit backwards. The biggest problem in our project that took a lot of time on my end was our bread board mounted to the top platform on the car. It was rising and causing some of the pins to push through when we added components to the circuit. I had to reconstruct the circuit onto a new breadboard that was provided. This enabled me to reorganize the circuit and make
it much neater and easier to follow.
This project taught me a lot and I’m definitely walking away from it with a lot of knowledge . I learned how to coordinate and work as a team to produce a finalized product. Working as a team is a valuable skill to have when it comes to the real world. I also gained important knowledge on troubleshooting and testing skills. This was also my first time using Multisim to build a complete schematic, which I feel is a very valuable skill to have, especially being an EET major. Phase II taught me some presentation skills that can be useful in almost any field out there. Being able to present your material with confidence and good flow is always important because your work is nothing if you can’t present it in a professional way. The most valuable thing I learned was the relationship between hardware and software and how each
60
contributes to a completed product. I’ve never been too much of a fan of software before this, but definitely have a new found respect for it and how truly powerful it is. CET 360 and the smartcar project have been very valuable in my undergrad studies and have given me important knowledge that I can
implement for the rest of career.
Sincerely,
Jordan Severo