cet360smartcar

65
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

Upload: jordan-severo

Post on 17-Jul-2015

73 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: CET360smartcar

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

Page 2: CET360smartcar

Instructor Comments

Page 3: CET360smartcar

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

Page 4: CET360smartcar

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

Page 5: CET360smartcar

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

Page 6: CET360smartcar

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.

Page 7: CET360smartcar

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

Page 8: CET360smartcar

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

Page 9: CET360smartcar

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

Page 10: CET360smartcar

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

Page 11: CET360smartcar

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

Page 12: CET360smartcar

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

Page 13: CET360smartcar

8

Figure 9: Firebird32 Block Diagram

Page 14: CET360smartcar

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

Page 15: CET360smartcar

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.

Page 16: CET360smartcar

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

Page 17: CET360smartcar

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

Page 18: CET360smartcar

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

Page 19: CET360smartcar

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

Page 20: CET360smartcar

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.

Page 21: CET360smartcar

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.

Page 22: CET360smartcar

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

Page 23: CET360smartcar

18

Figure 20: Call Graph

Page 24: CET360smartcar

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.

Page 25: CET360smartcar

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

Page 26: CET360smartcar

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.

Page 27: CET360smartcar

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.

Page 28: CET360smartcar

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.

Page 29: CET360smartcar

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

Page 30: CET360smartcar

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

Page 31: CET360smartcar

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

Page 32: CET360smartcar

27

6 Appendix A: Schematic

Page 33: CET360smartcar

28

Page 34: CET360smartcar

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

Page 35: CET360smartcar

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

Page 36: CET360smartcar

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

Page 37: CET360smartcar

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

Page 38: CET360smartcar

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

Page 39: CET360smartcar

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

Page 40: CET360smartcar

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

Page 41: CET360smartcar

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

Page 42: CET360smartcar

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

Page 43: CET360smartcar

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

Page 44: CET360smartcar

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

Page 45: CET360smartcar

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

Page 46: CET360smartcar

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

Page 47: CET360smartcar

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

Page 48: CET360smartcar

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

Page 49: CET360smartcar

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

Page 50: CET360smartcar

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

Page 51: CET360smartcar

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

Page 52: CET360smartcar

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

Page 53: CET360smartcar

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

Page 54: CET360smartcar

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

Page 55: CET360smartcar

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

Page 56: CET360smartcar

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-

Page 57: CET360smartcar

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

Page 58: CET360smartcar

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.

Page 59: CET360smartcar

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 _______________________________________

Page 60: CET360smartcar

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

Page 61: CET360smartcar

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 _________________________________________________________________

Page 62: CET360smartcar

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

Page 63: CET360smartcar

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 ____________________________________________________________________

Page 64: CET360smartcar

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

Page 65: CET360smartcar

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