SlideShare a Scribd company logo
Washington State University
EE3234 Microprocessor Systems
Final Project
Line Following Motor Robot Kit with PIC32
Nathan Wendt
11401887
Date: Dec. 11, 2015
1.0 Objective:
The objective of this project was to use the PIC32 motor robot kit and 4 infrared sensors
to identify and react to a small black path (created with electrical tape). The robot must have
two modes of operation: Tracking mode, and search mode. In tracking mode, the robot is to
continue following the line until the sensors cannot detect the line anymore. Once the sensors
have lost the track, the robot enters search mode. In search mode, the robot is to travel a
discrete distance forward, then reverse, then turns 90* and repeats for each North, East, South,
and West directions. While in search mode, at any time that the sensors detect the line, search
mode must be broken and track mode will be entered. As such our robot should be able to
traverse a simple electrical tape course with 90* corners, T crossroads, gaps, and curves.
1.1 Design Requirements:
1. Assemble the robot to the manufacturer’s specifications.
2. Use PmodHB5 H-bridges to control the DC motors.
3. Use the PmodLS1 and IROS sensors to detect the path
4. The robot must contain 2 modes of operation:
-Search mode: Travels 3 ft north, 3 ft reverse, 90* turn and repeat
for East, South, West
-Track mode: While a sensor has detected a line the robot will
follow the line via a logical mapping of commands to the sensor
inputs.
2.0 Introduction:
This lab uses a high-level programming language and compiler, specifically, C in MPLabX.
We used output compare registers in PWM mode without a fault pin to manage the duty cycle
of the motors. There are a total of 5 OC modules. We will use OC2 and OC3. We use the value
of PR2 to determine the PWM period and the value of OCxRS to determine the duty cycle.
Overall this lab can be broken into two pieces: external hardware peripherals and internal
peripherals. The external hardware used are two DC motors, two PmodHB5’s to control the
output of the DC motors, and the PmodLS1 with the 4 IROS infrared detectors. The internal
peripherals used are Timer1 (used as the basis for the interrupt), Timer2 (used to set OC2 and
OC3 PWM periods), Timer3 is used for the operations of the robot.3.0 Design:
3.1 Hardware
The hardware used is the PIC32, two DC motors controlled by H-bridges
(PmodHB5), and the 4 IROS sensors read by the PmodLS1. The duty cycles of the DC
motors are controlled within the output compare modules while the direction of the
motor is controlled by the H-bridge. A diagram of the H-bridge operation is shown on
the page below:
Figure 1: PmodHB5 4 pin operations
The PmodLS1 takes the inputs from the IROS infrared detectors to determine the
path. The IROS emit an infrared signal and assert high if they receive a reflection. As
such, the sensors read 1 over white areas and 0 over the electrical tape. Each of these
inputs is then assigned to a port and then the software of the robot uses conditional
logic to decide on the robot’s operation.
3.2 Software
We used the MPLabX IDE in Assembly to program our pic32. For the most part,
the software of this project was very straight forward. The OC modules were
programmed to operate in PWM mode. OC2 and OC3 each controlled the duty cycle of
one of the motors and were generally set together. The basic motion functions of the
robots were forward, reverse, right, left, and soft right (right and left have the wheels
spinning opposite while soft right had only one wheel spinning). Soft right was needed
to get past T’s and coming across horizontal paths in search mode. Additionally, there
were two functions to control which motion operation was used. These were the search
and track functions. Track used a logical mapping of binary representations of sensor
readings to control whether the robot used forward, right, left, or soft right. In track
mode, the robot simply followed a pattern of forward distance x, reverse distance x, and
turn 90* for each unique direction. The final key piece to the operation of the line-
tracking robot was the timer1 interrupt. Using a timer size of 13500 tics at 10MHz ended
up being the perfect refresh rate for the robot to operate smoothly. The timer1
interrupt contained 4 conditional statements that decided whether the robot was
supposed to start operations, cease operations, operate in track mode, or operate in
search mode.
The duty cycle of the motors is controlled by the OC registers in PWM mode. The figure below
shows how the period of the associated timer, and the OCxRS registers are used to control duty
cycles with pulse width modulation:
Figure 2: Duty cycle specified by OCxRS in PWM mode
4.0 Procedure:
The procedure for this lab is straight forward:
- Construct the motor robot kit drone with the IROS sensors
- Devise and write the C source code to control the robot’s operations
- Calibrate the duty cycles and timings
- Stop the robot from traveling down stairs
5.0 Results and Conclusion:
5.1 Results
Most of the issues I had in this lab were not solved by logical proceedings. The first
attempt to create the code for the robot simply would not do anything for the robot. I
eventually decided to create a new project file and copy over the code and it decided to
register. From the point it was basic debugging and determining the proper timings for
everything. The final product of my efforts was a fast acting and accurate line-following robot
that preferred to turn right. The reason I say this is when all sensors were asserted low (such as
when the robot came across a perpendicular track while in search mode or if a T crossroad was
hit in track mode) the robot’s logic told it to soft turn right (on wheel turn).
5.2 Conclusion:
In hindsight, this project would probably take me 20 minutes to complete so I think that
is a testament to lessons learned. My main issues were in understanding the operation of the
timer interrupts. As funny as it may be, I did not realize that the interrupt was triggered when
the PR limit was reached. Once that registered in my brain, the rest of the project was straight
forward. I also found that calling functions from the interrupt caused inefficiencies in the
robots movements and as such I created a run() function that controlled the function calls while
the timer1 interrupt simply set the robot’s state (just an enumerated type for track, search, and
stop). My final code came out fairly concise at under 300 lines and there is even more
optimization that could be done to the search operation.
Appendix A: Source code
#include <xc.h> /* contains Vector Name/Number Macros */
#include <sys/attribs.h> /* contains __ISR() Macros */
#include <stdio.h>
/* Oscillator Settings
*/
#pragma config FNOSC = PRIPLL // Oscillator selection
#pragma config POSCMOD = EC // Primary oscillator mode
#pragma config FPLLIDIV = DIV_2 // PLL input divider
#pragma config FPLLMUL = MUL_20 // PLL multiplier
#pragma config FPLLODIV = DIV_1 // PLL output divider
#pragma config FPBDIV = DIV_8 // Peripheral bus clock divider
#pragma config FSOSCEN = OFF // Secondary oscillator enable
#pragma config IESO = OFF // Internal/external clock switchover
#pragma config FCKSM = CSDCMD // Clock switching (CSx)/Clock monitor(CMx)
#pragma config OSCIOFNC = OFF // Clock output on OSCO pin enable
#pragma config UPLLEN = ON // USB PLL enable
#pragma config UPLLIDIV = DIV_2 // USB PLL input divider
/* Other Peripheral Device settings
*/
#pragma config FWDTEN = OFF // Watchdog timer enable
#pragma config WDTPS = PS1024 // Watchdog timer post-scaler
#
/* Code Protection settings
*/
#pragma config CP = OFF // Code protection
#pragma config BWP = OFF // Boot flash write protect
#pragma config PWP = OFF // Program flash write protect
//typedef enum{Forward, Stop1, Backward, Stop2, Turn, Stop3} Mode;
typedef enum{Search, Track, Stop} Mode;
Mode mode= Stop;
/** LOCAL PROTOTYPES ********************************************************/
void InitializeSystem();
void Initialize_Timer1();
void Initialize_Timer2();
void Initialize_Timer3();
void Initialize_OC();// Initialize hardware and global variables
void Initialize_IO();
void Initialize_IC();
void Motor_Forward();
void Turning(int speed, int direction);
void Turn1(int speed, int direction);
void Stop_Motion();
void Motor_Backward();
void Search_Mode();
void Track_Mode();
void InitializeSensors();
void Interrupts_enable();
void Run();
/** main() ********************************************************************/
int main(void)
{
InitializeSystem();
Interrupts_enable();
while(1)
{
Run();
}
}
void Run()
{
if (mode == Stop)
while (mode == Stop)
Stop_Motion();
if (mode == Track)
while (mode == Track)
Track_Mode();
if (mode == Search)
while (mode == Search)
Search_Mode();
}
void InitializeSystem(){
Initialize_IO();
Initialize_OC();
Initialize_Timer1();
Initialize_Timer2();
Initialize_Timer3();
}
void Initialize_IO()
{
TRISDbits.TRISD6 =0;
TRISDbits.TRISD7 =0;
TRISAbits.TRISA6 = 1;
TRISAbits.TRISA7 = 1;
TRISDbits.TRISD1 =0;
LATDbits.LATD1 = 0;
TRISDbits.TRISD2 =0;
LATDbits.LATD2 =0;
TRISGbits.TRISG12= 1;
TRISGbits.TRISG13 = 1;
TRISGbits.TRISG14 = 1;
TRISGbits.TRISG15 = 1;
}
void Initialize_OC() // output compare
{
OC2CONbits.OCM =6;
OC2R = 0;
OC2RS = 0;
OC2CONbits.ON=1;
OC3CONbits.OCM =6;
OC3R = 0;
OC3RS = 0;
OC3CONbits.ON = 1;
/* Set Interrupt Controller for multi-vector mode */
}
void Initialize_Timer1(){
T1CONbits.TON = 0;
T1CONbits.TCKPS = 3;
PR1 = 13500;
TMR1 = 0;
T1CONbits.ON =1;
}
void Initialize_Timer2(){
T2CONbits.TON = 0;
T2CONbits.TCKPS = 7;
PR2 = 2000;
TMR2 = 0;
T2CONbits.ON =1;;
}
void Initialize_Timer3(){
T3CONbits.TON = 0;
T3CONbits.TCKPS = 7;
PR3 = 0xFFFF;
TMR3 = 0;
T3CONbits.ON =1;;
}
void Interrupts_enable() //// Interrupt for Timer1
{
IFS0bits.T1IF =0;
IPC1bits.T1IP = 7;
IEC0bits.T1IE = 1;
INTCONbits.MVEC = 1;
__builtin_enable_interrupts();
}
void Motor_Forward(){
LATDbits.LATD6 = 1;
LATDbits.LATD7 = 0;
OC2RS = 500;
OC3RS = 500;
}
void Stop_Motion(){
OC2RS = 0;
OC3RS = 0;
}
void Turning(int speed, int direction){
LATDbits.LATD6 = direction;
LATDbits.LATD7 = direction;
OC2RS = speed;
OC3RS = speed;
}
void Turn1(int speed, int direction)
{
LATDbits.LATD6 = direction;
LATDbits.LATD7 = direction;
OC2RS = 0;
OC3RS = speed;
}
void Motor_Backward(){
LATDbits.LATD6 = 0;
LATDbits.LATD7 = 1;
OC2RS = 500;
OC3RS = 500;
}
void Search_Mode()
{
int i = 0;
for (i=0;i<4;i++)
{
TMR3 = 0;
while (TMR3 < 0xFFFF)
{
if (PORTGbits.RG12 == 0 || PORTGbits.RG13 ==0 || PORTGbits.RG14 == 0|| PORTGbits.RG15 == 0 || mode
== Stop)
{
Stop_Motion();
mode= Track;
break;
}
Motor_Forward();
}
TMR3 = 0;
while (TMR3 < 0xffff)
{
if (PORTGbits.RG12 == 0 || PORTGbits.RG13 ==0 || PORTGbits.RG14 == 0|| PORTGbits.RG15 == 0 || mode
== Stop)
{
Stop_Motion();
mode= Track;
break;
}
Motor_Backward();
}
TMR3 = 0;
while (TMR3 < 0xffff)
{
if (PORTGbits.RG12 == 0 || PORTGbits.RG13 ==0 || PORTGbits.RG14 == 0|| PORTGbits.RG15 == 0 || mode
== Stop)
{
Stop_Motion();
mode= Track;
break;
}
Turning(300, 1);
}
}
}
void Track_Mode()
{
unsigned int SR; //variable for sensor reading
SR = PORTG & 0xF000;
if (SR == 0x2000 || SR == 0x4000 || SR == 0x6000 || SR == 0x9000) //straight
{
Motor_Forward();
}
else if (SR == 0xA000 || SR == 0xC000 || SR == 0xD000 || SR == 0xE000) //soft right
{
Turning(350, 0);
}
else if (SR == 0x3000 || SR == 0x5000 || SR == 0x7000 || SR == 0xB000) //soft left
{
Turning(350, 1);
}
else if (SR == 0x8000) //hard right
{
Turn1(700, 1);
}
else if (SR == 0x1000 || SR == 0x0000) //hard right
{
Turning(700, 1);
}
else
{
Stop_Motion();
}
}
//PORTGbits.RG12 == 0 && PORTGbits.RG13 == 0 && PORTGbits.RG14 == 0 && PORTGbits.RG15 == 0
//PORTGbits.RG12 != 0 && PORTGbits.RG13 != 0 && PORTGbits.RG14 != 0 && PORTGbits.RG15 != 0
void __ISR (_TIMER_1_VECTOR, IPL7SOFT) T1Interrupt(void){
unsigned int SR;
SR = PORTG & 0xF000;
if (PORTAbits.RA7 == 1)
{
mode = Stop;
}
if (mode == Stop && PORTAbits.RA6 == 1)
{
mode = Search;
}
else if (SR == 0xF000 && mode == Track)
{
mode = Search;
}
else if (SR != 0xF000 && mode == Search)
{
mode = Track;
}
IFS0bits.T1IF = 0;
}

More Related Content

PDF
AVR_Course_Day6 external hardware interrupts and analogue to digital converter
PDF
Lecture 2 timers, pwm, state machine IN PIC
PDF
Handling Interrupts in Microchip MCUs
PDF
UART MCU
PDF
89c5131datasheet
PDF
AVR_Course_Day8 motor drive and pwm techniques
PDF
Itsp documentation quadcopter flight controller based on kalman filters
PPTX
AVR_Course_Day6 external hardware interrupts and analogue to digital converter
Lecture 2 timers, pwm, state machine IN PIC
Handling Interrupts in Microchip MCUs
UART MCU
89c5131datasheet
AVR_Course_Day8 motor drive and pwm techniques
Itsp documentation quadcopter flight controller based on kalman filters

What's hot (20)

PDF
Exercises with timers and UART
PDF
PDF
ARM AAE - Intrustion Sets
DOCX
Program, Code of Program and Screen Shot of Output (UNIVERSAL DRIVER USING µ...
PDF
Lecture 4 i2 c bus & interrupts
PDF
Using Timer2 in Microchip MCUs
PDF
Lecture 3a analog to digital converter
PPT
8051 interrupts
PPTX
Plc and hmi baed stenter machine01
DOCX
Arduino 101
PDF
PPT
Plc tutorial
PPT
8051 Inturrpt
PDF
Introduction to Microcontrollers
PPT
8 interrupt 8051
PPTX
PPT
Li354 plc lects 2011a
PPTX
Plc and hmi based stenter machine poster
PPTX
Interrupts programming in embedded C using 8051
Exercises with timers and UART
ARM AAE - Intrustion Sets
Program, Code of Program and Screen Shot of Output (UNIVERSAL DRIVER USING µ...
Lecture 4 i2 c bus & interrupts
Using Timer2 in Microchip MCUs
Lecture 3a analog to digital converter
8051 interrupts
Plc and hmi baed stenter machine01
Arduino 101
Plc tutorial
8051 Inturrpt
Introduction to Microcontrollers
8 interrupt 8051
Li354 plc lects 2011a
Plc and hmi based stenter machine poster
Interrupts programming in embedded C using 8051
Ad

Viewers also liked (10)

PDF
Lettre de l'AQCFRIS 2016 - no 4
DOCX
Proyecto final
PDF
ialpaper3rdpaper-2
ODP
how to make bumper video opensuse using inkscape and synfig
PDF
TR Article CMP3322_040816
PPTX
Typography
PPTX
PwC Case Challenge 2015
PPTX
Capitulo 01 Introducción a las Finanzas Corporativas I
RTF
Gradja ptica (p)
PDF
Modalidades de aprendizagem
Lettre de l'AQCFRIS 2016 - no 4
Proyecto final
ialpaper3rdpaper-2
how to make bumper video opensuse using inkscape and synfig
TR Article CMP3322_040816
Typography
PwC Case Challenge 2015
Capitulo 01 Introducción a las Finanzas Corporativas I
Gradja ptica (p)
Modalidades de aprendizagem
Ad

Similar to project_NathanWendt (20)

PPTX
PC-based mobile robot navigation sytem
PPSX
robotics and its components
PDF
Me 405 final report
PPTX
Robotic hand RGRGGHGHGFHGF FGHGFBNBN TG.pptx
PPT
Autonomous robotics based on simple sensor inputs.
PPTX
Presentation on embedded system and robotics
PDF
Ee6008 mcbsd notes
PPT
ROBOTICS - Introduction to Robotics Microcontroller
PPTX
Quadcopter Presentation
PDF
Microcontroller based speedo meter cum odometer
PDF
EE6008 MBSD
PDF
EE6008 MCBSD - Introduction to PIC Micro controller
PPTX
INDUSTRIAL TRAINING REPORT EMBEDDED SYSTEM.pptx
DOCX
Control Units : Microprogrammed and Hardwired:control unit
PDF
Testing tool for an automated ticketing system
PPT
Robowar
PPT
Introducttion to robotics and microcontrollers
PPT
Security Robot
PPTX
Computer Organization : CPU, Memory and I/O organization
PPTX
Embedded systems and robotics by scmandota
PC-based mobile robot navigation sytem
robotics and its components
Me 405 final report
Robotic hand RGRGGHGHGFHGF FGHGFBNBN TG.pptx
Autonomous robotics based on simple sensor inputs.
Presentation on embedded system and robotics
Ee6008 mcbsd notes
ROBOTICS - Introduction to Robotics Microcontroller
Quadcopter Presentation
Microcontroller based speedo meter cum odometer
EE6008 MBSD
EE6008 MCBSD - Introduction to PIC Micro controller
INDUSTRIAL TRAINING REPORT EMBEDDED SYSTEM.pptx
Control Units : Microprogrammed and Hardwired:control unit
Testing tool for an automated ticketing system
Robowar
Introducttion to robotics and microcontrollers
Security Robot
Computer Organization : CPU, Memory and I/O organization
Embedded systems and robotics by scmandota

project_NathanWendt

  • 1. Washington State University EE3234 Microprocessor Systems Final Project Line Following Motor Robot Kit with PIC32 Nathan Wendt 11401887 Date: Dec. 11, 2015
  • 2. 1.0 Objective: The objective of this project was to use the PIC32 motor robot kit and 4 infrared sensors to identify and react to a small black path (created with electrical tape). The robot must have two modes of operation: Tracking mode, and search mode. In tracking mode, the robot is to continue following the line until the sensors cannot detect the line anymore. Once the sensors have lost the track, the robot enters search mode. In search mode, the robot is to travel a discrete distance forward, then reverse, then turns 90* and repeats for each North, East, South, and West directions. While in search mode, at any time that the sensors detect the line, search mode must be broken and track mode will be entered. As such our robot should be able to traverse a simple electrical tape course with 90* corners, T crossroads, gaps, and curves. 1.1 Design Requirements: 1. Assemble the robot to the manufacturer’s specifications. 2. Use PmodHB5 H-bridges to control the DC motors. 3. Use the PmodLS1 and IROS sensors to detect the path 4. The robot must contain 2 modes of operation: -Search mode: Travels 3 ft north, 3 ft reverse, 90* turn and repeat for East, South, West -Track mode: While a sensor has detected a line the robot will follow the line via a logical mapping of commands to the sensor inputs. 2.0 Introduction: This lab uses a high-level programming language and compiler, specifically, C in MPLabX. We used output compare registers in PWM mode without a fault pin to manage the duty cycle of the motors. There are a total of 5 OC modules. We will use OC2 and OC3. We use the value of PR2 to determine the PWM period and the value of OCxRS to determine the duty cycle. Overall this lab can be broken into two pieces: external hardware peripherals and internal peripherals. The external hardware used are two DC motors, two PmodHB5’s to control the output of the DC motors, and the PmodLS1 with the 4 IROS infrared detectors. The internal peripherals used are Timer1 (used as the basis for the interrupt), Timer2 (used to set OC2 and OC3 PWM periods), Timer3 is used for the operations of the robot.3.0 Design: 3.1 Hardware The hardware used is the PIC32, two DC motors controlled by H-bridges (PmodHB5), and the 4 IROS sensors read by the PmodLS1. The duty cycles of the DC motors are controlled within the output compare modules while the direction of the motor is controlled by the H-bridge. A diagram of the H-bridge operation is shown on the page below:
  • 3. Figure 1: PmodHB5 4 pin operations The PmodLS1 takes the inputs from the IROS infrared detectors to determine the path. The IROS emit an infrared signal and assert high if they receive a reflection. As such, the sensors read 1 over white areas and 0 over the electrical tape. Each of these inputs is then assigned to a port and then the software of the robot uses conditional logic to decide on the robot’s operation. 3.2 Software We used the MPLabX IDE in Assembly to program our pic32. For the most part, the software of this project was very straight forward. The OC modules were programmed to operate in PWM mode. OC2 and OC3 each controlled the duty cycle of one of the motors and were generally set together. The basic motion functions of the robots were forward, reverse, right, left, and soft right (right and left have the wheels spinning opposite while soft right had only one wheel spinning). Soft right was needed to get past T’s and coming across horizontal paths in search mode. Additionally, there were two functions to control which motion operation was used. These were the search and track functions. Track used a logical mapping of binary representations of sensor readings to control whether the robot used forward, right, left, or soft right. In track mode, the robot simply followed a pattern of forward distance x, reverse distance x, and turn 90* for each unique direction. The final key piece to the operation of the line- tracking robot was the timer1 interrupt. Using a timer size of 13500 tics at 10MHz ended up being the perfect refresh rate for the robot to operate smoothly. The timer1 interrupt contained 4 conditional statements that decided whether the robot was supposed to start operations, cease operations, operate in track mode, or operate in search mode.
  • 4. The duty cycle of the motors is controlled by the OC registers in PWM mode. The figure below shows how the period of the associated timer, and the OCxRS registers are used to control duty cycles with pulse width modulation: Figure 2: Duty cycle specified by OCxRS in PWM mode 4.0 Procedure: The procedure for this lab is straight forward: - Construct the motor robot kit drone with the IROS sensors - Devise and write the C source code to control the robot’s operations - Calibrate the duty cycles and timings - Stop the robot from traveling down stairs 5.0 Results and Conclusion: 5.1 Results Most of the issues I had in this lab were not solved by logical proceedings. The first attempt to create the code for the robot simply would not do anything for the robot. I eventually decided to create a new project file and copy over the code and it decided to register. From the point it was basic debugging and determining the proper timings for everything. The final product of my efforts was a fast acting and accurate line-following robot that preferred to turn right. The reason I say this is when all sensors were asserted low (such as when the robot came across a perpendicular track while in search mode or if a T crossroad was hit in track mode) the robot’s logic told it to soft turn right (on wheel turn). 5.2 Conclusion: In hindsight, this project would probably take me 20 minutes to complete so I think that is a testament to lessons learned. My main issues were in understanding the operation of the timer interrupts. As funny as it may be, I did not realize that the interrupt was triggered when the PR limit was reached. Once that registered in my brain, the rest of the project was straight forward. I also found that calling functions from the interrupt caused inefficiencies in the robots movements and as such I created a run() function that controlled the function calls while
  • 5. the timer1 interrupt simply set the robot’s state (just an enumerated type for track, search, and stop). My final code came out fairly concise at under 300 lines and there is even more optimization that could be done to the search operation.
  • 6. Appendix A: Source code #include <xc.h> /* contains Vector Name/Number Macros */ #include <sys/attribs.h> /* contains __ISR() Macros */ #include <stdio.h> /* Oscillator Settings */ #pragma config FNOSC = PRIPLL // Oscillator selection #pragma config POSCMOD = EC // Primary oscillator mode #pragma config FPLLIDIV = DIV_2 // PLL input divider #pragma config FPLLMUL = MUL_20 // PLL multiplier #pragma config FPLLODIV = DIV_1 // PLL output divider #pragma config FPBDIV = DIV_8 // Peripheral bus clock divider #pragma config FSOSCEN = OFF // Secondary oscillator enable #pragma config IESO = OFF // Internal/external clock switchover #pragma config FCKSM = CSDCMD // Clock switching (CSx)/Clock monitor(CMx) #pragma config OSCIOFNC = OFF // Clock output on OSCO pin enable #pragma config UPLLEN = ON // USB PLL enable #pragma config UPLLIDIV = DIV_2 // USB PLL input divider /* Other Peripheral Device settings */ #pragma config FWDTEN = OFF // Watchdog timer enable #pragma config WDTPS = PS1024 // Watchdog timer post-scaler # /* Code Protection settings */ #pragma config CP = OFF // Code protection #pragma config BWP = OFF // Boot flash write protect #pragma config PWP = OFF // Program flash write protect //typedef enum{Forward, Stop1, Backward, Stop2, Turn, Stop3} Mode; typedef enum{Search, Track, Stop} Mode; Mode mode= Stop; /** LOCAL PROTOTYPES ********************************************************/ void InitializeSystem(); void Initialize_Timer1(); void Initialize_Timer2(); void Initialize_Timer3(); void Initialize_OC();// Initialize hardware and global variables void Initialize_IO(); void Initialize_IC();
  • 7. void Motor_Forward(); void Turning(int speed, int direction); void Turn1(int speed, int direction); void Stop_Motion(); void Motor_Backward(); void Search_Mode(); void Track_Mode(); void InitializeSensors(); void Interrupts_enable(); void Run(); /** main() ********************************************************************/ int main(void) { InitializeSystem(); Interrupts_enable(); while(1) { Run(); } } void Run() { if (mode == Stop) while (mode == Stop) Stop_Motion(); if (mode == Track) while (mode == Track) Track_Mode(); if (mode == Search) while (mode == Search) Search_Mode(); } void InitializeSystem(){ Initialize_IO(); Initialize_OC(); Initialize_Timer1(); Initialize_Timer2(); Initialize_Timer3(); }
  • 8. void Initialize_IO() { TRISDbits.TRISD6 =0; TRISDbits.TRISD7 =0; TRISAbits.TRISA6 = 1; TRISAbits.TRISA7 = 1; TRISDbits.TRISD1 =0; LATDbits.LATD1 = 0; TRISDbits.TRISD2 =0; LATDbits.LATD2 =0; TRISGbits.TRISG12= 1; TRISGbits.TRISG13 = 1; TRISGbits.TRISG14 = 1; TRISGbits.TRISG15 = 1; } void Initialize_OC() // output compare { OC2CONbits.OCM =6; OC2R = 0; OC2RS = 0; OC2CONbits.ON=1; OC3CONbits.OCM =6; OC3R = 0; OC3RS = 0; OC3CONbits.ON = 1; /* Set Interrupt Controller for multi-vector mode */ } void Initialize_Timer1(){ T1CONbits.TON = 0; T1CONbits.TCKPS = 3; PR1 = 13500; TMR1 = 0; T1CONbits.ON =1; } void Initialize_Timer2(){ T2CONbits.TON = 0; T2CONbits.TCKPS = 7; PR2 = 2000; TMR2 = 0;
  • 9. T2CONbits.ON =1;; } void Initialize_Timer3(){ T3CONbits.TON = 0; T3CONbits.TCKPS = 7; PR3 = 0xFFFF; TMR3 = 0; T3CONbits.ON =1;; } void Interrupts_enable() //// Interrupt for Timer1 { IFS0bits.T1IF =0; IPC1bits.T1IP = 7; IEC0bits.T1IE = 1; INTCONbits.MVEC = 1; __builtin_enable_interrupts(); } void Motor_Forward(){ LATDbits.LATD6 = 1; LATDbits.LATD7 = 0; OC2RS = 500; OC3RS = 500; } void Stop_Motion(){ OC2RS = 0; OC3RS = 0; } void Turning(int speed, int direction){ LATDbits.LATD6 = direction; LATDbits.LATD7 = direction; OC2RS = speed; OC3RS = speed; } void Turn1(int speed, int direction) { LATDbits.LATD6 = direction; LATDbits.LATD7 = direction; OC2RS = 0; OC3RS = speed; } void Motor_Backward(){
  • 10. LATDbits.LATD6 = 0; LATDbits.LATD7 = 1; OC2RS = 500; OC3RS = 500; } void Search_Mode() { int i = 0; for (i=0;i<4;i++) { TMR3 = 0; while (TMR3 < 0xFFFF) { if (PORTGbits.RG12 == 0 || PORTGbits.RG13 ==0 || PORTGbits.RG14 == 0|| PORTGbits.RG15 == 0 || mode == Stop) { Stop_Motion(); mode= Track; break; } Motor_Forward(); } TMR3 = 0; while (TMR3 < 0xffff) { if (PORTGbits.RG12 == 0 || PORTGbits.RG13 ==0 || PORTGbits.RG14 == 0|| PORTGbits.RG15 == 0 || mode == Stop) { Stop_Motion(); mode= Track; break; } Motor_Backward(); } TMR3 = 0; while (TMR3 < 0xffff) { if (PORTGbits.RG12 == 0 || PORTGbits.RG13 ==0 || PORTGbits.RG14 == 0|| PORTGbits.RG15 == 0 || mode == Stop) { Stop_Motion(); mode= Track;
  • 11. break; } Turning(300, 1); } } } void Track_Mode() { unsigned int SR; //variable for sensor reading SR = PORTG & 0xF000; if (SR == 0x2000 || SR == 0x4000 || SR == 0x6000 || SR == 0x9000) //straight { Motor_Forward(); } else if (SR == 0xA000 || SR == 0xC000 || SR == 0xD000 || SR == 0xE000) //soft right { Turning(350, 0); } else if (SR == 0x3000 || SR == 0x5000 || SR == 0x7000 || SR == 0xB000) //soft left { Turning(350, 1); } else if (SR == 0x8000) //hard right { Turn1(700, 1); } else if (SR == 0x1000 || SR == 0x0000) //hard right { Turning(700, 1); } else { Stop_Motion(); } } //PORTGbits.RG12 == 0 && PORTGbits.RG13 == 0 && PORTGbits.RG14 == 0 && PORTGbits.RG15 == 0 //PORTGbits.RG12 != 0 && PORTGbits.RG13 != 0 && PORTGbits.RG14 != 0 && PORTGbits.RG15 != 0 void __ISR (_TIMER_1_VECTOR, IPL7SOFT) T1Interrupt(void){ unsigned int SR; SR = PORTG & 0xF000; if (PORTAbits.RA7 == 1) {
  • 12. mode = Stop; } if (mode == Stop && PORTAbits.RA6 == 1) { mode = Search; } else if (SR == 0xF000 && mode == Track) { mode = Search; } else if (SR != 0xF000 && mode == Search) { mode = Track; } IFS0bits.T1IF = 0; }