/*
* 핀배열
* 적외선센서 출력 - A0
* 서보모터 데이터 -7
* 초음파 출력(trig)-5
* 초음파 입력(echo)-4
* 감지여부 확인 출력-6
* 블루투스 tx핀 - 2
* 블루투스 rx핀 - 3
*/
//공격용 인터럽트 관련
int cwThresh = 1020; // Sets CW Mode threshold (cwThresh/1023 *5)= Volts.
int minFreq = 2; // Minimum Frequency in Hz.
int fDiv = 2; // Frequency range divider. maxFreq = fDiv/1024.
int vpw;
int vbps;
int ontime;
int offtime;
int period;
int freq;
float duty;
int outPin = 9;
int bpsPin = A3;
int pwPin = A2;
//블루투스 통신 관련
#include <SoftwareSerial.h>
int T = 2;// 블루투스 모듈의 TXD 핀과 연결된 2번을 T 라는 변수로,
int R = 3;// 블루투스 모듈의 RXD 핀과 연결된 3번을 R 이라는 변수로 선언한다.
char data;
SoftwareSerial my_blue(T, R);
//서보관련
#include <Servo.h>
Servo myservo;
int pos = 0;
int ref_val = 700;//기준거리, 단위 mm. 50cm이내 detection
int delay_num = 5;//원래 1이었음
unsigned int angle = 1;//원래 2였음
//적외선 거리측정 관련
#define SIZE 3
int buffer[SIZE];
float sum;
int sensorValue;
float EMA_a = 0.4;
int EMA_S_pre = 0;
int EMA_S=0;
float volts;
float ir_distance ;
//초음파 거리측정 관련
unsigned long duration;
float distance;
float dist;//최종 거리값
//딜레이 스위치 관련
unsigned long ref_time = 500000;
int cnt= 10;
//setup 관련
int trig= 5;
int echo= 4;
int attack_detection_pre= 6;
void setup()
{
pinMode( trig, OUTPUT ); // HC-SR04의 Trig출력 5번
pinMode( echo, INPUT ); // HC-SR04의 Echo입력 4번
digitalWrite( trig, LOW );// Trig로 LOW신호 출력
delay(10); // 10ms 딜레이
//Serial.begin(9600); // 9,600 시리얼통신시작
my_blue.begin(9600);
///////////////
myservo.attach(7);
////////////////
pinMode( attack_detection_pre, OUTPUT);//6번핀. 감지되면 출력됨.
////////////////
pinMode(8, OUTPUT);//연주모드일때 high 공격모드일때 low
/////////////////
pinMode(outPin, OUTPUT);//9번
pinMode(bpsPin, INPUT);//A3
pinMode(pwPin, INPUT);//A2
}
//////////////////////////////////////////////
void interrupter_for_attack (void)
{
vpw = analogRead(pwPin); // read pw voltage
vbps = analogRead(bpsPin); // read bps voltage
vpw=250;
vbps=40;
/*if (vbps >= cwThresh) //1020 / CW mode threshold
{
digitalWrite(outPin, HIGH);
delayMicroseconds(100);
}*/
if (vbps >= cwThresh) //VBPS가 cwThresh를 넘어서면 출력을 DISABLE함.
{
digitalWrite(outPin, LOW);
delayMicroseconds(100);
}
else //일반적인 경우.
{
freq = 1 + ((vbps + fDiv) / fDiv);// Frequency range divider. fDiv는 2이다.
if (freq < minFreq) //최소 주파수 설정
{
freq = minFreq;
}
if (vpw < 52) //최소 펄스폭 설정
{
vpw = 52;
}
duty = vpw;
duty = duty / 2046;//듀티사이클 산출
if (freq <= 33)
{
if (freq > 25 && duty <= 0.035) //주파수는 25~33, 듀티는 0.035 이하.
{
period = 1000 / freq;//주기 산출
float onFloat = duty * period;
float offFloat = period - onFloat;
offtime = offFloat;
int onshort = 1000 * onFloat;
digitalWrite(outPin, HIGH);
delayMicroseconds(onshort);
digitalWrite(outPin, LOW);
delay(offtime);
}
else
{
period = 1000 / freq;
ontime = duty * period;
offtime = period - ontime;
digitalWrite(outPin, HIGH);
delay(ontime);
digitalWrite(outPin, LOW);
delay(offtime);
}
}
if (freq >= 34 && freq <= 54) //주파수가 34~54. this range glitches badly, PWM 고정시킴.
{
duty = 0.2;
period = 1000000 / freq;
ontime = duty * period;
offtime = period - ontime;
digitalWrite(outPin, HIGH);
delayMicroseconds(ontime);
digitalWrite(outPin, LOW);
delayMicroseconds(offtime);
}
if (freq >= 55) //주파수가 55이상일 경우
{
period = 1000000 / freq;
ontime = duty * period;
offtime = period - ontime;
digitalWrite(outPin, HIGH);
delayMicroseconds(ontime);
digitalWrite(outPin, LOW);
delayMicroseconds(offtime);
}
}
}
float ultra_sonic (void)
{
digitalWrite(trig, LOW);
digitalWrite(echo, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
duration = pulseIn(echo, HIGH);
distance = duration / 29.0 / 20.0*100.0;
return distance;
}
void caculating_dist (void)
{
//복합필터 적용한 적외선 거리측정
sensorValue = analogRead(0); //아날로그 센서값(적외선 센서값) 리딩
EMA_S_pre = (EMA_a*sensorValue) + ((1-EMA_a)*EMA_S_pre); //로우패스 필터 필터링 수식을 통해 필터링 된 센서값 도출(EMA_S_pre)
//이동평균 필터 적용////////////////////////////
sum-=buffer[0];
for(int i =0; i<SIZE-1 ; i++)
{
buffer[i]=buffer[i+1];
}
buffer[SIZE-1]=EMA_S_pre;
sum+=buffer[SIZE-1];
EMA_S=sum/SIZE+2;//이동평균필터를 통해 최종 필터링한 센서값 도출(EMA_S)
////////////////////////////////
volts=(EMA_S) * 5.0/ 1023.0;
ir_distance = 604.95* pow(volts, -1.1904);//필터링된 거리값 도출
if(ir_distance<200)
{
dist=ultra_sonic();//20cm이내에서 dist 값은 초음파센서 측정을 통해 얻어짐
}
else
{
dist=ir_distance;//20cm밖에서의 dist값은 적외선측정을 통해 얻어짐.
}
//Serial.println(dist);
}
///////////////////////////////////////////////
void loop()
{
if(my_blue.available())//만일 블루투스에서 뭔가 받으면, 그 값을 data에 저장
{
data = (char)my_blue.read();
}
///////////////////////////////////////////////////////////////////////////////////////
while(data=='a')//공격모드인 경우, 모터 회전, 센서 코드 및 인터럽트 코드 반복문 실행
{
digitalWrite(8,LOW);//8번핀에 LOW. LOW가 공격용.
/////////////////////////////
for(pos = 0; pos < 180; pos += angle)
{
myservo.write(pos);//일단 움직인다
delay(delay_num);
caculating_dist ();//dist값 갱신하고 이 값을 바로 아래 while문에서 검사
while(dist<ref_val)//거리 1미터이내면 진입, 아니면 while반복문 탈출
{
digitalWrite(6,HIGH);//1미터 이내일 경우, 6번핀에 high주고
interrupter_for_attack ();//인터럽트 신호 1회 발생
caculating_dist ();
if(dist>=ref_val)//1미터 밖일 경우, 6번핀 끄고 반복 종료
{digitalWrite(6,LOW);
break;
}
if(my_blue.available())//뭔가 받았을때 그게 m이면 while반복문 탈출
{
data = (char)my_blue.read();
}
if(data=='m')
{
digitalWrite(6,LOW);
break;
}
}
if(my_blue.available())//뭔가 받으면
{
data = (char)my_blue.read();
}
if(data=='m')
break;
}//for문 1번 종료
for(pos = 180; pos>=1;pos-=angle)
{
myservo.write(pos);
delay(delay_num); //일단 움직인다
caculating_dist ();//dist값 갱신하고 이 값을 바로 아래 while문에서 검사
while(dist<ref_val)//거리 1미터이내면 진입, 아니면 while반복문 탈출
{
digitalWrite(6,HIGH);
interrupter_for_attack ();//인터럽트 신호 1회 발생
caculating_dist ();
if(dist>=ref_val)//조건 불부합시.
{digitalWrite(6,LOW);
break;
}
if(my_blue.available())//뭔가 받으면
{
data = (char)my_blue.read();
}
if(data=='m')
{
digitalWrite(6,LOW);
break;
}
}
if(my_blue.available())//뭔가 받으면
{
data = (char)my_blue.read();
}
if(data=='m')
break;
}
////////////////////////////////
if(my_blue.available())//뭔가 받으면
{
data = (char)my_blue.read();
}
if(data=='m')
break;
}//data 가 a일 경우.
////////////////////////////////////////////////////////////////////////////
while(data=='m')//연주모드일경우.
{
digitalWrite(8,HIGH);//8번에 HIGH. HIGH가 연주모드를 설정함.
if(my_blue.available())//뭔가 받으면
{
data = (char)my_blue.read();
}
if(data=='a')
break;
}
/////////////////////////////////////////////////////////////////////////////
}//메인 루프문
'Project > DRSSTC' 카테고리의 다른 글
200V 입력 음악변조실험 (0) | 2022.02.18 |
---|---|
DRSSTC1- 시험 구동 및 음악변조(musical DRSSTC) (0) | 2022.02.16 |
various DRSSTC driver circuit (0) | 2022.02.16 |
DRSSTC1제작기-1차공진회로 시험과 위상앞섬(phase lead) (0) | 2022.02.16 |
DRSSTC1제작기-몸체 구성 및 배치 (0) | 2022.02.16 |