1
ABSTRACT
Published BY:
Name: Iman Yossi Torbati
Name: Alex Ming-Fan Lag
Name: Arya Ahmadi
2
The focus of this report is to construct a small Robot (Micromouse) that has memory and
is capable of navigating through the Standard Maze specified by the guidelines of the
IEEE International competition with the exception for the size of the maze. The
Micromice are judged by the time it takes them to find the center. As a result, the Robot
that makes the fastest timed run from the start to the center of the maze is declared the
winner of the competition.
3
Introduction Page 4
History Page 5
Major Constraints Page 8
Rules Page 10
Design Approach Pages 13-50 • Component Diagnostics and Results Page 13
• System Schematic and Design Page 45
• Mechanical Schematic and Design Page 48
• Maze Solving design approach Page 50
System Diagnostics, Layout and Results Page 61
Microcontroller Selection and Programming Page 63
Area of Improvement Page 98
Conclusion Page 101
References Page 102
Appendices Pages 103-160
INTRODUCTION
4
A "Micro-Tank" or a type of “Micro-Mouse” is a fully autonomous robot
designed to navigate and solve an arbitrary maze in the shortest period of time. To
achieve our goal, we will identify, analyze and test each component of the Robot to
assure sub-system functionality. Next, we will generate a design schematic and assemble
all the components together for the system level testing. Our Core objective in the end is
to create a non-memoryless system that is capable of traveling through the Maze in the
shortest period of time without drifting or hitting the side walls of the maze.
The “Micro-Tank” encompasses a vast range of engineering fields which can be divided
into Hardware and Software categories. The hardware consists of power subsystem,
control system and sensory system for navigation. Each of these parts in our project
underwent a through process of design, analysis and component selection. The software
portion of our design implements various algorithms such as wall following, depth-first
search, flood filled algorithm as well as modified flood-fill algorithm to solve the maze.
Our design uses the combination of depth-first algorithm and the newly proposed
algorithm by one of the members of our group. We in detail describe each of these
algorithms and the method we have chosen to for programming our Micro-Tank.
We selected this particular project to perform system level design and testing. This way,
we are able to become familiar with a broad range of information related to Engineering
rather than focusing on one particular area. For example, the project requires electrical
engineers to design the hardware section of our micro-tank, computer engineers to write
the algorithm and communicate with the components of our system, and mechanical
engineers to design and build the chassis and cause the mouse to make turns. By
5
focusing on all these areas, were able to gain lots of experience in other fields. To
proceed to farther details, it is also important to describe the significance of this project
which relates to applications and advantages for the research in the field of Robotics.
After all, research in the filed of robotics has a far-reaching social implications, including
advancements in biomedical engineering (as in Miniature Robots used to perform
surgery), automation of tasks unsuitable for human beings, rescue options, domestic
applications and more.
HISTORY
A: History of the Maze
For thousands of years in our history, the concept of mazes and labyrinths has intrigued
diverse cultures from around the world. A venture into the unknown, traveling the maze
symbolizes mankind’s own quest for truth or spiritual discovery.
Unlike the modern notion of maze enclosing numerous false passages and dead ends, the
ancient labyrinth usually featured a winding universal design with only a single entrance
and exit (1). Perhaps the most familiar story associated with the labyrinth is the Greek
Myth of Theseus and Minotaur.
The design of the Cretan Labyrinth, preserved on Cretan Coins of the 1st century BC has
been encountered in various other places in the world. The Cretan labyrinth is also found
on rock cravings in Spain, on an Etruscan wine jug from Italy, on a roof tile from the
Greek Parthenon, etc (2)
6
Maze designs flourished in various parts of Europe and Asia for many centuries. For
example, in Scandinavia, over 600 stone labyrinths line the shores of the Baltic Sea.
Religions such as Judaism, Sufism, Buddhism, and Taoism used symbols of mazes for
marriage fertility, birth, funeral, exorcism, wind control, healing, protective ritual, or even
as patterns to play games (3) Thus the mystery surrounding mazes make an indelible
mark upon many different areas of cultures. Today, in mathematics, finding the best path
is known as critical path analysis or CPA. Computer programs that perform critical path
analysis are called autorouters. Autorouters help to reduce the size and cost of electronics
and have been a major factor in development of today’s advanced information technology
(3). As a result, many algorithms for solving mazes have been evolved throughout the
years.
B: History of the Mouse
The micromouse competition has been running for over 25 years and is popular in the
UK, USA, Japan, Singapore, Taiwan, Hong Kong, Australia and elsewhere. To challenge
Engineers, the “maze solving” contest was designed as a way of competition. In 1977,
IEEE Spectrum magazine introduced the concept of micromouse and the amazing
micromouse competition which would be held in 1979 in New York. This competition
involved mices finding their way out of 10 by 10 mazes.
In 1980, Professor John Billlinsley, of Portsmouth Polytechnic, modified the rules and
introduced the first European competition-held in London at Euromicro. The rule
changes required the mice to find a goal in the center of the maze and wall followers
could be prevented from finding the goal. There were 200 enquiries and 100 entries, but
7
only 9 mice at the finals. Nick Smith’s Sterling Mouse became the first ever (and that
year the only) micromouse to find the center and know it had done so. Although
performance was less than stunning at about 0.18m/s, it was and still is a remarkable feat.
In 1985, the ‘First World Micromouse Competition’ was held in Tsukuba, Japan. Mazes
were sent to a number of countries around the world in order to encourage entries. A wide
range of mice from all over the world competed. The world champion was Noriko-1 from
Japan. The top six places were taken by Japanese entries. Seventh was Dave Woodfield
from England with Enterprise. In 1986, the US had its first competition, held in Atlantic
City, organized by the IEE (Institution of Electrical Engineers). Dave Otten of MIT had
his first competition entry with Mitee Mouse I. Unfortunately it came last. (4)
Today, various simpler versions of the contest have been created for schools and the
under 18’s. At certain schools, contestants must be an undergraduate IEEE student
member at a Region 6 school from within the Area of Region 6 in which contest they will
compete at the time of entry in the MicroMouse contest. Any student who graduates
anytime during the Fall-Spring academic year in which the contest is held is eligible to
enter the contest. (5)
8
MAJOR CONSTRAINTS
The design of our Micro-Tank is subjected to several constraints. We will explain some
of these constraints in detail.
A: Economical Constraints
One of the constraints we have to deal with in our project relates to the cost. We have to
design our mouse based on the fact that the total bill of the material must be below $500.
Being the students that are studying at UCI, we also have a budget limit of spending from
our own expense which cannot exceed $500 dollar. Such a constraint would deter us
from making a great Micro-mouse design that can win the IEEE competition. We have
ordered the parts for our Micro-tank considering our own budget limitation as well as the
IEEE rule for the budgeting limitation. The parts that we have purchased are not as good
as the more expensive parts that other competitors may use. As an example, we could
have purchase a DC motor that has a built in encoder and the fastest speed. But we had
to trade off such a great DC motor with its cost which was extremely expensive motor.
Indeed, in our project, we had to make lots of trade off associated with having the top of
the line parts compared to a part that is used by many Engineers who design the Micro-
mouse. In this way, we have decided to order parts that are not very expensive and
9
scarified the performance of our Micro-tank for it. The purchase of our Microcontroller
would be another example that can be discussed. We were initially looking to purchase a
Zbasic microcontroller in which many Engineers use for the construction of their Micro-
mouse. However, due to having small memory storage as well as a large cost, we have
decided to choose AVR Butterfly for the control of our Robot. The AVR butterfly on the
other hand, even though cheap with lots of storage, has given us lots of problems and
difficulties for our design. Our project could have been better and easier to make if we
have chosen the Z-basic Microcontroller. We have overcome such challenges for the
economic constraints we have encountered and we will always remember to incorporate
such constraint in our future design when making a product for consumers. Figure below
shows the cost for this project:
System CostsDescription Quantity Purpose Price/Unit Total PriceAVR Butterfly 1 Microcontroller $21.28 $21.28
L293D 2 Motor Driver $3.17 $6.34MC7805ECTBU 2 Regulator $0.37 $0.74
TSL261R-LF 6 Photoresistor $2.52 $15.12SN754410NE 2 Motor Driver $1.87 $3.74
TSAL6100 6 IR LED $0.21 $1.26GP2Y0D340K 6 Sharp Distance Sensors $6.42 $38.52
All Shipping Costs 1 All Shipping Costs $50.00 $50.00Chasis and Motors 1 Chasis and Motors $40.00 $40.00
Miselinious 1 Resistors, Caps, wires, etc $100.00 $100.00Tools and Breadboard 1 Tools and Boards $25.00 $25.00
Plexiglas 1 Chasis design $4.00 $4.00Maze Equipment 1 Construct Maze $30.00 $30.00
Total Costs $336.00
B: Environmental Constraint
The environment in which the Micromouse will need to function is a maze compromised
of a 16 by 16 cm array. In other words, Our Micro-tank must be small enough to fit
10
within the maze cell that has the 16 by 16 cm dimension. Even though we have violated
this rule due to selecting a tank for our design project, we still have constraint for size
which is very important when our tank is going to make a turn. In addition to the maze
environmental constraint, we have another environmental constraint in which the robot
cannot cause any damages to the maze or leave behind any debris in its path. As a result,
the engineer must think of a way to make such an environment suitable. For this project,
we have changed the rules of the maze (size is changed to 40cm by 40 cm array) simply
due to time and economical constraints. By doing so, we were able to overcome the
environmental constraint in a way. However, such an issue will be a challenge for our
future work in designing smaller autonomous devices.
There is also another environmental constraint to illustrate and that is related to
Reduction of Hazardous Substances. Our micro-tank uses components that are made up
of reduction of hazardous substances. According to Wikipedia, RoHS is a new European
environmental directive being adopted in America which includes the banning of lead,
Mercury, Cadmium, Hexavalent Chromium, PBB, and PBDE from all computer
electronics (6). The safety of the environment is a major factor for any engineer to
consider while designing as it is the case for our team.
RULES
A: MicroTank
• A MicroMouse shall be self-contained (no remote controls).
11
• A MicroMouse shall not leave any part of its body behind while going through the
maze.
• A MicroMouse shall not jump over, fly over, climb, scratch, cut, burn, mark,
damage, or destroy the walls of the maze.
• The dimensions of a MicroMouse that changes its geometry during a run shall not
be greater than 25 cm x 25 cm. there are no restrictions on the height of a
MicroMouse.
• Any violation of these rules will constitute immediate disqualification from the
contest and ineligibility for the associated prizes.
B: Maze
• The maze is composed of multiples of an 18 cm x 18 cm unit square. The maze
comprises 16 x 16 (38 x 38 in our case) unit squares. The walls of the maze are 5
cm high and 1.2 cm thick.
• The slides of the maze walls are white, the tops of the walls are red, and the floor
is black. The maze is made of wood, finished with non-glass paint.
• Multiple paths to the destination square are allowed and are to be expected.
C: Contest:
12
• Each contesting MicroMouse is allocated a total of 10 minutes of access to the
maze from the moment the contest administrator acknowledges the contestant(s)
and grants access to the maze.
• Any time used to adjust a mouse between runs is included in the 10 minutes.
• Each run (from the start cell to the center zone) in which a mouse successfully
reaches the destination square is given a run time.
• The minimum run time shall be the mouse’s official time.
• Changing ROMs or downloading programs is NOT allowed once the maze is
revealed.
DESIGN APPROACH
Our design approach is a simple classical control system block diagram. Consider the
figure below:
13
The sensory subsystem will sense the incoming walls or the side walls as well as the
positioning of the Micro-Tank and sends a signal to the Microcontroller. The
Microcontroller then processes the incoming signal and output signal to the Motor Driver.
The motor driver will then turn on the motors according to the logic received from the
Microcontroller. The power subsystem will power up all the subcomponents of the
Micro-Tank. This block diagram is the basis of the Negative Feedback. It is important to
note that in our design we did not include an encoder as power of our sensory subsystem
due having a different design implementation and time limitation we have had. As a
result, our circuit is a close look system only with the side sensors as well as the middle
sensors. The microcontroller is the sensory system will assist in controlling the Micro-
tank to navigate in a straight line as well as detects any incoming holes o walls in the
maze. Below, we will describe the functionality of each component and state our results.
A: Component Diagnostics and Results
14
1. Center LED/Sensors:
Sensors are the main part of the micromouse that detects the distance from the walls and
communicate with the microcontroller. In other words, sensors give robots the mean to
perceive its environment and the robot will processes the information received from its
sensors and reacts in a predetermined manner according to the design of control system
we have shown above. Our Micro-tank is required to detect the surrounding walls, dead
ends and two way openings as well as keep itself aligned in the center. In fact, the main
purpose of the Center LED Sensors is to keep the mouse navigating in a straight path. In
selecting the type of sensors that keeps our Mouse in a straight path, we were introduced
to many types of sensors such as IR Sensors, Ultrasonic or sonar sensors, touch or bump
sensors, reflective sensors, side looking sensors, differential sensors, and top down
sensors.
Reflective Sensors
Many Engineers use the reflective sensors for the design of their Micromouse simply
because they are relatively easy to build and the parts are easy to come by (7). Some of
the examples of these groups of sensors include the IR sensor which can be used to
measure the distance and positioning from the side-walls. A major problem with any
reflective sensor is that the nature of surface can have a large effect on the size of the
reflected signal (4). Another major problem with these types of sensors is that at some
point the signal can be non-linear due to effect of light spreading out from the emitter.
This problem is also known as Radar equation and can be solved by using a non-linear
Amplifier in the circuit. The second problem with these types of sensors is that the level
15
of reflected light is dependent upon the reflected angle. This problem becomes worsen as
more light is reflected in a shiner surface. In relation to math, this problem is called the
Cosine law.
Side-looking wall sensors
A side looking wall sensor returns an analog value that carries information related to the
distance from the walls in a form of voltages. This type of sensor is used in robotics
applications often but it has its own disadvantage as well. One of the issues with this
type of sensor is that variation in wall reflectivity from wall to wall or cell to cell can
make getting the results a bit more difficult. Such variations require auto-calibration
which must happen when the mouse is running.
Top Down Sensors
Top Down sensors also work as a result of reflecting a light from the walls, but these
sensors are used to detect the top section of the walls and output the digital signals to the
Microcontroller. These types of sensors can have a huge advantage in that they are
able to detect walls in adjacent cells.
In addition to gaining knowledge related to the kinds of the sensors described, we have
performed some research related to different groups of sensors namely proximity sensors,
flex sensors and distance sensors. According to our research, proximity and flex sensors
are used to keep the Micromouse centered within the cell and for environmental mapping
in adjacent cells while distance sensors are mainly used to detect the length of the path in
front and to the sides of the Micromouse. In some cases, we can use the IR distance
sensors as proximity sensors which can give us the analog value of voltages from the side
16
walls positioning our Micro-tank centered in the maze. After conducting our research
and considering our economical constraints, we have decided to select the Infrared Light-
emitting diode and photo-resistor sensors which are a type of reflectivity sensors that can
give us the reading distance from the walls in a form of analog voltages. The type of the
LED we have selected is the high power infrared emitting diode with the wavelength of
950 nm made from GaAlAs/GaAs (TSAL6100). Figure below shows the picture of our
IR LED, TSAL6100.
If we place this LED next to an object or a barrier that has a reflective white color, we
will see that the strength of the signal detected or the irradiance is dependent upon the
distance of the receiver (the white barrier). As a result, the closer the LED is to the
receiver, the higher the strength of the signal is at the sensor and vise versa. Figure below
shows this relationship in detail:
17
When connecting the LED in a circuit, we must consider adding a resistor in series with it
to reduce the current and hence any damage to the LED. The resistance we have
calculated to add to this circuit is 100 ohm with an input voltage supply of 5V as shown
in the figure below:
Using the KVL, we are able to calculate the current passing through the diode with our
knowledge of the turn on voltage for the diode specified in the data sheet of this product
and compare it to our measured calculation. We have done this and it is an approximate
matching results. It is also important to note that based on our schematic, the forward
current usage of the LED at maximum for certain period of time is 200 mA. Our results
for the LED are shown below:
IR LED MeasurementMeasured Diode Voltage (V) 1.23
Measured Current (A) 4.86E-02Measured Resistance (Ohm) 25.30864198
It is also important to note that in order to reduce the signal interference to other sensors
we have covered the side hemispherical window of the LED with the electric tape.
Interference occurs when light reflected from the walls with the wide range will bounce
18
off into other sensors resulting to an output with incorrect information. As a result, we
are not able to detect the location and distance from the walls and the mouse may hit the
walls at some point. This was a problem we have encountered when initially tested out
Micro-tank and after covering the LEDs with tape part of our problem was resolved.
Figure below shows the view for positioning our IR Center sensors in our Micro-Tank:
The Photo resistor that we have selected is of the type TSL262R Infrared light-to-voltage
optical sensors as shown in figure below:
19
Due to having high irradiance responsively at the wavelength of 940 nm and a linear
correspondence with the output voltage, these photo resistors are designed to detect
signals clearer with reduction in noise and a full output voltage. Figure below shows the
structure design of this sensor in details:
As shown on the figure above, the sensor is comprised of a photodiode and an amplifier.
The LED will send IR light to the sensor and the sensor will detect the signal and gives
an output voltage that is very weak. The weak voltage will then pass through an
amplifier and picks up a gain that is about 2.9 Volt. The higher the intensity of light, the
higher voltage we are able to read from the voltmeter. The figure below shows the graph
of irradiance vs. output voltage for our photoresistor:
20
As shown from the figure above, there is a direction linear relationship between the
irradiance and the output voltage we receive from the sensor. The higher the radiation,
the higher output voltage we will get. This output voltage will then feed through the
Analog to digital converter port of the microcontroller where it will be processed for the
control of the Micro-Tank in navigating a straight path. For matching our output voltage
to that of the Vdd or the regulated voltage of the regulator, we have chosen to add a 100K
ohm resistor connected between the output and input voltage of the photo resistor. The
resistor in this case is a pull-up resistor in which extends the linear output range to near
Vdd with minimal effect on Vdark. Figure below will describe our connection:
21
After selecting both the LED and the Photoresistor, we have connected these parts to the
circuit to perform component testing. It is important to note that the purpose of these
sensors is to compare the two voltage readings obtained from the two center sides of the
Micro-tank and set them equal for the mouse to travel in a straight path. To perform our
component testing in a more accurate way, we have tested our two IR sensors in four
trials and averaged them together to get a graph with the accurate results on it. Below we
will find these results:
22
Trial 1 Trial 2Distance Output Voltage Distance Output Voltage
1 0.96 1 1.012 3.79 2 3.793 3.79 3 3.794 3.79 4 3.795 3.79 5 3.79
5.2 3.77 5.2 3.76 2.75 6 2.597 1.845 7 1.7258 1.33 8 1.279 0.937 9 0.858
10 0.655 10 0.65311 0.56 11 0.51112 0.427 12 0.43813 0.336 13 0.33114 0.303 14 0.29215 0.248 15 0.23816 0.199 16 0.21717 0.185 17 0.18618 0.16 18 0.16119 0.148 19 0.14520 0.14 20 0.14121 0.131 21 0.13422 0.125 22 0.127
23
Trial 3 Trial 4Distance Output Voltage Distance Output Voltage
1 1.57 1 1.222 3.79 2 3.793 3.79 3 3.794 3.79 4 3.795 3.79 5 3.79
5.2 3.75 5.2 3.696 2.61 6 2.617 1.84 7 1.838 1.23 8 1.189 0.865 9 0.918
10 0.628 10 0.67711 0.535 11 0.50312 0.442 12 0.4413 0.346 13 0.33114 0.285 14 0.28515 0.245 15 0.24116 0.212 16 0.22517 0.181 17 0.18318 0.157 18 0.14919 0.142 19 0.14420 0.136 20 0.1421 0.134 21 0.13822 0.12 22 0.119
24
Average of All TrialsDistance Output Voltage
1 1.192 3.793 3.794 3.795 3.79
5.2 3.72756 2.647 1.818 1.25259 0.8945
10 0.6532511 0.5272512 0.4367513 0.33614 0.2912515 0.24316 0.2132517 0.1837518 0.1567519 0.1447520 0.1392521 0.1342522 0.12275
The supply current for this photo-resistor is 1.1 mA which is very low and a benefit
toward our design.
25
The Chart for the Average Number of trials:
2. Side and Corner digital Sensors:
26
In addition to the two center IR sensors, our micro-tank also uses 5 additional side and
corner sensors which are made by sharp and output a digital value based on hysteresis
effect. The Sharp GP2Y0D340K is a type of a distanced sensor in which can also be
used as a proximity sensor. Figure below shows the picture of this type of sensor:
We are using this type of sensor for detecting the walls and openings in front of our
device as well as on the corner section of our tank. Since our output from this sensor is
either high near vdd or low, we cannot use were not able to use it for any other
applications. At the time of order this type of sensor, we assumed that we are able to get
wide range of output voltage reading. However, later on we realized that this sensor give
an output of high or low based on hysteresis effect. One of the good features of this
sensor is that it has long range distance detection at maximum of 40cm. The resistor that
is connected to the LED’s internal feedback loop can be changed to reduce the distance
range suitable for our project. In addition, we also connect a 0.1 uF capacitor to the
ground from the input voltage of this sensor to reduce the existence of noise generated
27
from rotation of the motor. Another great feature of this sensor is that the variety of the
reflectivity of the object, the environmental temperature, and the operating duration are
not influenced easily to the distance detection. Finally, another great feature of this sensor
is that it draws very little current for its operation which results to reduction in power
consumption. Figure below shows the functionality of this sensor which matches our
component testing:
As shown in the figure above, the output voltage is low until the 40 cm distance limit.
Then, due to internal hysteresis, the voltage will become high with the variation of
+-80mm. This is the characteristics that we have also obtained based on our
measurement.
28
The figure below shows how these sensors are positioned in our Micro-tank:
3. The Motor Driver:
The main purpose of using a driver in our system is to control the motors and turn them
on and off through communicating with our Microcontroller. To understand the concept
of driver which in reality is nothing but H-Bridge ICs, we have examined the
understanding of a simple H-Bridge Circuit as shown in the figure below:
29
As shown from the figure, the main purpose of an H-Bridge is to connect the input of the
motor to the battery voltage supply using some sort of switching mechanism. The reason
we want to do this is because the motors require large amount of current which is not safe
for a sensitive microcontroller. In addition, our most microcontrollers have an external
power supply range of up to 5 volt which is not sufficient enough to run the motors at a
high velocity or may be not enough operating voltage for the motors at all. In order to fix
these issues, we use the H-Bridge configuration shown on the figure above. When
closing switches A and D above, we are connecting the positive supply of the battery to
the positive side of the motor and the ground to the negative side of the motor. The
resulting schematics would be one shown below where the motor will be spinning
forward.
30
Forward
By closing the switches B and C, we will cause the motor to rotate backward as shown in
the figure below:
Backward
By closing switches A and C, we will disconnect the batter from the Motor as shown on
the figure below:
Braking
One of the major mistakes that can cause battery burning is by closing switches A and B.
In this way, we are connecting the positive side of the battery to the negative side of the
31
battery which results to melting of wires as a result of shorting the circuit. The figure
below will describe this phenomenon:
Don't Short the Battery!!
Now that we have insight about how the H-Bridge Circuit works as a switching
mechanism, the question remains in how can we make this switching effect? The answer
to this question is straight forward; we will use a transistor to that performs the switching
mechanism for in our circuit. The type of transistor that can be used to implement our
design varies, but most of these transistors operate in the same way. Consider the
transistor H-Bridge Figure below:
An H-Bridge with Transistors
32
When supplying a VDD regulated voltage of 5 Volt to the gate of the transistors connected
to the resistor (let’s consider gate A in this case), two things may happen:
If Vdd is higher than the turn on voltage of the transistor which is related to the threshold
voltage, then there will be channel formed between the source and drain of the transistor
(considering a CMOS Transistor). The connection of the source and drain (collector and
emitter in case BJT Configuration) resembles the closing of the switch A which will then
connect the positive side of the motor to the positive supply voltage of the battery.
If the Vdd is lower than the turn on voltage of the transistor, the nothing will happen and
the switch is still off. It is important to note that selecting a right transistor in this case is
a critical step. Most transistors however have a threshold voltage much less than 5 Volt.
The job of our microcontroller in this case is to supply continuous pulses that have 5V
peak to peak value in order to turn on the motors.
The driver we have selected for our design project is the L293D driver which is the
quadruple high-current half-H drivers. These drivers consist of H-Bridges that can
connect two DC motors inputs to the battery supply. Similar to the H-bridge, our driver
works in a similar fashion with an advantage of having several safety features added into
it. This driver has been designed by the Texas Instrument to provide bidirectional drive
currents of up to 1A at the input voltage ranges of 4.5 to 36 volt. In addition, this driver
has a safety feature of internal ESD protection, thermal shutdown, and internal fly back
diodes used for the back induced EMF voltage of the motors. The internal logic of our
33
driver will prevent the battery positive and negative terminals to be shorted as it was the
case with a regular H-Bridge.
In order to describe the truth table for our driver, consider our driver schematic below:
As shown in the figure above, our L293D driver has two enable pins that are pins 1 and 9.
When the enabled inputs are high, the associated drivers are enabled and their outputs are
active and in phase with their inputs. On the other hand, when the enable inputs are low,
those drivers are disabled and their outputs are off and in the high impedance state. The
enable pins in our driver are mainly used to control the speed of the motors through
generation of the pulse waves from the Microcontroller, a method known as Pulse Width
Modulation. In our design, we ignored the use of Pulse Width modulation to control the
speed of the Micro-tank and connect our enable pins directly to Vdd regulated 5 Volt.
The reason for doing so is that our AVR Butterfly Microcontroller has limited I/O ports
and we were unable to use additional I/O ports for controlling the speed of the tank
through the enable pin of the driver. This will however be one of the tasks that is going
to be accomplished in future for improvement and better control of our device.
34
Pins 4,5,13 and 12 of our driver are connected directly to the ground as shown in the
picture above. From the figure above, Pin 8 is connected directly to the supply voltage of
the battery and pin 26 is connected to the 5 V regulated voltage from the regulator for
powering up the internal logic of the driver. The remaining pins are the input pins
characterized by letter A and output pins characterized by letter Y. Table below shows the
truth table of our driver and how it is related to forward, reverse, backward and stop
movement of our micro-tank.
Truth Table
Motor 1Input Output Motor Action
Pin 2 Pin 7 Pin 3 Pin 60 0 0 0 Stop0 1 0 1 Forward1 0 1 0 Backward1 1 1 1 Stop (Prevent Using this Logic)
Motor 2Input Output Motor Action
Pin 10 Pin 15 Pin 11 Pin 140 0 0 0 Stop0 1 0 1 Forward1 0 1 0 Backward1 1 1 1 Stop (Prevent Using this Logic)
Below is our component testing results for the driver under the truth table condition
above (Analog Results):
Motor 1Input Voltage Output Results Motor ActionPin 2 Pin 7 Pin 3 Pin 6
35
0 Volt 0 Volt 0 0 Stop0 Volt 5 Volt 0 6.87 Forward5 Volt 0 Volt 6.87 0 Backward5 Volt 5 Volt -- -- Stop (Prevent Using this Logic)
Total Current Drawing per channel Measured 0.4 A
Battery Voltage Measured 7.96 VoltVoltage Difference 1.09 v
Motor 2Input Voltage Output Results Motor ActionPin 2 Pin 7 Pin 3 Pin 60 Volt 0 Volt 0 0 Stop0 Volt 5 Volt 0 6.87 Forward5 Volt 0 Volt 6.87 0 Backward5 Volt 5 Volt -- -- Stop (Prevent Using this Logic)
Total Current Drawing per channel Measured 0.45 A
Battery Voltage Measured 7.96 VoltVoltage Difference 1.09 v
4. Motors and Chassis:
Motors are the equipment in which gets the car moving. Without the motors, the
Micromouse would not be able to do much of anything (Last year Report). Selection of a
suitable motor for our project has been a controversial issue among the members of our
group. We had to make a decision in selecting a motor that would give us maximum
speed, a good amount of torque during turning, higher stalled current, high internal
impedance and low power consumption. There were various types of motors in which we
have conducted a research for in our project. In general, the types of motors used in the
design of a micromouse lies in two categories; Dc motors and Stepper Motors.
DC Motors Vs. Stepper Motors
36
DC motors will almost certainly give you the best combination of power to weight ratio
and top speed (http://micromouse.cannock.ac.uk/motors/dcmotors.htm). Figure below
shows a picture of a DC motor:
When applying a voltage to the DC motor, the motor
will start to rotate and results into the induction of
an opposite voltage that opposes the current.
Eventually, the speed of the motor stabilizes. The DC motors generally run more
efficiently at higher speeds where the available torque will be less than that of the stall
torque. As a result, we will have issues with turning when having a smaller torque. To
solve this issue, DC motors are connected to the gear boxes driving gears. The main
functionality of the gear is to increase the torque while the speed of the motor will be
reduced a little. The combination of high speed velocity and gear box damping effect in
DC motors makes them suitable for design of the Micromouse Robots that require high
speed and adequate amount of torque. In addition, DC motors without an encoder are
relatively cheaper than the stepper motors and are very light weighted as well compared
to the stepper motors. So, now, one may ask, why did we have to debate about
purchasing a stepper motor when DC motors have all these advantages? To answer this
question, let’s consider discussing more about the stepper motors. Figure below shows a
picture of a Stepper motor:
37
Stepper motors only rotate a specific number of degrees when receiving a pulse of
electricity at the inputs. In the similar fashion, the more the motor is pulsed, the farther
the motor will travel. Counting the number of pulses will already give us the velocity
and positioning distance we need. Stepper motors are usually more bulky than the DC
motors and have higher torque than the DC motors. As it is described in any motor
equation, having a higher torque indicates a lower velocity. Unlike stepper motors, DC
motors have no sensory mechanism that can automatically measure their rotational
velocity. To solve this issue, the designer must incorporate an additional part in his or her
design that can measure the velocity as well as determine the positioning of the
Micromouse. This specific part is called an encoder. There are various types of encoders
that can be used for the design of the micromouse. Figure Below shows a typical picture
of a paper encoder wheel:
These encoders are attached to the wheel or the gear disk. In addition to this paper
encoder there is an emitter and a detector connected in the circuit. When the wheels
38
rotate, the shaft encoder provides pulse train (since the white color reflects the ray and
black does not so we have 0 and 1 logical values considered as voltages in an analog
terminology) that can be counted and allow the microcontroller to determine the velocity
of the motor as well as how far the motor has traveled. Some DC motors come with an
internal encoder, but with the downfall of having higher costs. Adding the additional
encoder part to our system in addition to dc motor also increases the cost of the whole
thing. Since stepper motors do not need encoders (Stepper motors turn based on giving it
input pulses) they would be in the long term more cost effective. In addition, it is much
easier to program the stepper motors than DC motors because stepper motors turn at
certain specified angle when supplying input pulses to them. As a result, measurement of
velocity and position is obtained through the motor itself whereas DC motors require
encoders that need to be connected to the I/O port of the Microcontroller for detection
and control of speed. In other words, the advantage of the stepper motor over DC motor
is that there is no need for feedback from the wheels to determine the speed and distance
traveled for the input pulse trains will already do that (7) All of these factors would make
the stepper motor suitable for the beginners who are just starting to design a Micromouse
with the trade of weight, size, lower speed, hardware complexity and at some point costs.
Now that we have covered the two types of motors let’s specify which type of motor we
have selected for our design. Initially, our team was leaning toward using a stepper motor
simply because of the ease of programming when using these motors. As time elapsed,
one of the team members in our group was not able to communicate with the rest of the
team so we have decided to change our method from Stepper motor configuration that
39
came up with the chassis to using DC motors of a tank. The chassis we have purchased
for our tank has already included integrated DC motors as well as the gear box with it.
We immediately liked the idea of using the tank since the gear box would reduce the
speed and provide adequate torque that would make turns suitable. Even though the
motors that were included with our chassis did not have an encoder, we came up with
methods for programming this tank that we thought at the time did not require the use of
an encoder. This obviously is not true since encoder is needed for stabilizing the
overshoot effect, an idea we have learned in classical control system. Later on, we
realized that one of our gears have a spot in which we can use for building our own
encoder on it. In addition to motor issues that has focused our attention of using the tank
for our design, we have also considered the chassis itself as an advantage to our design.
Wheels vs. Treads
Based on our understanding from last year design of the Micromouse, the mouse would
not stop right away and there were factors such as wheel drifting and skidding involved.
To solve this issue we have decided to choose a Tank that operated with treads
incorporating higher surface friction than wheels. This by far was one of the main
reasons we leaned toward choosing the Tank chassis composed of two DC motors rather
than using the Two Wheel chassis with stepper motor connection. We will now show our
component rest results for chassis as well as the motors in the table below:
Motor Test ResultsMotor's Maximum Operating Voltage (V) 12
40
Motor's Stalled Current (A) 0.6Motor's Impedance (Ohm) 20
Motor Type DC BrushlessEncoder Included NoOperating Voltage 6V
Tank/Chassis SpecificationTank Width 13 cmTank Height 5.5 cmTank Length 17 cm
Tank Weight Including Wheels Not SpecifiedWheel Diameter 4.5 cm
Figure below shows the relationship between the dimension of the tank and the maze,
material of the maze as well as the Algorithms used that will be explained later
5. Batteries:
Our choice for battery selection was a difficult task for we had to consider system level
power analysis before selecting our batteries. When choosing the battery, we considered
41
three criteria related to our system design. The first criterion is battery voltage, next one
is the battery capacity and the third one is the type of battery we had to select from. Let’s
consider battery voltage selection for our design at first. In doing so, we first figured out
the two main elements that have a direct relation to the battery voltage. The two elements
were the limitation on the input supply of our regulator as well as the minimum operating
voltage of our motor. Based on our analysis from the motor and regulator, we have
observed that the minimum operating voltage of the motor as well as minimum operating
voltage of the regulator is about 6 Volt. Considering the marginal changes in voltage, we
have decided to select 6 1.2 Volt battery cells that would give us total of 7.2 Volt. This
would be suitable for both the regulator and the motors. Now let’s consider the second
criterion which is related to the battery capacity and the type of battery. These two
criteria are related in some ways as we are going to discuss. The battery capacity will
determine the life time of the battery or the period of time in which the battery will
remain charged for while providing the maximum current to the components. Since this
is our first design project, we wanted to make sure that we have the maximum capacity
available, and that our batteries do not heat up or go bad soon. After a few searches from
one store to another, we have found batteries that have 2700 mAH charging capacity,
giving our tank plenty of time to navigate through the maze without the battery going
bad. The size of the battery we have selected for this purpose was AA batteries since
smaller sizes did not give such a high capacity. It is important to note that when selecting
batteries, size is also a very important factor; the larger size the battery is the more space
it will occupy in our tank and the heavier it is, resulting to even more power
42
consumption. As a result, we did not choose to have larger size batteries with more
capacity simply due to this fact. In addition, we have conducted a few researches from
Micromouse designers in which they have stated AA size batteries were the best typical
size to use in the Micromouse. Finally, when selecting batteries, we had to choose from a
variety of batteries that are out there in the market. Table below will illustrate general
specification of each type:
Alkaline NiCad NiMH unitCell Voltage 1.5 1.2 1.2 voltCapacity 2000 500 1100 mAhEnergy Density 190 44 53 Wh/kgInternal Resistance 150 10 30 mohmCharger none simple harder
http://www.micromouseinfo.com/introduction/batteries.html
Alkaline: These batteries are regular batteries that are out there in the store and they have
a higher cell voltage compared to other batteries. However, because of their high internal
resistance, they cannot provide current needed for the motors.
NiCad: These types of batteries have lower cell voltages so there need to be more cells
to obtain the required voltage. These batteries also have a very low capacity, but they are
very easy to recharge and because of their small internal resistance, they are good for
powering the motors for a short period of time however.
NiMH: NiMH batteries are similar to the more expensive NiCad batteries except that
they can deliver current for a longer period of time due to having higher capacity. These
types of batteries take longer time to charge, but they are more suitable for Robotic
applications.
43
Based on the researched performed above, we have selected 6 AA sized NimH batteries
for the total of 7.2 Volt (1.2 Volt per cell) and capacity of 2700 mAh connected in series
together. The results below describe our measurement for the batteries as well as the
diagram of our selected battery:
Battery TestVoltmeter Measured Voltage (V) 7.96
Battery Capacity (mAH) 2700Internal Resistance (Ohm) ~0.2
Battery Type NiMhBattery Size AA
Rechargeable? Yes
Internal Resistance Calculation: We have calculated the internal resistance by
connecting the battery to the 100 ohm resistor in series for a short period of time and
measuring the current drawing from the battery. By knowing the current, the voltage of
the battery as 7.2 Volt and the resistance value of 100 ohm (R1), we have used the voltage
divider technique to solve for rb as follows:
44
Vin
6. Regulator:
The main purpose of using a regulator in our design project is to step down the battery
voltage to a 5 volt regulated output that can be used for powering the sensors and the
microcontroller. Regulated voltage is required in our circuit to reduce the change in
voltage that may damage the sensors or in many ways it can cause the sensors to give us
wrong readings due to input voltage distortions. In choosing a regulator, we had many
choices to select from. We were mostly interested to purchase the voltage regulator
Max727 which is the switch mode regulator with the peak efficiency of 90%. However,
this product was discontinued when we wanted to order it. So, we have decided to
choose the regular 7805 regulator that would give us 5V regulated output voltage. The
manufacture we have selected this regulator from is the Fairchild semiconductor. This
type of regulator can supply an output current of up to 1A which is very suitable for our
design. To determine the turn on voltage of the regulator, we have performed an
experiment in the lab. Table below as well as the chart below will describe our results for
the component testing of the regulator:
Regulator Test Results Input Voltage 7.96
Output Voltage 4.95Maximum Current 1AHeat Sink Included Yes
rb R1Voltage Divider
45
Input Voltage Output Voltage0 0.0261 0.2472 1.243 3.194 4.1325 4.9616 4.9647 4.9648 4.9649 4.964
10 4.96411 4.964
46
B: System Design Schematics and Connection
After we have tested each individual components of our Micro-tank, we were ready to
design a schematic that incorporates everything together with the addition of a few
components such as capacitors and resistors added to our tested components. To
illustrate our system design, let’s consider the schematic below.
47
As shown on the schematic, initially, the batteries provide a voltage of 7.2 volt to the
regulator and the VCC2 of our L293D Driver. Since each channel of the driver will can
draw maximum of 1A from the batteries, and since other components in our circuit will
draw less than 700 mA current, our battery will not overheat or discharge very fast. In
the worst case scenario, our battery should discharge in an hour when 2.7 Amp of current
is drawn. The regulator as shown on the schematic will provide an output voltage of 5
Volt to all the sensors, Vcc1 (logic voltage) of the driver, as well as the external voltage of
the Microcontroller. The main question in here is that if the total amount of current the
driver can supply to the loads is about 1A, are the loads drawing one amp or more? This
is critical factor to know since if our loads are drawing more than 1A and our regulator
48
supply current limit is only 1A, we will overheat the regulator and at some point cause
the component to burn. So, in order to prevent such thing from happening, we have
performed calculation for the worst case scenario current drawings of our loads which
include the sensors, microcontroller, and the driver logic circuits. The calculation is as
follows:
Description Quantity Maximum Current Drawing Total
IR LED TSAL6100 2 0.15 0.3IR Photoresistor
TSL260R 2 0.001 0.002
Sharp GP2Y0D340K Sensor 5 0.033 0.165
L293D Driver Vcc1 1 0.1 0.1Avr Butterly
Microcontroller 1 0.12 0.12
Total Current Drawing 0.687
As we can see from our calculation, under the worst condition, our regulator must supply
the current of 0.687 to the loads in our circuit and this is possible since the maximum
rating for current supply of the regulator is rated at 1A. Nevertheless, even 0.7 A is a
large current for the regulator, we are using a heat sink to get rid of an excess heat (if it’s
there) from the regulator in order to not damage it. In the system schematic design
above, we can also see the addition of 0.1 uF capacitors and 10K Ω resistors to the
circuit. We are using the 0.1 uF ceramic capacitors in or circuit to reduce the noise that
can be generated from the motors in our circuit. This noise as a result of back emf of the
motor can damage the sensors and even the driver logic circuit. To avoid such damage,
we are filtering the high frequency noise as a low pass filter by adding a capacitor to the
49
ground of our circuit. After all, the equation for the capacitor can be written as the
following:
Based on this equation, at high frequency w, we have an infinite impedance Z
corresponding disconnection of our circuit to pass the high frequencies through. The 10
K resistors, on the other hand are used connecting the driver’s input to the
microcontroller output port. The purpose of these resistors is also to protect the
microcontroller from the back emf characteristics of the circuit as well as noise
generation from the motors.
D: Mechanical Schematic and Design
50
The mechanical schematic for our Micro-Tank consists of consists of screws, short
metallic column extenders, tall column extenders and a transparent thick Plexiglas that
can be drilled at four corners on top of the tank. As part of our design, the tall column
extenders are made to hold the board on top of the tank so that it would be easier to move
the battery from the inside of the tank when the battery needs to be recharged. We had to
cut a rectangular piece from the inside of the transparent tick Plexiglas in order to be able
to access the battery from the inside of the tank. Doing this was not an easy task since
the Plexiglas was very brittle and it would crack easily during the cutting process.
However, after destroying two of them, we were finally able to make one that was good
for mounting around the tank. In order to mount the screws around the tank, it was
necessary to do exact measurements since the edge of the tank was short. The diagram
below shows how this measurement has been done and how we marked the perimeter for
cutting a piece of tick transparent Plexiglas and indicate the locations where the screws
were used to connect the column extenders to the body of the tank as well as to the board
on top. (Note: the short column extenders used for connecting the microcontroller to the
surface of the board)
Mechanical SpecificationPlexiglas dimension (cm) 18 by 11Plexiglas length thickness 2 cm from each sidePlexiglas width thickness 1 cm from each side
PCB Board Dimension (cm) 10 by 16Screw Sizing 4-40 1/4 SLOT ROUND
Drill Size 4Microcontroller Dimension (Cm) 6.6 by 4.4
51
PlexiglasTank Width Plastic
Screws
52
D: Maze Solving Design Approach
Now that we have constructed our design schematic, it is important to focus our attention
to find ways in solving the maze to generate our own algorithms in combination with
other types of algorithms that may be used for programming of our microcontroller. We
have generated a method in solving a maze that combines 5 sensors, and 2 center sensors
in trying all possible paths through the maze in order to find the destination. Here, there
are a few questions that need to be addressed; when does the Tank decides to turn? How
does the Tank know what direction to turn? And how can we recognize the paths that are
dead-end and omit them after the first round of Navigation? The answers to these
questions rely on our maze solving strategy which is illustrated on the next page:
1. When does the Tank decide to turn?
53
The answer to this question is explained based on the few figures below:
Initially our tank is moving centered between the two side walls. The upper left, upper
right, lower left and lower right distance sensors detect these walls as the mouse is
navigating forward. The center sensors on the left and right also control the mouse to
navigate through the center of the maze.
54
The next step is that the mouse will navigate forward until it reaches the intersection or
the position at t he upper left sensor and upper right sensors cannot detect any walls.
When this happens, the upper left and upper right sensors will send a signal to the
microcontroller telling the microcontroller to reduce the speed of the motors through the
process of Pulse Width Modulation.
55
As our tank navigates forward, it will eventually reach a point where all the four side
sensors (the upper left, the lower left, t he upper right, and the lower right) does not detect
any walls as shown in the figure above. At this point, the sensors send a signal to the
microcontroller to reduce the speed of the tank to 0 and begin the turning process at 90
degree angle. Notice that the programming we are doing does not stop the tank
immediately, rather it will reduce the speed to 0 and turns 90 degrees toward the right.
The concept of why the tank will turn right and not left will be explained in the answer to
the next question.
56
Sometimes, the mouse may navigate through a route that is dead-end. In this case, all
four side sensors, the upper left, the upper right, the lower left and the lower right sensors
as well as the front sensor detects wall. When this scenario occurs, there will be a tank
will stop and brakes before hitting the wall in the range of sensor detection we have
specified in our design. Then, once the tank stops, it will make a 180 degree turn to turn
57
around. Our original idea about this was to add a back sensor so that it can back-up, but
we have observed that the tank is capable of making the 180 degree turns easily.
The following describes the turning mechanism of the tank shown on the diagrams
below:
58
59
60
61
How does the Tank know what direction to turn?
The tank knows which direction it should turn based on the programming algorithm that
we are using. When programming the microcontroller, we will initiate the tank
movement by clicking on the joy-stick button on the microcontroller. Our design is built
in a way that when pressing the joystick up, the mouse will navigate through the maze
and uses the long path algorithm or what we call the special kind of Depth First algorithm
RFLB. RFLB simply indicates that the mouse will always prioritize turning right first,
then forward, then left and then backward or turn. In doing so, the tank will travel
through all of the paths in the maze in order to get toward the destination and will always
find the path toward destination. It is important also to note that when the mouse is
navigating through the maze for the first time, it will record the data in the form of an
array and saves it to the flash memory of the AVR butterfly for use in the second round.
Based on this design, the first round of navigation through the maze is always time
consuming and slow. The next section of our programming Algorithm comes into effect
when pressing the joystick downward and having he mouse navigate through the maze
62
for the second time. At this point, there will be a new algorithm written by Arya Ahmadi
used. This algorithm will always work and eliminates the paths that were unnecessary to
navigate through from the first round.
Figure below shows the basic concept behind RLFB Depth First Algorithm:
We now use the RFLB Depth First Algorithm in the figure above. At first the mouse
considers turning right. However, since the upper right and lower right sensors detect a
wall, the mouse will not turn right. The next step it for the mouse to consider going
63
forward. However, since the front sensor detects wall, this is not going to happen. Third
the mouse tries to look at the left side. Since the upper left and lower left sensors are not
detecting any walls, the mouse will turn left and move forward. Such an analogy will
happen repeatedly until the mouse finds the center of the maze. (In our case, our tank
does this)
SYSTEM DIAGNOSTICS, LAYOUT AND RESULTS
After having all the possible design approaches specified above, we were now ready to
create the PCB layout of our Micro-tank. Due to time limitation we have encountered
during this project, we were not able to draw the PCB layout using express PCB or any
other Engineering software available to accomplish this task. Instead, we purchased a
PCB board that was suitable for any connection and required a little wiring for complete
connection of our components underneath the board. The soldering process as well as
troubleshooting of our system took a long time and it was by far the hardest part of our
project. In the end, our PCB layout looks as shown in the figure below:
64
Our design for the PCB layout above was constructed in a way that would make
troubleshooting of it very easy. For example, the board itself can easily get disassembled
from the tank due to having removable harnesses that our wires were attached to as well
as screws on the side that mounted the board to the body of the tank. In other words, you
could easily disassemble the board from the tank by removing the wire harnesses and
screws without the use of soldering or unsoldering any component as well as without
damaging any parts on the tank. This technique of design has made our task easier for
troubleshooting our system since every time we though there was a problem with
connection of our components, we were able to easily disassemble the board, fix the
problems, and then connect the board back to the tank. We have also used a switch in our
layout to securely test our system and if God forbid there was a problem, we would be
Regulator
65
able to immediately turn off the switch to prevent any major damage to our system. After
finishing our layout, we had no more issues and problems with our tank, except that at the
last minute of program testing, one of our side sensors malfunctioned.
MICROCONTROLLER SELECTION AND
PROGRAMING
Probably one of the hardest parts of this design project has been the programming of the
microcontroller as well as finding the suitable microcontroller. The microcontroller is the
considered to be the brain of our Micro-tank in which it controls all the components on
the tank. The information form the sensors is sent to the microcontroller and processed in
order to send a signal to the drivers to turning on and off the motors. In addition, the
microcontroller has several other features in which allow us to incorporate other
functionalities in our tank. The microcontroller that we have selected is the AVR
Butterfly as shown in the figure below:
66
The decision to purchase this microcontroller was perhaps the biggest mistake we have
done for we were not that is processor shares most of the I/O ports with other functions in
it. Our main decision to purchase this microcontroller was based on have a large memory
data flash which many other microcontrollers did not have. The features of the AVR
butterfly that was useful in this project includes Atmega 169 microprocessor, 100
segment LCD display, 4Mbt of Dataflash, 32Khz Oscillator for the Real time Clock or
RTC, 4-way directional button, light sensor pins, temperature sensor pins, as well as the
UART port for connection to the computer. The main disadvantage of this
microcontroller is that the ports that we were planning to use of Tank were mostly shared
with other modules within the system. As a result, our task became very challenging in
trying to find a way to disable some of these sharing ports. In addition, we were not able
to disable everything since some of the ports shared important components that we were
using. An example of this would the LCD display. The figure below will illustrate the
ports that we used for connecting the components of our micro-tank:
67
PORT B is used for connecting the motor driver inputs to it.
Port D is used for the Corner Sensors and the Front Sensor
The JTAG port is used for connecting the center sensors from our Microtank
68
In order to become familiar with which section are these part sharing with, it is important
to look at the Atmega 169 processor schematic used for this microcontroller. The picture
below will illustrate this:
Programming
(Note: this section of our project has not been completed well. We are still working on
completing this section and when we are done, we will update our results to this section.
Sorry about this we had time limitation and issues in our group. Thanks)
#include <avr/io.h>
#include "adc.h"
69
#include "mboard.h"
//#define LIGHT_SENSOR 2
int ADC_read(void);
/******************************************************************************* Function name : ADC_init** Returns : None** Parameters : char input** Purpose : Initialize the ADC with the selected ADC-channel******************************************************************************/void ADC_init(char input) ADMUX = input; // external AREF and ADCx ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // set ADC prescaler to , 1MHz / 8 = 125kHz
input = ADC_read(); // dummy
/******************************************************************************* Function name : ADC_read (from modified atmel code)** Returns : int ADC** Parameters : None** Purpose : Do a Analog to Digital Conversion
70
******************************************************************************/int ADC_read(void) char i; int ADC_temp; // mt int ADC = 0 ; int ADCr = 0; // To save power, the voltage over the LDR and the NTC is turned off when not used // This is done by controlling the voltage from a I/O-pin (PORTF3) sbiBF(PORTF, PF3); // mt sbi(PORTF, PORTF3); // Enable the VCP (VC-peripheral) sbiBF(DDRF, DDF3); // sbi(DDRF, PORTF3);
sbiBF(ADCSRA, ADEN); // Enable the ADC
//do a dummy readout first ADCSRA |= (1<<ADSC); // do single conversion while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active for(i=0;i<8;i++) // do the ADC conversion 8 times for better accuracy ADCSRA |= (1<<ADSC); // do single conversion while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active ADC_temp = ADCL; // read out ADCL register ADC_temp += (ADCH << 8); // read out ADCH register
ADCr += ADC_temp; // accumulate result (8 samples) for later averaging
ADCr = ADCr >> 3; // average the 8 samples cbiBF(PORTF,PF3); // mt cbi(PORTF, PORTF3); // disable the VCP cbiBF(DDRF,DDF3); // mt cbi(DDRF, PORTF3); cbiBF(ADCSRA, ADEN); // disable the ADC
return ADCr;
71
//***************************************************************************// File........: BCD.c// Author(s)...: ATMEL Norway// Target(s)...: ATmega169// Compiler....: IAR EWAAVR 2.28a// Description.: AVR Butterfly BCD conversion algorithms// Revisions...: 1.0// YYYYMMDD - VER. - COMMENT - SIGN.// 20030116 - 1.0 - Created - KS//***************************************************************************
/****************************************************************************** Function name : CHAR2BCD2* Returns : Binary coded decimal value of the input (2 digits)* Parameters : Value between (0-99) to be encoded into BCD * Purpose : Convert a character into a BCD encoded character.* The input must be in the range 0 to 99.* The result is byte where the high and low nibbles* contain the tens and ones of the input.*****************************************************************************/char CHAR2BCD2(char input) char high = 0; while (input >= 10) // Count tens high++; input -= 10;
return (high << 4) | input; // Add ones and return answer
72
/******************************************************************************* Function name : CHAR2BCD3** Returns : Binary coded decimal value of the input (3 digits)** Parameters : Value between (0-255) to be encoded into BCD ** Purpose : Convert a character into a BCD encoded character.* The input must be in the range 0 to 255.* The result is an integer where the three lowest nibbles* contain the ones, tens and hundreds of the input.******************************************************************************/unsigned int CHAR2BCD3(char input) int high = 0; while (input >= 100) // Count hundreds high++; input -= 100;
high <<= 4; while (input >= 10) // Count tens high++; input -= 10;
return (high << 4) | input; // Add ones and return answer
73
//
// Author(s)...: ATMEL Norway
//
// Target(s)...: ATmega169
//
// mt - used for debugging only - may not work
// Include files.
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include <avr/signal.h>
#include "lcd_driver.h"
#define BOOL char
#define FALSE 0
#define TRUE (!FALSE)
// Variable from "button.c" to prevent button-bouncing
74
extern unsigned char gButtonTimeout;
extern BOOL gAutoPressJoystick;
// Used to indicate when the LCD interrupt handler should update the LCD
// mt jw char gLCD_Update_Required = FALSE;
volatile char gLCD_Update_Required = FALSE;
// LCD display buffer (for double buffering).
char LCD_Data[LCD_REGISTER_COUNT];
// Buffer that contains the text to be displayed
// Note: Bit 7 indicates that this character is flashing
char gTextBuffer[TEXTBUFFER_SIZE];
// Only six letters can be shown on the LCD.
// With the gScroll and gScrollMode variables,
// one can select which part of the buffer to show
volatile signed char gScroll;
volatile char gScrollMode;
////Start-up delay before scrolling a string over the LCD
75
char gLCD_Start_Scroll_Timer = 0;
// The gFlashTimer is used to determine the on/off
// timing of flashing characters
char gFlashTimer = 0;
// Turns on/off the colons on the LCD
char gColon = 0;
// Look-up table used when converting ASCII to
// LCD display data (segment control)
// mt __flash unsigned int LCD_character_table[] =
unsigned int LCD_character_table[] PROGMEM =
0x0A51, // '*' (?)
0x2A80, // '+'
0x0000, // ',' (Not defined)
0x0A00, // '-'
0x0A51, // '.' Degree sign
0x0000, // '/' (Not defined)
0x5559, // '0'
76
0x0118, // '1'
0x1e11, // '2
0x1b11, // '3
0x0b50, // '4
0x1b41, // '5
0x1f41, // '6
0x0111, // '7
0x1f51, // '8
0x1b51, // '9'
0x0000, // ':' (Not defined)
0x0000, // ';' (Not defined)
0x0000, // '<' (Not defined)
0x0000, // '=' (Not defined)
0x0000, // '>' (Not defined)
0x0000, // '?' (Not defined)
0x0000, // '@' (Not defined)
0x0f51, // 'A' (+ 'a')
0x3991, // 'B' (+ 'b')
0x1441, // 'C' (+ 'c')
0x3191, // 'D' (+ 'd')
0x1e41, // 'E' (+ 'e')
0x0e41, // 'F' (+ 'f')
77
0x1d41, // 'G' (+ 'g')
0x0f50, // 'H' (+ 'h')
0x2080, // 'I' (+ 'i')
0x1510, // 'J' (+ 'j')
0x8648, // 'K' (+ 'k')
0x1440, // 'L' (+ 'l')
0x0578, // 'M' (+ 'm')
0x8570, // 'N' (+ 'n')
0x1551, // 'O' (+ 'o')
0x0e51, // 'P' (+ 'p')
0x9551, // 'Q' (+ 'q')
0x8e51, // 'R' (+ 'r')
0x9021, // 'S' (+ 's')
0x2081, // 'T' (+ 't')
0x1550, // 'U' (+ 'u')
0x4448, // 'V' (+ 'v')
0xc550, // 'W' (+ 'w')
0xc028, // 'X' (+ 'x')
0x2028, // 'Y' (+ 'y')
0x5009, // 'Z' (+ 'z')
0x0000, // '[' (Not defined)
0x0000, // '\' (Not defined)
78
0x0000, // ']' (Not defined)
0x0000, // '^' (Not defined)
0x0000 // '_'
;
/******************************************************************************* Function name : LCD_Init** Returns : None** Parameters : None** Purpose : Initialize LCD_displayData buffer.* Set up the LCD (timing, contrast, etc.)******************************************************************************/void LCD_Init (void) LCD_AllSegments(FALSE); // Clear segment buffer.
LCD_CONTRAST_LEVEL(LCD_INITIAL_CONTRAST); //Set the LCD contrast level
// Select asynchronous clock source, enable all COM pins and enable all // segment pins. LCDCRB = (1<<LCDCS) | (3<<LCDMUX0) | (7<<LCDPM0);
// Set LCD prescaler to give a framerate of 32,0 Hz LCDFRR = (0<<LCDPS0) | (7<<LCDCD0);
LCDCRA = (1<<LCDEN) | (1<<LCDAB); // Enable LCD and set low power waveform
79
//Enable LCD start of frame interrupt LCDCRA |= (1<<LCDIE);
gLCD_Update_Required = FALSE;
/******************************************************************************* Function name : LCD_WriteDigit(char c, char digit)** Returns : None** Parameters : Inputs* c: The symbol to be displayed in a LCD digit* digit: In which digit (0-5) the symbol should be displayed* Note: Digit 0 is the first used digit on the LCD,* i.e LCD digit 2** Purpose : Stores LCD control data in the LCD_displayData buffer.* (The LCD_displayData is latched in the LCD_SOF interrupt.)******************************************************************************/void LCD_WriteDigit(char c, char digit)
unsigned int seg = 0x0000; // Holds the segment pattern char mask, nibble; char *ptr; char i;
if (digit > 5) // Skip if digit is illegal return;
//Lookup character table for segmet data if ((c >= '*') && (c <= 'z'))
80
// c is a letter if (c >= 'a') // Convert to upper case c &= ~0x20; // if necessarry
c -= '*';
//mt seg = LCD_character_table[c]; seg = (unsigned int) pgm_read_word(&LCD_character_table[(uint8_t)c]);
// Adjust mask according to LCD segment mapping if (digit & 0x01) mask = 0x0F; // Digit 1, 3, 5 else mask = 0xF0; // Digit 0, 2, 4
ptr = LCD_Data + (digit >> 1); // digit = 0,0,1,1,2,2
for (i = 0; i < 4; i++) nibble = seg & 0x000F; seg >>= 4; if (digit & 0x01) nibble <<= 4; *ptr = (*ptr & mask) | nibble; ptr += 5;
/******************************************************************************* Function name : LCD_AllSegments(unsigned char input)** Returns : None** Parameters : show - [TRUE;FALSE]** Purpose : shows or hide all all LCD segments on the LCD
81
******************************************************************************/void LCD_AllSegments(char show) unsigned char i;
if (show) show = 0xFF;
// Set/clear all bits in all LCD registers for (i=0; i < LCD_REGISTER_COUNT; i++) *(LCD_Data + i) = show;
/******************************************************************************* LCD Interrupt Routine** Returns : None** Parameters : None** Purpose: Latch the LCD_displayData and Set LCD_status.updateComplete******************************************************************************/
SIGNAL(SIG_LCD) static char LCD_timer = LCD_TIMER_SEED; char c; char c_flash; char flash;
char EOL; unsigned char i;
///!!! static char timeout_count;///!!! static char auto_joystick_count;
82
c_flash=0; // mt /**************** Button timeout for the button.c, START ****************//*!!! if(!gButtonTimeout) timeout_count++; if(timeout_count > 3) gButtonTimeout = TRUE; timeout_count = 0; *//**************** Button timeout for the button.c, END ******************/
/**************** Auto press joystick for the main.c, START *************/
/*!!! if(gAutoPressJoystick == AUTO) auto_joystick_count++; if(auto_joystick_count > 16) gAutoPressJoystick = TRUE; auto_joystick_count = 15; else auto_joystick_count = 0;*/
/**************** Auto press joystick for the main.c, END ***************/
LCD_timer--; // Decreased every LCD frame
if (gScrollMode) // If we are in scroll mode, and the timer has expired, // we will update the LCD if (LCD_timer == 0)
83
if (gLCD_Start_Scroll_Timer == 0) gLCD_Update_Required = TRUE; else gLCD_Start_Scroll_Timer--; else // if not scrolling, // disble LCD start of frame interrupt// cbi(LCDCRA, LCDIE); //DEBUG gScroll = 0;
EOL = FALSE; if (gLCD_Update_Required == TRUE) // Duty cycle of flashing characters if (gFlashTimer < (LCD_FLASH_SEED >> 1)) flash = 0; else flash = 1;
// Repeat for the six LCD characters for (i = 0; i < 6; i++) if ((gScroll+i) >= 0 && (!EOL)) // We have some visible characters c = gTextBuffer[i + gScroll]; c_flash = c & 0x80 ? 1 : 0; c = c & 0x7F;
if (c == '\0') EOL = i+1; // End of character data else c = ' ';
// Check if this character is flashing
84
if (c_flash && flash) LCD_WriteDigit(' ', i); else LCD_WriteDigit(c, i);
// Copy the segment buffer to the real segments for (i = 0; i < LCD_REGISTER_COUNT; i++) *(pLCDREG + i) = *(LCD_Data+i);
// Handle colon if (gColon) *(pLCDREG + 8) = 0x01; else *(pLCDREG + 8) = 0x00;
// If the text scrolled off the display, // we have to start over again. if (EOL == 1) gScroll = -6; else gScroll++;
// No need to update anymore gLCD_Update_Required = FALSE;
// LCD_timer is used when scrolling text if (LCD_timer == 0) /* if ((gScroll <= 0) || EOL) LCD_timer = LCD_TIMER_SEED/2; else*/ LCD_timer = LCD_TIMER_SEED;
// gFlashTimer is used when flashing characters if (gFlashTimer == LCD_FLASH_SEED) gFlashTimer= 0; else gFlashTimer++;
85
//// Author(s)...: ATMEL Norway//// Target(s)...: ATmega169//// mt - used for debugging only - may not work
// Include files#include <avr/io.h>#include <avr/pgmspace.h>#include <inttypes.h>#include "lcd_driver.h"#include "lcd_functions.h"#include "BCD.h"#include "main.h"
#define FALSE 0#define TRUE (!FALSE)
char CONTRAST = LCD_INITIAL_CONTRAST;
// Start-up delay before scrolling a string over the LCD. "LCD_driver.c"extern char gLCD_Start_Scroll_Timer;
/****************************************************************************** Function name : LCD_puts_f** Returns : None** Parameters : pFlashStr: Pointer to the string in flash* scrollmode: Not in use** Purpose : Writes a string stored in flash to the LCD******************************************************************************/
86
// mt void LCD_puts_f(char __flash *pFlashStr, char scrollmode)void LCD_puts_f(const char *pFlashStr, char scrollmode) // char i; uint8_t i;
while (gLCD_Update_Required); // Wait for access to buffer
// mt: for (i = 0; pFlashStr[i] && i < TEXTBUFFER_SIZE; i++) for (i = 0; pgm_read_byte(&pFlashStr[i]) && i < TEXTBUFFER_SIZE; i++) // mt: gTextBuffer[i] = pFlashStr[i]; gTextBuffer[i] = pgm_read_byte(&pFlashStr[i]);
gTextBuffer[i] = '\0';
if (i > 6) gScrollMode = 1; // Scroll if text is longer than display size gScroll = 0; gLCD_Start_Scroll_Timer = 3; //Start-up delay before scrolling the text else gScrollMode = 0; gScroll = 0;
gLCD_Update_Required = 1;
/****************************************************************************** Function name : LCD_puts** Returns : None** Parameters : pStr: Pointer to the string
87
* scrollmode: Not in use** Purpose : Writes a string to the LCD******************************************************************************/void LCD_puts(char *pStr, char scrollmode) uint8_t i; // char i; while (gLCD_Update_Required); // Wait for access to buffer
for (i = 0; pStr[i] && i < TEXTBUFFER_SIZE; i++) gTextBuffer[i] = pStr[i];
gTextBuffer[i] = '\0';
if (i > 6) gScrollMode = 1; // Scroll if text is longer than display size gScroll = 0; gLCD_Start_Scroll_Timer = 3; //Start-up delay before scrolling the text else gScrollMode = 0; gScroll = 0;
gLCD_Update_Required = 1;
/****************************************************************************** Function name : LCD_putc** Returns : None*
88
* Parameters : digit: Which digit to write on the LCD* character: Character to write** Purpose : Writes a character to the LCD******************************************************************************/// mt void LCD_putc(char digit, char character)// mt void LCD_putc(char digit, char character)void LCD_putc(uint8_t digit, char character) if (digit < TEXTBUFFER_SIZE) gTextBuffer[digit] = character;
/****************************************************************************** Function name : LCD_Clear** Returns : None** Parameters : None** Purpose : Clear the LCD******************************************************************************/void LCD_Clear(void) uint8_t i; // char i; for (i=0; i<TEXTBUFFER_SIZE; i++) gTextBuffer[i] = ' ';
/*****************************************************************************
89
* Function name : LCD_Colon** Returns : None** Parameters : show: Enables the colon if TRUE, disable if FALSE** Purpose : Enable/disable colons on the LCD******************************************************************************/void LCD_Colon(char show) gColon = show;
/****************************************************************************** Function name : LCD_UpdateRequired** Returns : None** Parameters : update: TRUE/FALSE* scrollmode: not in use** Purpose : Tells the LCD that there is new data to be presented******************************************************************************/void LCD_UpdateRequired(char update, char scrollmode)
while (gLCD_Update_Required); gScrollMode = scrollmode; gScroll = 0;
gLCD_Update_Required = update;
90
/****************************************************************************** Function name : LCD_FlashReset** Returns : None** Parameters : None** Purpose : This function resets the blinking cycle of a flashing digit******************************************************************************/void LCD_FlashReset(void) gFlashTimer = 0;
/****************************************************************************** Function name : SetContrast** Returns : char ST_state (to the state-machine)** Parameters : char input (from joystick)** Purpose : Adjust the LCD contrast******************************************************************************/
/*
char SetContrast(char input) static char enter = 1; char CH, CL;
if (enter)
91
LCD_Clear(); enter = 0;
CH = CHAR2BCD2(CONTRAST); CL = (CH & 0x0F) + '0'; CH = (CH >> 4) + '0';
LCD_putc(0, 'C'); LCD_putc(1, 'T'); LCD_putc(2, 'R'); LCD_putc(3, ' '); LCD_putc(4, CH); LCD_putc(5, CL);
LCD_UpdateRequired(TRUE, 0);
if (input == KEY_PLUS) CONTRAST++; else if (input == KEY_MINUS) CONTRAST--;
if (CONTRAST == 255) CONTRAST = 0; if (CONTRAST > 15) CONTRAST = 15;
LCD_CONTRAST_LEVEL(CONTRAST);
if (input == KEY_ENTER) enter = 1; return ST_OPTIONS_DISPLAY_CONTRAST;
return ST_OPTIONS_DISPLAY_CONTRAST_FUNC;
*/
92
// mt - used for debugging only - may not work
#include <avr/io.h>#include <avr/interrupt.h>//#include <avr/pgmspace.h>//#include <avr/sleep.h>//#include <inttypes.h>//#include <stdio.h>#include <avr/delay.h>
#include "main.h"#include "lcd_functions.h"#include "lcd_driver.h"#include "adc.h"#define pLCDREG_test (*(char *)(0xEC))
// extern unsigned int LCD_character_table[] PROGMEM;
/******************************************************************************* Function name : main** Returns : None** Parameters : None** Purpose : Contains the main loop of the program******************************************************************************/int main(void) int leftwall; int rightwall; //rightwall //PGM_P statetext; Initialization(); sei(); //statetext= PSTR("arya"); char ss[5];
93
int arya; _delay_ms(2000); //left_tmt_right(); //right_tmt_left(); ADC_init(SENSOR_LEFT); //forward(); //_delay_ms(10000); //backward(); //_delay_ms(10000); //leftturn(); //_delay_ms(10000); //rightturn(); //_delay_ms(10000); //stop(); //_delay_ms(10000); while(1) //leftwall = ADC_read(); arya = ADC_read(); //itoa(arya,ss,10); //LCD_puts(ss,0); //right_tmt_left(); if (arya> 50 && arya < 200 ) right_tmt_left();//while (arya<100) else if (arya>250) left_tmt_right(); else forward(); //forward(); //if (bit_is_set(PINB,6)) // //LCD_Init(); // LCD_puts("hell",0); // //else // LCD_puts("NO",0); //PORTB & _BV(); //sprintf("a","1",223); return 0;
94
/******************************************************************************* Function name : Initialization** Returns : None** Parameters : None** Purpose : Initializate the different modules******************************************************************************/void Initialization(void) /* CLKPR = (1<<CLKPCE); // set Clock Prescaler Change Enable
// set prescaler = 8, Inter RC 8Mhz / 8 = 1Mhz CLKPR = (1<<CLKPS1) | (1<<CLKPS0);
// Disable Analog Comparator (power save) ACSR = (1<<ACD);
// Disable Digital input on PF0-2 (power save) DIDR1 = (7<<ADC0D);
// mt PORTB = (15<<PORTB0); // Enable pullup on PORTB = (15<<PB0); // Enable pullup on // mt PORTE = (15<<PORTE4); PORTE = (15<<PE4);
sbi(DDRB, 5); // set OC1A as output sbi(PORTB, 5); // set OC1A high */ CLKPR = (1<<CLKPCE); // set Clock Prescaler Change Enable
// set prescaler = 8, Inter RC 8Mhz / 8 = 1Mhz CLKPR = (1<<CLKPS1) | (1<<CLKPS0); LCD_Init(); // initialize the LCD
95
init_PORTS();
void init_PORTS(void) //motor 1: pin 0 and pin 2 //motor 2: pin 2 and pin 4 ////// //DDRB = 0xff; //output - motors DDRB = 0b10101010; //motors DDRB = 0xff //PORTB = 0x00; //PCMSK1 = 0x00; //DDRF = 0x00;
//PORTB = 0x00; //DDRB = 0x55; //input ports
//PORTB |=_BV(0); //SEG22 = 0x00; /* LCDDR0 = 0; LCDDR1= 0; LCDDR2= 0; LCDDR3= 0; //LCDDR4= 0; LCDDR5= 0; LCDDR6= 0; LCDDR7= 0; LCDDR8= 0; //LCDDR9= 0; LCDDR10= 0; LCDDR11= 0; LCDDR12= 0; LCDDR13= 0; //LCDDR14= 0; LCDDR15= 0; LCDDR16= 0; LCDDR17= 0; LCDDR18= 0; */
96
//0x00<<PINB; //0x00<<PORTB; //0x00<<PCINT15; //0x00<<PCINT14; //0x00<<PCINT13; //0x00<<PCINT12; //0x00<<PCINT11; //0x00<<PCINT10; //0x00<<PCINT9; //0x00<<PCINT8; //SCK = 0x00; //ss# = 0x00; //PORTB = 0x00; //DDRB |= 0<<DDB5; //PORTO = 0x00; //DDRD = 0xff; //input - Sensors //PORTD =
void forward(void) //PORTB = 00000001;//00001010; PORTB = 0b10001000; void backward(void) PORTB = 0b00100010;void leftturn(void) PORTB = 0b10000010;void rightturn(void) PORTB = 0b00101000;
void stop(void)
97
PORTB = 0b00000000;void left_tmt_right(void)
PORTB = 0b10000000; _delay_ms(20); PORTB = 0b00001000; //_delay_ms(2); //rightturn(); //_delay_ms(200); //stop(); //leftturn(); //_delay_ms(100); //stop();void right_tmt_left(void) PORTB = 0b00001000; _delay_ms(20); PORTB = 0b10000000; //_delay_ms(2); //_delay_ms(2); //leftturn(); //_delay_ms(2); //stop(); //rightturn(); //_delay_ms(100); //stop();
#define BOOL char
#define FALSE 0#define TRUE (!FALSE)//#define NULL 0
// Macro definitions//mtA -
98
// sbi and cbi will not be supported by future avr-libc// version - changed to sbiBF/cbiBF "everywhere"#define sbiBF(port,bit) (port |= (1<<bit)) //set bit in port#define cbiBF(port,bit) (port &= ~(1<<bit)) //clear bit in port//mtE
void Initialization(void);
//#define SENSOR_LEFT 1 //voltage sensor//#define SENSOR_RIGHT 2 //light sensor#define SENSOR_LEFT 4#define SENSOR_RIGHT 6
#ifndef ADC_H#define ADC_Hvoid ADC_init(char input);int ADC_read(void);#endif //ADC_H
//***************************************************************************// File........: BCD.h// Author(s)...: ATMEL Norway// Target(s)...: ATmega169// Compiler....: IAR EWAAVR 2.28a// Description.: AVR Butterfly main module// Revisions...: 1.0// YYYYMMDD - VER. - COMMENT - SIGN.// 20030116 - 1.0 - Created - KS//***************************************************************************
// Function declarationschar CHAR2BCD2(char input);unsigned int CHAR2BCD3(char input);
//// Author(s)...: ATMEL Norway//// Target(s)...: ATmega169//
99
// mt - used for debugging only - may not work
/************************************************************************/// Definitions/************************************************************************/#define LCD_INITIAL_CONTRAST 0x0F#define LCD_TIMER_SEED 3#define LCD_FLASH_SEED 10#define LCD_REGISTER_COUNT 20#define TEXTBUFFER_SIZE 25
#define SCROLLMODE_ONCE 0x01#define SCROLLMODE_LOOP 0x02#define SCROLLMODE_WAVE 0x03
/************************************************************************///MACROS/************************************************************************///active = [TRUE;FALSE]#define LCD_SET_COLON(active) LCD_Data[8] = active
// DEVICE SPECIFIC!!! (ATmega169)#define pLCDREG ((unsigned char *)(0xEC))
// DEVICE SPECIFIC!!! (ATmega169) First LCD segment register#define LCD_CONTRAST_LEVEL(level) LCDCCR=(0x0F & level)
/************************************************************************/// Global variables/************************************************************************/
100
extern volatile char gLCD_Update_Required;extern char LCD_Data[LCD_REGISTER_COUNT];extern char gTextBuffer[TEXTBUFFER_SIZE];extern volatile char gScrollMode;extern char gFlashTimer;extern char gColon;extern volatile signed char gScroll;
/************************************************************************/// Global functions/************************************************************************/void LCD_Init (void);void LCD_WriteDigit(char input, char digit);void LCD_AllSegments(char show);
//// Author(s)...: ATMEL Norway//// Target(s)...: ATmega169//// mt - used for debugging only - may not work
#include <avr/pgmspace.h>//Functions// mt void LCD_puts_f(char __flash *pFlashStr, char scrollmode);void LCD_puts_f(const char *pFlashStr, char scrollmode);void LCD_puts(char *pStr, char scrollmode);void LCD_UpdateRequired(char update, char scrollmode);//void LCD_putc(char digit, char character);void LCD_putc(uint8_t digit, char character);void LCD_Clear(void);void LCD_Colon(char show);void LCD_FlashReset(void);char SetContrast(char input);
// mt - used for debugging only - may not work
#define BOOL char
101
#define FALSE 0#define TRUE (!FALSE)#define NULL 0
#define AUTO 3
void Initialization(void);
#include <avr/io.h>#include <avr/interrupt.h>#include <avr/pgmspace.h>#include <avr/sleep.h>#define F_CPU 8000000UL // 8 MHz#include <util/delay.h>#include <inttypes.h>#include <avr/interrupt.h>#include <string.h>
#include "mboard.h"#include "lcd_driver.h"#include "usart.h"#include "button.h"#include "adc.h"
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX_STRING_SIZE 25
#define DEFAULT_DELAY_CYCLES 3#define SWEEP_SHIFT 7 // shift amount to divide light level to get speeds
char myString[MAX_STRING_SIZE];int stringLen;int offset;
typedef enum INIT, NORMAL, SLEEP, RS232RECV, SPI_MASTER, SPI_SLAVE
102
States;
int delayCount = DEFAULT_DELAY_CYCLES;
States currentState = INIT;
ISR(__vector_default) // do nothing, but make sure the thing does not crash void RS232GetString() int count; char rs232Char;
currentState = RS232RECV; LCD_WriteDigit(' ', 5);
for (count = 0; count < MAX_STRING_SIZE - 1; count++) rs232Char = Usart_Rx(); LCD_WriteDigit(rs232Char, 5); if (rs232Char == '\r') break; myString[count] = rs232Char; stringLen = count; myString[count] = '\0';
void SPI_Reset() DDRB = 0; // set as inputs// PORTB = (1<< PB0); // pull-up on SS PORTB = PINB_MASK | (1 << PB0); SPCR = 0;
void SPI_Init_Slave() DDRB = (1<<DDB3); //Set MISO as output // pull-up on SS, MOSI,SCK PORTB = (1<<PB2) | (1<<PB1) | (1<< PB0) | PINB_MASK;
103
SPCR = 1 << SPE; // enable SPI
void SPI_Init_Master() /* MOSI & SCK & SS output */ PORTB = PINB_MASK | (1<<PB3); // note that PB0 (SS) is low! //PORTB = (1<<PB3); // pull up on MISO // PINB_MASK is from button
AREA OF IMPROVEMENT
The design of this Micro-tank could have been better if we have purchased a better
Microcontroller as well as if we have incorporated the use of an encoder in our design.
Below I will describe each of the improvements that can be done to make the design of
our Micro-Tank the best design available:
104
Microcontroller Problem: The AVR Butterfly has the problems in which we did not
notice at the time we have ordered this microcontroller. These problems are described
below in the order of importance:
Ports are shared
No USB I/O port (for programming)
Finding the Right Compiler
LCD driver not compatible with integer
Interrupts hard to handle
Not enough resources such as books and necessary information
Microcontroller Solutions:
Ignored and Disabled I/O Port Sharing (But we still were not able to do this to all the
ports)
We used Serial to USB converter
We downloaded the GCC (C Compiler)
We have added Drivers from other C compilers itoa()
Unfortunately, we did not have time to use Interrupt and end up with problems
We downloaded the actual Chip's manufacturer's user manual as our only source of
information.
Obviously, the better solution for future is to select a microcontroller that has lots of I/O
ports that are not shared, has USB I/O port as well as it has a great environment for
105
programming and using interrupts. In addition, we need to also consider purchasing a
microcontroller that has plenty of books published from it as well as includes lots of
resources online or anywhere.
Algorithm Update: It would be a good idea if we would have used the Modified Flood-
Filled Algorithm to solve the maze since this algorithm would find the shortest path
toward the center even when navigating fist time in the maze. The implementation of this
algorithm is explained in many text books and it would be the future goal of our team to
change the microcontroller and implement this algorithm.
Use of Encoder: Another major factor for improvement of our Micro-Tank would be to
use an encoder so that along with the sensors, it would have been easier to determine the
position of the micro-tank in the maze and control the speed of the tank.
PCB Manufacturing Layout: It would have been a great idea if we would use the
software such as express PCB to design the layout of our circuit and send it for
manufacturing. The PCB layout would be done through the use of Express PCB software
and the manufacture would do a better job in designing the layout on the board. In this
way, we need no need for soldering he wires together and our design would have been
more professional efficient. It is also important to note that even though we have used
wires for connecting our components, we have used a design that would require the least
amount of wires connected from one component to another. This is due to the fact that
106
the protoboard that we have purchased had several busses and printed connections that
from ground, and Vdd. This has allowed us to configure a way that would use the least
amount of wiring as we have done. (Nevertheless, making the PCB layout through the
use of Express PCB software would have been a better idea) Figure below shows our
wiring connection:
CONCLUSION
107
In conclusion, this project was a very touch project that we have encountered and yet it
was one of the projects that was of the most interest to our group. I want to thank our
mentor professor Jafar for suggesting this project to us and the rest of the design
instructors who have given us more time to accomplish this task. Even though our
Micro-tank did not work the way we wanted to, we will still work on it and try to finish
programming of it.
108
REFERENCES
(1)“ A short history of mazes.” Adrian Fisher Mazes Ltd.
http://www.mazemaker.com/history_mazes.htm.
(2)“The History of Mazes and Labyrinths.” Amazeingart.com.
http://www.amazeingart.com/maze-faqs/Ancient-mazes.html. .
(3)“A brief history of Mazes.” The Amazing Hedge Puzzle.
http://www.btinternet.com/~mazes/history.htm.
(4)“Micromouse Information Center” Peter Harrison
http://micromouse.cannock.ac.uk/history.htm
(5)Supportive Information from Last Year Senior Design Project
(6) http://en.wikipedia.org/wiki/RoHS
(7)“Micromouseinfo.com:” Steve Benkovic
http://www.micromouseinfo.com/introduction/steppers.html
Other Sources of websites used:
http://www.piclist.com/techref/piclist/jal/DrivingBipolarStepperMotors.htmhttp://www.supplyframe.com/campaign/?gclid=CIDNppHB-5ACFRsFagodGwIm1whttp://www.datasheetcatalog.com/datasheets_pdf/A/3/9/6/A3968.shtmlhttp://micromouse.cannock.ac.uk/sensors/side_looking.htmhttp://www.atmel.com/dyn/products/tools_card.asp?tool_id=3146
109
APPENDIX
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
THE END!
Thanks GOD it’s the END