-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSumoBot_SensorsTest.ino
309 lines (240 loc) · 8.7 KB
/
SumoBot_SensorsTest.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
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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*
Author : Simeon Simeonov
Name : Bolid Arduino project
Ver: 1.0.0
*/
#include <Arduino.h>
#include <PWM.h>
#include "pitches.h"
#include <stdio.h> // for function sprintf
//--------------------- PIN definitions -----------
/*
#define RIGHT_SIDE A2
#define RIGHT_FRONT A3
#define DOHIO_LEFT A4
#define DOHIO_RIGHT A5
#define LEFT_FRONT A6
#define LEFT_SIDE A7
*/
//--------- Array index -------
#define RIGHT_SIDE 0
#define RIGHT_FRONT 1
#define DOHIO_RIGHT 2
#define DOHIO_LEFT 3
#define LEFT_FRONT 4
#define LEFT_SIDE 5
//---------- Motors --------
#define LEFT_PWM 10
#define RIGHT_PWM 9
#define LEFT_DIR 6
#define RIGHT_DIR 5
//--------------- LEDS -----------
#define LED1 4 // LED1
//-------------- SENSORS ---------
#define OPT_ENABLE1 3
#define OPT_ENABLE2 2
//-------------- Beep ----------
#define BEEP 13
//-------------- Buttons -----------
#define BUTT1 7
#define BUTT2 11
//-------------- Ultrasonic --------
#define TRIG 12
#define ECHO A0
//----------------- IR --------------
#define IR_PIN 8
//-------------------------- Sensors and position -------------------------
#define SENSORS_NR 6
const unsigned int sensors[SENSORS_NR] = { A2, A3, A4, A5, A6, A7 }; //left-right
//------------------------ Калибрираща константа -------------------------
// Използва се за линеаризиране и калибриране на сенозрите
// преобразужането е : distance = CALLIBRATE / sensor_value; - разстоянието е в мм
#define CALLIBRATE 18000
///////////////////////////////////////////////////////////////////////////
//----------------------------------- PID ---------------------------------
///////////////////////////////////////////////////////////////////////////
#define PWM_FREQ 50000
//------------------ -------------
#define DISTANCE 200 //200mm
#define KP 1
#define KD 48
#define Ki 0.03
#define SPEED 160
#define ACQUIRE_SPEED 30
/////////////////////////////////////////////////////////////////////////
//------- Global Variables -----
int dir;
signed int error;
signed int lastError;
signed int left_pwm;
signed int right_pwm;
signed int motorSpeed;
signed int control_value;
signed int speed;
signed int derivate;
signed int integral = 0;
unsigned int frontL_distance;
unsigned int frontR_distance;
unsigned int left_distance;
unsigned int right_distance;
//================= CALIBRATE ==========================
unsigned int sensor_values[SENSORS_NR];
unsigned int sensor_min[SENSORS_NR];
//--------- Common ------------
char tmp_str[64];
//--------------------------------
int melody[] = { NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 };
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = { 4, 8, 8, 4, 4, 4, 4, 4 };
//////////////////////////////////////////////////////////////////////////////
//
// SETUP
//////////////////////////////////////////////////////////////////////////////
// Първоначална инициализация на всички входове, изходи и променливи
//
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
//---- Инициализация на пиновете за управление на моторите
pinMode(LEFT_PWM, OUTPUT);
pinMode(RIGHT_PWM, OUTPUT);
pinMode(LEFT_DIR, OUTPUT);
pinMode(RIGHT_DIR, OUTPUT);
//---- PWM инициализация за управление на моторите
InitTimersSafe();
if ( SetPinFrequencySafe(LEFT_PWM, PWM_FREQ))
{
pinMode(LEFT_PWM, OUTPUT);
}
if (SetPinFrequencySafe(RIGHT_PWM, PWM_FREQ))
{
pinMode(RIGHT_PWM, OUTPUT);
}
// Управление на оптроните
pinMode( OPT_ENABLE1 , OUTPUT);
pinMode( OPT_ENABLE2 , OUTPUT);
digitalWrite( OPT_ENABLE1 , LOW);
digitalWrite( OPT_ENABLE2 , LOW);
// --- Изходи ---
pinMode(LED1, OUTPUT);
pinMode(BEEP, OUTPUT);
// --- Входове ---
pinMode(BUTT1, INPUT_PULLUP);
pinMode(IR_PIN, INPUT_PULLUP);
tone(BEEP, 2400, 400);
delay(500);
noTone(BEEP);
analogWrite(LEFT_PWM, 0);
analogWrite(RIGHT_PWM, 0);
left_motor_speed(0);
right_motor_speed(0);
// Изчакване натискането на бутон
while (digitalRead (BUTT1) == HIGH);
dir = FORWARD;
lastError = 0;
prevError = 0;
// --- Изпълняване на мелодията ---
for (int thisNote = 0; thisNote < 8; thisNote++) {
// to calculate the note duration, take one second
// divided by the note type. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(BEEP, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(BEEP);
}
}
//============================================================================
//
// the loop routine runs over and over again forever:
//
//============================================================================
void loop() {
int adc_value;
//---- Прочитане на текущата позиция и пресмятане на грешката ----
read_position();
frontL_distance = CALLIBRATE / sensor_values[LEFT_FRONT];
frontR_distance = CALLIBRATE / sensor_values[RIGHT_FRONT];
left_distance = CALLIBRATE / sensor_values[LEFT_SIDE];
right_distance = CALLIBRATE / sensor_values[RIGHT_SIDE];
/*
Left and right dohio sensors are analog values.
Lower than 100 is the white border. Higher - dohio black disk.
sensor_values[DOHIO_LEFT], sensor_values[DOHIO_RIGHT]
*/
//-------------------- PID --------------------------
error = right_distance - left_distance;
//----------------------- Print sensors ---------------------------
sprintf(tmp_str, " / %3d %3d %3d", left_distance, frontL_distance, frontR_distance);
Serial.print(tmp_str);
sprintf(tmp_str, " %3d err= %d | %3d %3d ",right_distance, error, sensor_values[DOHIO_LEFT], sensor_values[DOHIO_RIGHT]);
Serial.println(tmp_str);
delay(100);
//-------------------------------------------------------------------
//-------------- Control ---------
//left_motor_speed(left_pwm);
//right_motor_speed(right_pwm);
while (digitalRead(IR_PIN) == LOW); // Спиране ако има команда от Старт модул
delay(3);
}
//=======================================================================================
/* -----------------------------------------------------------------------------------
Two way PWM speed control. If speed is >0 then motor runs forward.
Else if speed is < 0 then motor runs backward
------------------------------------------------------------------------------------ */
void left_motor_speed(signed int motor_speed) {
if (motor_speed == 0)
motor_speed = 1;
if (motor_speed > 0) {
digitalWrite(LEFT_DIR, HIGH);
}
else {
digitalWrite(LEFT_DIR, LOW);
}
motor_speed = abs(motor_speed);
if (motor_speed > 255)
motor_speed = 255;
pwmWrite(LEFT_PWM, motor_speed);
}
//---------------------------------------
void right_motor_speed(signed int motor_speed) {
if (motor_speed == 0)
motor_speed = 1;
if (motor_speed > 0) {
digitalWrite(RIGHT_DIR, HIGH);
}
else {
digitalWrite(RIGHT_DIR, LOW);
}
motor_speed = abs(motor_speed);
if (motor_speed > 255)
motor_speed = 255;
pwmWrite(RIGHT_PWM, motor_speed);
}
//===================== Read sensors and scale ==================
void read_position(void) {
unsigned char sens;
unsigned int tmp_value;
for (sens = 0; sens < SENSORS_NR; sens++) {
sensor_min[sens] = analogRead(sensors[sens]) / 2;
}
//-------------- Read Left sensors ------------
digitalWrite( OPT_ENABLE1 , HIGH);
delayMicroseconds(320); // Wait for lighting
for (sens = 0; sens < 2; sens++) {
sensor_values[sens] = analogRead(sensors[sens]) / 2 - sensor_min[sens];
}
sensor_values[DOHIO_RIGHT] = analogRead(sensors[DOHIO_RIGHT]) / 2; // Right dohio sensor
digitalWrite( OPT_ENABLE1, LOW);
//-------------- Read Right sensors ------------
digitalWrite( OPT_ENABLE2 , HIGH);
delayMicroseconds(320); // Wait for lighting
sensor_values[DOHIO_LEFT] = analogRead(sensors[DOHIO_LEFT]) / 2; // Left dohio sensor
for (sens = 4; sens < SENSORS_NR; sens++) {
sensor_values[sens] = analogRead(sensors[sens]) / 2 - sensor_min[sens];
}
digitalWrite( OPT_ENABLE2, LOW);
}