Showing
1 changed file
with
170 additions
and
0 deletions
Project_source/temp/shock_detect.ino
0 → 100644
1 | +// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files | ||
2 | +// for both classes must be in the include path of your project | ||
3 | +// 전처리부 | ||
4 | +#include "I2Cdev.h" | ||
5 | +#include "MPU6050.h" | ||
6 | +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE | ||
7 | + #include "Wire.h" | ||
8 | +#endif | ||
9 | +#define mpu_add 0x68 | ||
10 | +#define Pin_Relay 13 | ||
11 | +MPU6050 mpu; | ||
12 | + | ||
13 | + | ||
14 | +// 변수 및 상수부 | ||
15 | +long ac_x, ac_y, ac_z, gy_x, gy_y, gy_z; //acc, gyro data (acc, gyro 계산 수식) | ||
16 | +double angle = 0, deg; // angle, deg data (각도계산) | ||
17 | +double dgy_x; // double type acc data | ||
18 | +long int normal_x, normal_y, normal_z, deltha_x[3], deltha_y[3], deltha_z[3], deltha; // 노말라이즈(정규화 데이터), 가속도 변화량 표시 | ||
19 | +long int angle_value; | ||
20 | +const int mapping_value = 1000; | ||
21 | +const int Emergency_value = 1300; // 충격상태로 판단하는 값 | ||
22 | +const int Emergency_angle = 25; // 충격상태로 판단하는 각도(기울기) | ||
23 | +const int Emergency_value2 = 1200;// 충격상태로 판단하는 값 | ||
24 | +const int Emergency_angle2 = 9; // 충격상태로 판단하는 각도(기울기) | ||
25 | +boolean State_Parameter = false; // 충격상태 | ||
26 | +const long int sum_count = 2; // 평균 내는 횟수 | ||
27 | +const long interval = 1000; // 충격을 감지후 다음 충격을 감지하는 최소 간극 시간 (ms) | ||
28 | +unsigned long previousMillis = 0; // 최초 시작시간 | ||
29 | + | ||
30 | + | ||
31 | +/* 사용자지정함수부 | ||
32 | +*/ | ||
33 | +// 모듈초기화 | ||
34 | +void mpu6050_init(){ | ||
35 | + Wire.begin(); //I2C통신 시작 | ||
36 | + Wire.beginTransmission(mpu_add) ; // 0x68(주소) 찾아가기 | ||
37 | + Wire.write(0x6B) ; // 0x6B의 레지스트를 0으로 함으로써 Sleep에서 깨움 | ||
38 | + Wire.write(0); // set to ZERO(WAKE UP THE MPU6050) | ||
39 | + Wire.endTransmission(true) ; | ||
40 | +} | ||
41 | + | ||
42 | +// 연산에 필요한 변수들을 초기화 | ||
43 | +void value_init(){ | ||
44 | + normal_x = 0; | ||
45 | + normal_y = 0; | ||
46 | + normal_z = 0; | ||
47 | + | ||
48 | + for(int i = 0; i < 3; i++){ | ||
49 | + deltha_x[i] = 0; | ||
50 | + deltha_y[i] = 0; | ||
51 | + deltha_z[i] = 0; | ||
52 | + angle = 0; | ||
53 | + angle_value = 0; | ||
54 | + } | ||
55 | +} | ||
56 | + | ||
57 | +// 가속도 연산 함수 | ||
58 | +void accel_calculate() { | ||
59 | + ac_x = 0; | ||
60 | + ac_y = 0; | ||
61 | + ac_z = 0; | ||
62 | + normal_x = 0; | ||
63 | + normal_y = 0; | ||
64 | + normal_z = 0; | ||
65 | + | ||
66 | + Wire.beginTransmission(mpu_add) ; // 번지수 찾기 | ||
67 | + Wire.write(0x3B) ; // 가속도 데이터 보내달라고 컨트롤 신호 보내기 | ||
68 | + Wire.endTransmission(false) ; // 기달리고, | ||
69 | + Wire.requestFrom(mpu_add, 6, true) ; // 데이터를 받아 처리 | ||
70 | + | ||
71 | + // Data SHIFT | ||
72 | + ac_x = Wire.read() << 8 | Wire.read() ; | ||
73 | + ac_y = Wire.read() << 8 | Wire.read() ; | ||
74 | + ac_z = Wire.read() << 8 | Wire.read() ; | ||
75 | + | ||
76 | + //맵핑화 시킨 것 - 즉 10000으로 맵핑시킴 | ||
77 | + normal_x = map(int(ac_x), -16384, 16384, 0, mapping_value); | ||
78 | + normal_y = map(int(ac_y), -16384, 16384, 0, mapping_value); | ||
79 | + normal_z = map(int(ac_z), -16384, 16384, 0, mapping_value); | ||
80 | + | ||
81 | + //각도계산 deg -> 각도 | ||
82 | + deg = atan2(ac_x, ac_z) * 180 / PI ; //rad to deg | ||
83 | + dgy_x = gy_y / 131. ; //16-bit data to 250 deg/sec | ||
84 | + angle = (0.95 * (angle + (dgy_x * 0.001))) + (0.05 * deg) ; | ||
85 | +} | ||
86 | + | ||
87 | +// 충격상태함수 | ||
88 | +void Emergency_state_(){ | ||
89 | + digitalWrite(Pin_Relay , HIGH); // 릴레이핀을 True값으로 바꿔 13번 핀의 LED를 ON시킨다. | ||
90 | + Serial.println("SHOCK!!!!!!!!!!!!!!!!!"); // Serial 모니터로 확인 | ||
91 | +} | ||
92 | + | ||
93 | +void Shock_Sensing(){ | ||
94 | + State_Parameter = false; // 충격상태 초기화 | ||
95 | + | ||
96 | + //첫번째 센싱 | ||
97 | + for (int i=0; i < sum_count; i++){ | ||
98 | + accel_calculate(); | ||
99 | + deltha_x[1] = deltha_x[1]+(normal_x); | ||
100 | + deltha_y[1] = deltha_y[1]+(normal_y); | ||
101 | + deltha_z[1] = deltha_z[1]+(normal_z); | ||
102 | + angle_value = angle_value + angle; | ||
103 | + } | ||
104 | + deltha_x[1] = int(deltha_x[1]/sum_count); | ||
105 | + deltha_y[1] = int(deltha_y[1]/sum_count); | ||
106 | + deltha_z[1] = int(deltha_z[1]/sum_count); | ||
107 | + | ||
108 | + //두번째 센싱 | ||
109 | + for (int i=0; i < sum_count; i++){ | ||
110 | + accel_calculate(); | ||
111 | + deltha_x[2] = deltha_x[2]+(normal_x); | ||
112 | + deltha_y[2] = deltha_y[2]+(normal_y); | ||
113 | + deltha_z[2] = deltha_z[2]+(normal_z); | ||
114 | + angle_value = angle_value + angle; | ||
115 | + } | ||
116 | + deltha_x[2] = int(deltha_x[2]/sum_count); | ||
117 | + deltha_y[2] = int(deltha_y[2]/sum_count); | ||
118 | + deltha_z[2] = int(deltha_z[2]/sum_count); | ||
119 | + | ||
120 | + //3축 변화량 비교 - 가속도 변화량, 각도 평균 값 | ||
121 | + deltha_x[0] = abs(deltha_x[1]-deltha_x[2]); | ||
122 | + deltha_y[0] = abs(deltha_y[1]-deltha_y[2]); | ||
123 | + deltha_z[0] = abs(deltha_z[1]-deltha_z[2]); | ||
124 | + deltha = deltha_x[0] + deltha_y[0] + deltha_z[0]; | ||
125 | + angle_value = abs(int(angle_value/(sum_count))); | ||
126 | + | ||
127 | + // deltha : 가속도 변화량 | ||
128 | + // angle_value : 각도 값(현재 각도 값) | ||
129 | + if (deltha > Emergency_value){ | ||
130 | + State_Parameter=true; | ||
131 | + } | ||
132 | + /*if (angle_value > Emergency_angle){ | ||
133 | + State_Parameter=true; | ||
134 | + } | ||
135 | + if ((deltha > Emergency_value2)&&(angle_value > Emergency_angle2)){ | ||
136 | + State_Parameter=true; | ||
137 | + }*/ | ||
138 | + | ||
139 | + // 충격상태체크 | ||
140 | + if( State_Parameter == true ){ | ||
141 | + Emergency_state_(); | ||
142 | + } | ||
143 | + else { | ||
144 | + digitalWrite(Pin_Relay , LOW); | ||
145 | + } | ||
146 | +} | ||
147 | + | ||
148 | + | ||
149 | + | ||
150 | +/*main 함수부*/ | ||
151 | +void setup() { | ||
152 | + Serial.begin(9600); // 시리얼 속도 설정 | ||
153 | + Serial.println("Initializing I2C devices..."); | ||
154 | + mpu6050_init(); // 가속도 센서 초기화 | ||
155 | + Serial.println("Testing device connections..."); | ||
156 | + Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); | ||
157 | + pinMode(Pin_Relay, OUTPUT); // 핀모드사용, led로 육안확인 가능하게끔 | ||
158 | + digitalWrite(Pin_Relay , LOW); // HIGH - LED on, LOW - LED off (DEFAULT : OFF) | ||
159 | +} | ||
160 | + | ||
161 | +void loop() { | ||
162 | + value_init(); //가속도-각도 관련 초기값 선언 | ||
163 | + unsigned long currentMillis = millis(); | ||
164 | + if(currentMillis - previousMillis >= interval){ | ||
165 | + Shock_Sensing(); | ||
166 | + if(State_Parameter == true){ | ||
167 | + previousMillis = currentMillis; | ||
168 | + } | ||
169 | + } | ||
170 | +} |
-
Please register or login to post a comment