-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmovement.h
234 lines (206 loc) · 7.47 KB
/
movement.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*******************************************************************************
* MSP432 movement file
*
* Description: In this example, the Timer_A module is used to create a precision
* PWM with an adjustable duty cycle. Initial duty cycle is at 10% and will be
* changed when different functions are executed. Interrupt handler for port 5 and
* 6 will be used to balance the car pwm when moving forward.
*
* MSP432P401
* ------------------
* /|\| |
* | | |
* --|RST Port 4.4,4.5|<-- motor a
* | Port 2.4 |<-- ENA
* | |
* | |
* | Port 4.2,4.0|<-- motor b
* | Port 2.5 |<-- ENB
* | |
* | Port 5.5|<-- right wheels encoder
* | Port 6.4|<-- left wheel encoder
* | |
*
*******************************************************************************/
#pragma once
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include "ultrasonic.h"
/*these variables are used for the encoder
to sync up the speed between the two wheels*/
int detectleft = 0;
int detectright = 0;
float ratio = 1;
/* Timer_A PWM Configuration Parameter */
//this config for timer A register 1, p2.4
Timer_A_PWMConfig pwmConfig1 =
{
TIMER_A_CLOCKSOURCE_SMCLK,
TIMER_A_CLOCKSOURCE_DIVIDER_24,
10000,
TIMER_A_CAPTURECOMPARE_REGISTER_1,
TIMER_A_OUTPUTMODE_RESET_SET,
1000
};
//this config for timer A register 2, p2.5
Timer_A_PWMConfig pwmConfig2 =
{
TIMER_A_CLOCKSOURCE_SMCLK,
TIMER_A_CLOCKSOURCE_DIVIDER_24,
10000,
TIMER_A_CAPTURECOMPARE_REGISTER_2,
TIMER_A_OUTPUTMODE_RESET_SET,
1000
};
//this function sets the output on motor for it to go forward
void setOutputOnMotor(){
GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN5);
GPIO_setOutputHighOnPin(GPIO_PORT_P4, GPIO_PIN4);
GPIO_setOutputHighOnPin(GPIO_PORT_P4, GPIO_PIN0);
GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN2);
}
//this function sets the needed ports as output pins for wheel movement
void setMotorPorts(){
//motor A
GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN4);
GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN5);
//motor B
GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN0);
GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN2);
//ENA
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2,
GPIO_PIN4,
GPIO_PRIMARY_MODULE_FUNCTION);
//ENB
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2,
GPIO_PIN5,
GPIO_PRIMARY_MODULE_FUNCTION);
setOutputOnMotor();
}
//this function sets interrupt for port 5 and 6, for the wheel encoders
void setWheelInterupt(){
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P6, GPIO_PIN4);
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN5);
GPIO_clearInterruptFlag(GPIO_PORT_P6, GPIO_PIN4);
GPIO_enableInterrupt(GPIO_PORT_P6, GPIO_PIN4);
GPIO_clearInterruptFlag(GPIO_PORT_P5, GPIO_PIN5);
GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN5);
Interrupt_enableInterrupt(INT_PORT5);
Interrupt_enableInterrupt(INT_PORT6);
Interrupt_enableSleepOnIsrExit();
Interrupt_enableMaster();
}
//this function sets interrupt for port 1, for S1 and S2
void setS1S2Interrupt(){
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);
GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);
GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN4);
GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN4);
GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN4);
Interrupt_enableInterrupt(INT_PORT1);
Interrupt_enableSleepOnIsrExit();
Interrupt_enableMaster();
}
//this function generates PWM for timer A, register 1 and 2
void generatePWN(){
Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig1);
Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig2);
}
//this function toggles the wheels output to change its direction
void changeDirection(){
GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN4);
GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN5);
GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN0);
GPIO_toggleOutputOnPin(GPIO_PORT_P4, GPIO_PIN2);
generatePWN();
}
//this function sets the PWM to 0 to stop the car
void zeroPWN(){
pwmConfig1.dutyCycle = pwmConfig2.dutyCycle = 0;
generatePWN();
}
//this function moves the car forward
void startMoving(){
//check front ultrasonic to see if moving forward is possible
if (getHCSR04DistanceFront() > MIN_DISTANCE){
pwmConfig1.dutyCycle = pwmConfig2.dutyCycle = 5000;
generatePWN();
}
else zeroPWN(); //no space to move in front, stop
}
//this function turns the car left
void rotateCarLeft(){
//check left ultrasonic to see if turning left is possible
if (getHCSR04DistanceLeft() > LR_MIN_DISTANCE){
pwmConfig1.dutyCycle = 6000;
pwmConfig2.dutyCycle = 4000;
generatePWN();
}
else zeroPWN(); //no space to turn left, stop
}
//this function turns the car right
void rotateCarRight(){
//check right ultrasonic to see if turning left is possible
if (getHCSR04DistanceRight() > LR_MIN_DISTANCE){
pwmConfig1.dutyCycle = 4000;
pwmConfig2.dutyCycle = 6000;
generatePWN();
}
else zeroPWN(); //no space to turn right, stop
}
//this function checks all three ultrasonic sensors
//dependent on the current state of the PWM duty cycles
void checkUltraSonic(){
if (pwmConfig1.dutyCycle > 0 && pwmConfig2.dutyCycle > 0){
if (pwmConfig1.dutyCycle == pwmConfig2.dutyCycle &&
getHCSR04DistanceFront() <= MIN_DISTANCE) {
zeroPWN();
}
else if (pwmConfig1.dutyCycle > pwmConfig2.dutyCycle &&
getHCSR04DistanceLeft() <= LR_MIN_DISTANCE) {
zeroPWN();
}
else if (pwmConfig1.dutyCycle < pwmConfig2.dutyCycle &&
getHCSR04DistanceRight() <= LR_MIN_DISTANCE) {
zeroPWN();
}
}
}
//port 6 interrupt handler to sync the wheels speed
void PORT6_IRQHandler(void)
{
//FOR RIGHT SIDE SLAVE
uint32_t status;
status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P6);
detectleft++;
//if left wheel is faster than right wheel
//calculate ratio and set duty cycle for both wheels
if(detectleft !=0 && detectright != 0 ){
if(detectleft == 40){
ratio = detectleft/detectright;
checkUltraSonic();
pwmConfig1.dutyCycle = pwmConfig1.dutyCycle*ratio;
generatePWN();
detectleft=detectright=0;
}
}
GPIO_clearInterruptFlag(GPIO_PORT_P6, status);
}
//port 5 interrupt handler to sync the wheels speed
void PORT5_IRQHandler(void)
{
//FOR LEFTSIDE SLAVE ENCODER
uint32_t status;
status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P5);
detectright++;
if(detectleft !=0 && detectright != 0 ){
if(detectright == 40){
ratio = detectright/detectleft;
checkUltraSonic();
pwmConfig2.dutyCycle = pwmConfig2.dutyCycle*ratio;
generatePWN();
detectleft=detectright=0;
}
}
GPIO_clearInterruptFlag(GPIO_PORT_P5, status);
}