-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
180 lines (164 loc) · 4.93 KB
/
main.c
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
#include"UTIL/STD_TYPES.h"
#include"MCAL/PORT_interface.h"
#include"MCAL/DIO_interface.h"
#include "MCAL/TIMER/TIMER_interface.h"
#include "MCAL/TIMER/TIMER_reg.h"
#include "UTIL/BIT_MATH.h"
#include "MCAL/PWM/PWM_interface.h"
#include <util/delay.h>
#include "MCAL/INTERRUPT/GIE_interface.h"
#include "HAL/CLCD/CLCD_interface.h"
#include "HAL/USS/USS_interface.h"
#include "HAL/SERVO/SERVO_interface.h"
#include "HAL/MOTOR/MOTOR_interface.h"
#define CRITICAL_u8_DISTANCE 80
#define CAR_u16_OBSTCALE_SKIP_TIME 1000
#define SERVO_u8_DELAY 200
struct Motor MOTOR1, MOTOR2;
uint8 MoveServo180Degrees();
void voidInitMotors();
void voidCheckObstacle_MoveAccordingly(uint32 Copy_32USSDistance, uint8 Copy_u8Dirction);
uint8 MoveServo180Degrees(){
/* This function moves the servo 0 to 90 to 180 and back
* based on the last angle stored in Local_u8CurrentAngle static variable */
static uint8 Local_u8CurrentAngle = 0;
/* inc_flag is used ro rotate the servo on the
* specified angles Clock wise or anti clock wise */
static uint8 Local_u8IncFlag = 1;
uint8 Local_u8Direction = ' ';
if(Local_u8IncFlag)
Local_u8CurrentAngle += 50;
else
Local_u8CurrentAngle -= 50;
switch(Local_u8CurrentAngle){
case 0:
Local_u8Direction = 'L';
break;
case 50:
Local_u8Direction = 'C';
break;
case 100:
Local_u8Direction = 'R';
break;
default:
Local_u8Direction = ' ';
break;
}
/* rotate servo according to changes */
SERVO_voidRotateToAngle(Local_u8CurrentAngle);
if(Local_u8CurrentAngle <= 1 || Local_u8CurrentAngle >= 100)
Local_u8IncFlag = !Local_u8IncFlag;
else{
/* nothing */
}
_delay_ms(SERVO_u8_DELAY);
return Local_u8Direction;
}
void voidInitMotors(){
/* sets port and pin numbers of the connected motors */
MOTOR1.motor_u8_port = DIO_u8_PORTB;
MOTOR1.motor_u8_pin1 = DIO_u8_PIN4;
MOTOR1.motor_u8_pin2 = DIO_u8_PIN5;
MOTOR2.motor_u8_port = DIO_u8_PORTB;
MOTOR2.motor_u8_pin1 = DIO_u8_PIN6;
MOTOR2.motor_u8_pin2 = DIO_u8_PIN7;
}
void voidCheckObstacle_MoveAccordingly(uint32 Copy_32USSDistance, uint8 Copy_u8Dirction){
/* check if ultrasonic measured distance (Copy_32USSDistance) lower than the critical value
* if true then move according to the direction of Servo motor (Copy_u8Dirction)
*/
if(Copy_32USSDistance <= CRITICAL_u8_DISTANCE){
MOTOR_voidSetMotorsPWMDutyCycle(100);
switch(Copy_u8Dirction){
case 'L':
MOTOR_u8MoveMotor(MOTOR1, MOTOR_u8_ANTICLOCKWISE);
MOTOR_voidStopMotor(MOTOR2);
_delay_ms(CAR_u16_OBSTCALE_SKIP_TIME);
break;
case 'R':
MOTOR_u8MoveMotor(MOTOR2, MOTOR_u8_ANTICLOCKWISE);
MOTOR_voidStopMotor(MOTOR1);
_delay_ms(CAR_u16_OBSTCALE_SKIP_TIME);
break;
case 'C':
MOTOR_u8MoveMotor(MOTOR1, MOTOR_u8_ANTICLOCKWISE);
MOTOR_u8MoveMotor(MOTOR2, MOTOR_u8_CLOCKWISE);
_delay_ms(CAR_u16_OBSTCALE_SKIP_TIME);
}
}
else{
/* set speed of the motor by chaning dutycycle */
MOTOR_voidSetMotorsPWMDutyCycle(100);
MOTOR_u8MoveMotor(MOTOR1, MOTOR_u8_CLOCKWISE);
MOTOR_u8MoveMotor(MOTOR2, MOTOR_u8_CLOCKWISE);
}
}
char* charptrCarDirection(uint32 Copy_32USSDistance, uint8 Copy_u8Dirction){
/* this function returns a string of 3 letters descriping the current
* direction the car is taking
*/
static char Local_carDir[3] = "F \0";
Local_carDir[0] = 'F';
Local_carDir[1] = ' ';
if(Copy_32USSDistance <= CRITICAL_u8_DISTANCE){
switch(Copy_u8Dirction){
case 'L':
/* Backward - Right */
Local_carDir[0] = 'B';
Local_carDir[1] = 'R';
break;
case 'R':
/* Backward - Left */
Local_carDir[0] = 'B';
Local_carDir[1] = 'L';
break;
case 'C':
/* rotate arount it self */
Local_carDir[0] = 'R';
Local_carDir[1] = 'R';
break;
}
}
Local_carDir[2] = '\0';
return Local_carDir;
}
int main(){
/* Init directions and initial values configured in PORT_config.h file */
PORT_voidInit();
/* Init CLCD 8bit mode */
CLCD_voidInit();
/* init ultra sonic sensor
* - enables Global interrupt
* - enables overflow interrupt for timer 1
* - start count
*/
USS_voidInit();
/* init PWM of timer0 fast PWM, inverted */
PWM0_VoidInit();
/* Call Motor init function in main file */
voidInitMotors();
while(1){
/* Moves the servo 0 to 90 to 180 and back */
uint8 Local_u8ServoDirection = MoveServo180Degrees();
/* get distance in cm from ultra sonic sensor */
uint32 Local_u32distance = USS_u32GetDistance();
CLCD_sendString("distance:");
/* print distance of ultrasonic to CLCD */
CLCD_sendNumebr((uint32)Local_u32distance);
/* Newline */
CLCD_voidGoToXY(0, 1);
CLCD_sendString("srvo:");
/* print current servo direction on CLCD */
CLCD_voidSendData(Local_u8ServoDirection);
CLCD_sendString(" dir:");
char* Local_charptrCarDir = charptrCarDirection
(Local_u32distance, Local_u8ServoDirection);
/* print current car direction to CLCD */
CLCD_sendString(Local_charptrCarDir);
voidCheckObstacle_MoveAccordingly(Local_u32distance, Local_u8ServoDirection);
_delay_ms(500);
/* clear CLCD */
CLCD_voidClearDisplay();
}
return 0;
}