SlideShare une entreprise Scribd logo
1  sur  12
Télécharger pour lire hors ligne
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;
}

Contenu connexe

Tendances (20)

Exercises with timers and UART
Exercises with timers and UARTExercises with timers and UART
Exercises with timers and UART
 
ATMEGA-169P.pdf
ATMEGA-169P.pdfATMEGA-169P.pdf
ATMEGA-169P.pdf
 
ARM AAE - Intrustion Sets
ARM AAE - Intrustion SetsARM AAE - Intrustion Sets
ARM AAE - Intrustion Sets
 
Program, Code of Program and Screen Shot of Output (UNIVERSAL DRIVER USING µ...
Program, Code of Program and  Screen Shot of Output (UNIVERSAL DRIVER USING µ...Program, Code of Program and  Screen Shot of Output (UNIVERSAL DRIVER USING µ...
Program, Code of Program and Screen Shot of Output (UNIVERSAL DRIVER USING µ...
 
Lecture 4 i2 c bus & interrupts
Lecture 4   i2 c bus & interruptsLecture 4   i2 c bus & interrupts
Lecture 4 i2 c bus & interrupts
 
Class8
Class8Class8
Class8
 
Using Timer2 in Microchip MCUs
Using Timer2 in Microchip MCUsUsing Timer2 in Microchip MCUs
Using Timer2 in Microchip MCUs
 
Lecture 3a analog to digital converter
Lecture 3a   analog to digital converterLecture 3a   analog to digital converter
Lecture 3a analog to digital converter
 
8051 interrupts
8051 interrupts8051 interrupts
8051 interrupts
 
Plc and hmi baed stenter machine01
Plc and hmi baed stenter machine01Plc and hmi baed stenter machine01
Plc and hmi baed stenter machine01
 
Arduino 101
Arduino 101Arduino 101
Arduino 101
 
8051 Timers
8051 Timers8051 Timers
8051 Timers
 
Plc tutorial
Plc tutorialPlc tutorial
Plc tutorial
 
8051 Inturrpt
8051 Inturrpt8051 Inturrpt
8051 Inturrpt
 
Introduction to Microcontrollers
Introduction to MicrocontrollersIntroduction to Microcontrollers
Introduction to Microcontrollers
 
8 interrupt 8051
8 interrupt 80518 interrupt 8051
8 interrupt 8051
 
Jtagppt
JtagpptJtagppt
Jtagppt
 
Li354 plc lects 2011a
Li354  plc lects 2011aLi354  plc lects 2011a
Li354 plc lects 2011a
 
Plc and hmi based stenter machine poster
Plc and hmi based stenter machine posterPlc and hmi based stenter machine poster
Plc and hmi based stenter machine poster
 
Interrupts programming in embedded C using 8051
Interrupts programming in embedded C using 8051Interrupts programming in embedded C using 8051
Interrupts programming in embedded C using 8051
 

En vedette

Lettre de l'AQCFRIS 2016 - no 4
Lettre de l'AQCFRIS 2016 - no 4Lettre de l'AQCFRIS 2016 - no 4
Lettre de l'AQCFRIS 2016 - no 4Parazelli
 
ialpaper3rdpaper-2
ialpaper3rdpaper-2ialpaper3rdpaper-2
ialpaper3rdpaper-2Philip Azour
 
how to make bumper video opensuse using inkscape and synfig
how to make bumper video opensuse using inkscape and synfighow to make bumper video opensuse using inkscape and synfig
how to make bumper video opensuse using inkscape and synfigMuhammad Irfan
 
TR Article CMP3322_040816
TR Article CMP3322_040816TR Article CMP3322_040816
TR Article CMP3322_040816Amanda Hollis
 
PwC Case Challenge 2015
PwC Case Challenge 2015PwC Case Challenge 2015
PwC Case Challenge 2015Linda Wei
 
Capitulo 01 Introducción a las Finanzas Corporativas I
Capitulo 01 Introducción a las Finanzas Corporativas ICapitulo 01 Introducción a las Finanzas Corporativas I
Capitulo 01 Introducción a las Finanzas Corporativas IAndres Altamirano
 

En vedette (10)

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

Similaire à project_NathanWendt

PC-based mobile robot navigation sytem
PC-based mobile robot navigation sytemPC-based mobile robot navigation sytem
PC-based mobile robot navigation sytemANKIT SURATI
 
robotics and its components
robotics and its componentsrobotics and its components
robotics and its componentsAmandeep Kaur
 
Autonomous robotics based on simple sensor inputs.
Autonomous robotics based on simplesensor inputs.Autonomous robotics based on simplesensor inputs.
Autonomous robotics based on simple sensor inputs. sathish sak
 
Presentation on embedded system and robotics
Presentation on embedded system and roboticsPresentation on embedded system and robotics
Presentation on embedded system and roboticsArpit Upadhyay
 
Microcontroller based speedo meter cum odometer
Microcontroller based speedo meter cum odometerMicrocontroller based speedo meter cum odometer
Microcontroller based speedo meter cum odometerNexus
 
EE6008 MCBSD - Introduction to PIC Micro controller
EE6008 MCBSD - Introduction to PIC Micro controller EE6008 MCBSD - Introduction to PIC Micro controller
EE6008 MCBSD - Introduction to PIC Micro controller pavihari
 
INDUSTRIAL TRAINING REPORT EMBEDDED SYSTEM.pptx
INDUSTRIAL TRAINING REPORT EMBEDDED SYSTEM.pptxINDUSTRIAL TRAINING REPORT EMBEDDED SYSTEM.pptx
INDUSTRIAL TRAINING REPORT EMBEDDED SYSTEM.pptxMeghdeepSingh
 
Control Units : Microprogrammed and Hardwired:control unit
Control Units : Microprogrammed and Hardwired:control unitControl Units : Microprogrammed and Hardwired:control unit
Control Units : Microprogrammed and Hardwired:control unitabdosaidgkv
 
Testing tool for an automated ticketing system
Testing tool for an automated ticketing systemTesting tool for an automated ticketing system
Testing tool for an automated ticketing systemVladimirZitoli
 
Introducttion to robotics and microcontrollers
Introducttion to robotics and microcontrollersIntroducttion to robotics and microcontrollers
Introducttion to robotics and microcontrollersSandeep Kamath
 
Security Robot
Security RobotSecurity Robot
Security Robotdiego5wh
 
Computer Organization : CPU, Memory and I/O organization
Computer Organization : CPU, Memory and I/O organizationComputer Organization : CPU, Memory and I/O organization
Computer Organization : CPU, Memory and I/O organizationAmrutaMehata
 
Embedded systems and robotics by scmandota
Embedded systems and robotics by scmandotaEmbedded systems and robotics by scmandota
Embedded systems and robotics by scmandotascmandota
 

Similaire à project_NathanWendt (20)

PC-based mobile robot navigation sytem
PC-based mobile robot navigation sytemPC-based mobile robot navigation sytem
PC-based mobile robot navigation sytem
 
robotics and its components
robotics and its componentsrobotics and its components
robotics and its components
 
Me 405 final report
Me 405 final reportMe 405 final report
Me 405 final report
 
Autonomous robotics based on simple sensor inputs.
Autonomous robotics based on simplesensor inputs.Autonomous robotics based on simplesensor inputs.
Autonomous robotics based on simple sensor inputs.
 
Presentation on embedded system and robotics
Presentation on embedded system and roboticsPresentation on embedded system and robotics
Presentation on embedded system and robotics
 
Ee6008 mcbsd notes
Ee6008 mcbsd notesEe6008 mcbsd notes
Ee6008 mcbsd notes
 
ROBOTICS - Introduction to Robotics Microcontroller
ROBOTICS -  Introduction to Robotics MicrocontrollerROBOTICS -  Introduction to Robotics Microcontroller
ROBOTICS - Introduction to Robotics Microcontroller
 
Quadcopter Presentation
Quadcopter PresentationQuadcopter Presentation
Quadcopter Presentation
 
Microcontroller based speedo meter cum odometer
Microcontroller based speedo meter cum odometerMicrocontroller based speedo meter cum odometer
Microcontroller based speedo meter cum odometer
 
EE6008 MBSD
EE6008  MBSDEE6008  MBSD
EE6008 MBSD
 
EE6008 MCBSD - Introduction to PIC Micro controller
EE6008 MCBSD - Introduction to PIC Micro controller EE6008 MCBSD - Introduction to PIC Micro controller
EE6008 MCBSD - Introduction to PIC Micro controller
 
INDUSTRIAL TRAINING REPORT EMBEDDED SYSTEM.pptx
INDUSTRIAL TRAINING REPORT EMBEDDED SYSTEM.pptxINDUSTRIAL TRAINING REPORT EMBEDDED SYSTEM.pptx
INDUSTRIAL TRAINING REPORT EMBEDDED SYSTEM.pptx
 
Control Units : Microprogrammed and Hardwired:control unit
Control Units : Microprogrammed and Hardwired:control unitControl Units : Microprogrammed and Hardwired:control unit
Control Units : Microprogrammed and Hardwired:control unit
 
Testing tool for an automated ticketing system
Testing tool for an automated ticketing systemTesting tool for an automated ticketing system
Testing tool for an automated ticketing system
 
Robowar
RobowarRobowar
Robowar
 
Introducttion to robotics and microcontrollers
Introducttion to robotics and microcontrollersIntroducttion to robotics and microcontrollers
Introducttion to robotics and microcontrollers
 
Security Robot
Security RobotSecurity Robot
Security Robot
 
Computer Organization : CPU, Memory and I/O organization
Computer Organization : CPU, Memory and I/O organizationComputer Organization : CPU, Memory and I/O organization
Computer Organization : CPU, Memory and I/O organization
 
Embedded systems and robotics by scmandota
Embedded systems and robotics by scmandotaEmbedded systems and robotics by scmandota
Embedded systems and robotics by scmandota
 
Micro controller
Micro controllerMicro controller
Micro controller
 

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; }