capstonedesign2.ino
5.8 KB
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
#include <CoDrone.h> // 코드론 라이브러리
#define ShockLed 12 // 충격 상태 확인을 위한 LED 핀번호
#define buzzer 7 // 피에조 버저 핀번호
#define LeftVib 27 // 왼쪽 진동자 핀번호
#define RightVib 28 // 오른쪽 진동자 핀번호
// 변수 및 상수부
long int ac_x, ac_y, ac_z;
long int normal_x, normal_y, normal_z, deltha_x[3], deltha_y[3], deltha_z[3], deltha; // 노말라이즈(정규화 데이터), 가속도 변화량 표시
const int mapping_value = 5000;
const int Emergency_value = 300; // 충격상태로 판단하는 값
boolean State_Parameter = false; // 충격상태 판단
long int shock_level;
const long int sum_count = 4; // 평균 내는 횟수
long shock_sum = 0; // 누적 충격값
//사용자지정 함수부
void value_init()
{
normal_x = 0;
normal_y = 0;
normal_z = 0;
for(int i = 0; i < 3; i++)
{
deltha_x[i] = 0;
deltha_y[i] = 0;
deltha_z[i] = 0;
}
}
// 가속도 연산 함수
void accel_calculate()
{
ac_x = 0;
ac_y = 0;
ac_z = 0;
// Data SHIFT From CoDrone Accelerometer
acceldata accel;
accel = CoDrone.getAccelerometer(); // CoDrone에서 가속도 전달받음.
ac_x = accel.x; // 넘겨 받은 x축 raw data
ac_y = accel.y; // 넘겨 받은 y축 raw data
ac_z = accel.z; // 넘겨 받은 z축 raw data
// 맵핑화 시킨 것 - 즉 10000으로 맵핑시킴
normal_x = map(int(ac_x), -16384, 16383, -1 * mapping_value, mapping_value);
normal_y = map(int(ac_y), -16384, 16383, -1 * mapping_value, mapping_value);
normal_z = map(int(ac_z), -16384, 16383, -1 * mapping_value, mapping_value);
}
// 충격상태함수
void Emergency_state_()
{
digitalWrite(ShockLed , HIGH); // LED를 True값으로 바꿔 12번 핀의 LED를 ON시킨다.
digitalWrite(buzzer, HIGH); // buzzer를 True값으로 바꿔
if(ac_x < 0)
{
analogWrite(LeftVib ,map(int(shock_level), 0, 15000, 0, 255));
}
else
{
analogWrite(RightVib ,map(int(shock_level), 0, 15000, 0, 255));
}
}
// 충격 감지함수
void Shock_Sensing()
{
State_Parameter = false; // 충격상태 초기화
//첫번째 센싱
for (int i=0; i < sum_count; i++)
{
accel_calculate();
deltha_x[1] = deltha_x[1]+(normal_x);
deltha_y[1] = deltha_y[1]+(normal_y);
deltha_z[1] = deltha_z[1]+(normal_z);
}
deltha_x[1] = int(deltha_x[1]/sum_count);
deltha_y[1] = int(deltha_y[1]/sum_count);
deltha_z[1] = int(deltha_z[1]/sum_count);
//두번째 센싱
for (int i=0; i < sum_count; i++)
{
accel_calculate();
deltha_x[2] = deltha_x[2]+(normal_x);
deltha_y[2] = deltha_y[2]+(normal_y);
deltha_z[2] = deltha_z[2]+(normal_z);
}
deltha_x[2] = int(deltha_x[2]/sum_count);
deltha_y[2] = int(deltha_y[2]/sum_count);
deltha_z[2] = int(deltha_z[2]/sum_count);
//3축 변화량 비교 - 가속도 변화량, 각도 평균 값
deltha_x[0] = abs(deltha_x[1]-deltha_x[2]);
deltha_y[0] = abs(deltha_y[1]-deltha_y[2]);
deltha_z[0] = abs(deltha_z[1]-deltha_z[2]);
deltha = deltha_x[0] + deltha_y[0] + deltha_z[0];
// deltha : 가속도 변화량
if (deltha > Emergency_value)
{
State_Parameter=true;
}
// 충격상태체크
if( State_Parameter == true )
{
Emergency_state_();
}
else
{
digitalWrite(ShockLed, LOW);
digitalWrite(buzzer, LOW);
}
}
// 누적 충격량 계산
void ShockCal()
{
Shock_Sensing();
if(State_Parameter == true)
{
shock_sum += deltha;
}
if(State_Parameter == false && shock_sum != 0)
{
shock_level = shock_sum; // 충격 누적값 전송
shock_sum = 0; // 충격의 지속이 끝났으니 원래값인 0으로 초기화
}
}
// Main 함수부
void setup()
{
// 부속 하드웨어 제어
pinMode(LeftVib,OUTPUT); // 핀모드사용, 왼쪽 진동자
pinMode(RightVib,OUTPUT); // 핀모드사용, 오른쪽 진동자
pinMode(ShockLed,OUTPUT); // 핀모드사용, led로 육안확인 가능하게끔
pinMode(buzzer,OUTPUT); // 핀모드사용, 버저
digitalWrite(ShockLed,LOW); // HIGH - LED on, LOW - LED off (DEFAULT : OFF)
digitalWrite(buzzer,LOW); // HIGH - buzzer on, buzzer - LED off (DEFAULT : OFF)
CoDrone.begin(115200); // 드론 플러그의 통신 개시 (115200bps)
CoDrone.AutoConnect(NearbyDrone); // 가장 가까운 위치의 드론과 연결
CoDrone.DroneModeChange(Flight); // 드론을 플라이트 모드로 설정
}
void loop()
{
value_init(); //가속도-각도 관련 초기값 선언
byte bt1 = digitalRead(11); // ■ □ □ □ □ □ □ 밑면 적외선 센서를 입력으로 사용
byte bt4 = digitalRead(14); // □ □ □ ■ □ □ □ 밑면 적외선 센서를 입력으로 사용
byte bt8 = digitalRead(18); // □ □ □ □ □ □ ■ 밑면 적외선 센서를 입력으로 사용
if (bt1 && !bt4 && !bt8) // 밑면 센서 가장 끝 11번 센서에 손을 대면 실행합니다.
{
CoDrone.FlightEvent(Stop); // 드론을 정지시킵니다.
}
if (!bt1 && !bt4 && bt8) // 밑면 센서 가장 끝 18번 센서에 손을 대면 실행합니다.
{
CoDrone.FlightEvent(Landing); // 드론을 착륙시킵니다.
}
if(PAIRING == true) // 연결(페어링)이 성공한 경우에만 실행
{
ShockCal();
YAW = -1 * CoDrone.AnalogScaleChange(analogRead(A3)); // 아날로그 3번 핀의 값을 YAW 값으로 사용합니다. - 좌우회전
THROTTLE = CoDrone.AnalogScaleChange(analogRead(A4)); // 아날로그 4번 핀의 값을 THROTTLE 값으로 사용합니다. - 승하강
ROLL = -1 * CoDrone.AnalogScaleChange(analogRead(A5)); // 아날로그 5번 핀의 값을 ROLL 값으로 사용합니다. - 좌우이동
PITCH = CoDrone.AnalogScaleChange(analogRead(A6)); // 아날로그 6번 핀의 값을 PITCH 값으로 사용합니다. - 전후진
CoDrone.Control(1);
}
}