-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAMACar.ino
165 lines (143 loc) · 4.13 KB
/
AMACar.ino
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
/*
* 30% - cea mai mica viteza
* 100% - cea mai mare viteza
* 0, 1, 2 - stanga dreapta
*/
#include "AMADefines.h"
#include "AMADcMotor.h"
#include "AMAServoMotor.h"
#include "AMABluetooth.h"
using namespace AMACar;
AMADcMotor *motorRight = NULL, *motorLeft = NULL;
AMAServoMotor *servo = NULL;
AMABluetooth *bluetooth = NULL;
int cmd, dutyCycle, servoIndex, motorIndex;
ulong time_last_command;
int *directionPins = new int[2]{ DC_MOTOR_BUS_PIN_MSB, DC_MOTOR_BUS_PIN_LSB };
byte *servoDirs = new byte[3] { SERVO_MOTOR_LEFT, SERVO_MOTOR_FRONT, SERVO_MOTOR_RIGHT };
byte *motorDirs = new byte[3] { DC_MOTOR_FORWARD, DC_MOTOR_STOP, DC_MOTOR_BACKWARD };
bool between(int a, int x, int b);
int minValue(int x, int y);
void test_servo();
void setup()
{
Serial.begin(DEFAULT_BAUD_RATE);
delay(10);
motorRight = new AMADcMotor(DC_MOTOR_RIGHT_PWM_PIN, CAR_SPEED_LOWEST_PERCENT, 2, directionPins);
delay(100);
motorLeft = new AMADcMotor(DC_MOTOR_LEFT_PWM_PIN, CAR_SPEED_LOWEST_PERCENT, 2, directionPins);
delay(100);
servo = new AMAServoMotor(SERVO_MOTOR_PWM_PIN);
delay(100);
bluetooth = new AMABluetooth(ARDUINO_BT_PIN_RX, ARDUINO_BT_PIN_TX);
delay(100);
dutyCycle = map(0,
CAR_SPEED_LOWEST_VALUE, CAR_SPEED_HIGHEST_VALUE,
CAR_SPEED_LOWEST_PERCENT, CAR_SPEED_HIGHEST_PERCENT);
Serial.println("loop started");
}
void setMotorsSpeed(const byte servoValue, const byte dutyCycle) // left or right
{
int turningDutyCycle = minValue(dutyCycle + DC_MOTOR_TURN_SPEEDUP, CAR_SPEED_HIGHEST_PERCENT);
if(servoValue == SERVO_MOTOR_LEFT)
{
motorRight->setDutyCycle(turningDutyCycle);
}
else if(servoValue == SERVO_MOTOR_FRONT)
{
motorLeft->setDutyCycle(dutyCycle);
motorRight->setDutyCycle(dutyCycle);
}
else if(servoValue == SERVO_MOTOR_RIGHT)
{
motorLeft->setDutyCycle(turningDutyCycle);
}
}
void stopCar()
{
servo->setDirection(SERVO_MOTOR_FRONT);
motorLeft->setMovement(DC_MOTOR_STOP);
motorRight->setMovement(DC_MOTOR_STOP);
}
void loop()
{
cmd = bluetooth->receive();
if (cmd != -1)
{
time_last_command = millis();
if (between(CAR_SPEED_LOWEST_VALUE, cmd, CAR_SPEED_HIGHEST_VALUE)) // speed command
{
//map(value, fromLow, fromHigh, toLow, toHigh)
dutyCycle = map(cmd,
CAR_SPEED_LOWEST_VALUE, CAR_SPEED_HIGHEST_VALUE,
CAR_SPEED_LOWEST_PERCENT, CAR_SPEED_HIGHEST_PERCENT);
setMotorsSpeed(SERVO_MOTOR_FRONT, dutyCycle);
// motorLeft->setDutyCycle(dutyCycle);
// motorRight->setDutyCycle(dutyCycle);
}
else if (between(11, cmd, 13) || between(21, cmd, 23) || between(31, cmd, 33)) // direction command
{
if (cmd == 22) // special case when everything needs to stop
{
stopCar();
}
else
{
motorIndex = (cmd / 10) - 1; // tens digit encodes direction (forward/backward)
servoIndex = (cmd % 10) - 1; // units digit encodes steering (left/right)
servo->setDirection(servoDirs[servoIndex]);
motorLeft->setMovement(motorDirs[motorIndex]);
motorRight->setMovement(motorDirs[motorIndex]);
setMotorsSpeed(servoDirs[servoIndex], dutyCycle);
}
}
else if (between(40, cmd, 41)) // front lights on/off
{
digitalWrite(LIGHTS_FRONT_PIN, cmd % 10);
}
else if (between(50, cmd, 51)) // back lights on/off
{
digitalWrite(LIGHTS_BACK_PIN, cmd % 10);
}
else if (between(60, cmd, 61)) // horn on/off
{
if (cmd == 60)
noTone(BUZZER_PIN);
else if (cmd == 61)
tone(BUZZER_PIN, BUZZER_FREQ_HZ);
}
}
// stop car when time between two consecutive commands is higher than predefined threshold
if(millis() - time_last_command > TIMEOUT_BETWEEN_COMMANDS_MS)
{
stopCar();
}
}
bool between(int a, int x, int b)
{
return (a <= x && x <= b);
}
int minValue(int x, int y)
{
return ((x < y) ? x : y);
}
void test_servo()
{
cmd = bluetooth->receive();
if (cmd != -1)
{
Serial.println(cmd);
if (cmd == 21)
{
servo->setDirection(SERVO_MOTOR_LEFT);
}
else if (cmd == 23)
{
servo->setDirection(SERVO_MOTOR_RIGHT);
}
else
{
servo->setDirection(SERVO_MOTOR_FRONT);
}
}
}