* 무조건적으로 풀업 저항을 달고 시작할 것!!!!!
* 회로를 혼자 만들 수 있는 수준의 사람이라고 가정하고 써놓음
센서에서 정보를 제공하는 방법
1) 디지털 켜기/끄기
ex) tilt seneor , motion sensor
2) 아날로그
감지된 값에 비려하는 전압을 제공하는 센서도 있다.
ex) 온도 ,조명 ,동작, 진도, 소리
analogRead 명령어를 사용한다.
3) 펄스 폭
거리값에 비례하는 펄스 지속 시간을 사용하여 데이터를 제공한다.
ex) PING))
pulseIn 명령을 사용하여 펄스의 지속 시간을 측정한다.
4) 시리얼
시리얼 프로토콜을 사용하여 값을 제공한다.
ex) GPS
5) 동기 프로토콜 : I2C와 SPI
이 장이 아닌 또다른 장에서 자세히 다룰 것임
주의점:
1) 센서를 사용하기 전에 센서의 데이터시트를 잘 참조해라
2) 센서의 출력값을 일반인들이 알아볼 수 있는 단위로 변경하는 코드를 짜넣어라
3) 원하는 신호와 주위의 잡음을 분리할 수 있어야 한다.
흔들림 감지하기(디지털로 신호를 주는 센서 처리 방법)
/*tilt sketch*/
const int tiltSensorPin = 2; //틸트 센서가 연결된 핀
const int firstLEDPin = 11; // LED 핀 중 하나
const int secondLEDPin = 12; //또 하나의 LED 핀
void setup()
{
pinMode(tiltSensorPin,INPUT); // 2번 핀을 읽는다
pinMode(tiltSensorPin,HIGH); //풀업 저항을 사용
pinMode(firstLEDPin, OUTPUT); // 11 핀을 제어한다.
pinMode(secondLEDPin,OUTPUT); // 12 핀을 제어한다.
}
void loop()
{
if(digitalRead(tiltSensorPin)) { //핀이 high인지 검사한다.
digitalWrite(firstLEDPin,HIGH); //high라면 firstLED를 켠다.
digitalWrite(secondLEDPin,LOW); //secondLED를 켠다
}else{
digitalWrite(firstLEDPin,LOW); //반대로 수행한다.
digitalWrite(secondLEDPin,HIGH);
}
}
=> 틸트 센서의 기울어진 방향에 따라 LED 중 하나가 켜짐
/* shaken sketch*/
const int tiltSensorPin = 2; //틸트 센서가 연결된 핀
const int ledPin = 13; //led가 연결된 핀
int tiltSensorPreviousValue = 0; //틸트센서의 과거값
int tiltSensorCurrentValue = 0; //틸트센서의 현재값
long lastTimeMoved = 0; /마지막으로 흔들렸던 시간
int shakeTime = 50; //흔들림의 기준
void setup()
{
pinMode(tiltSensorPin,INPUT); // 2번 핀을 읽는다
digitalWrite(tiltSensorPin,HIGH); //풀업 저항 사용
pinMode(ledPin,OUTPUT); // 13 핀을 제어한다.
}
void loop()
{
tiltSensorCurrentValue = digitalRead(tiltSensorPin); // 2번 핀의 값을 현재값에 대입한다
if(tiltSensorPreviousValue != tiltSensorCurrentValue) { //과거값과 현재값이 같지 않으면
lastTimeMoved = millis();
//millis: 프로그램이 시작된 후의 시간을 밀리세컨드 단위로 리턴한다.
tiltSensorPreviousValue = tiltSensorCurrentValue; //현재값을 과거값에 대입
}
if(millis() - lastTimeMoved < shakeTime) { // 흔들렸으면
digitalWrite(ledPin,HIGH);
}
else { //흔들리지 않았으면
digitalWrite(ledPin,LOW);
}
}
흔들림을 판단하는 메커니즘
------------------------------------------------------------------------->
millis
l l l l l l l >
lastTimeMoved
-------- ---------------- ---- -------- ---------- ------
millis - lasttimeMoved =>이게 50 millisecond 이되지 않으면 흔들린 것으로 간주
조명 감지하기( 아날로그 신호를 주는 센서들 처리 방법)
/*light sensor*/
const int ledPin = 13;
const int sensorPin =0;
void setup()
{
pinMode(ledPin,OUTPUT);
}
void loop()
{
int rate = analogRead(sensorPin); // 0 ~ 1023 사이의 값으로 나온다.
digitalWrite(ledPin, HIGH);
delay(rate);
digitalWrite(ledPin,LOW);
delay(rate);
}
거리 측정하기(펄스 폭 신호를 주는 센서들 처리방법)
/*EZ1 Rangefinder Distance Sensor*/
const int sensorPin = 5;
const int ledPin = 13;
long value = 0;
int cm = 0;
int inches =0;
void setup()
{
value = pulseIn(sensorPin, HIGH);
cm = value / 58; //펄스 폭이 cm당 58마이크로다.
inches = value / 147; //인치당 147마이크로초
Serial.print(cm);
Serial.print(',');
Serial.println(inches);
digitalWrite(ledPin, HIGH);
delay(cm*10); //1센티미터당 지연 시간을 10밀리초 추가한다.
digitalWrite(ledPin, LOW);
delay(cm*10);
delay(20);
}
정확한 거리 측정하기
/*infrared-ray_distance sketch*/
const int ledPin = 13;
const int sensorPin = 0;
const long referenceMv = 5000; //곱하기 연산 시 오버플로우를 방지하기 위한 long형 정수
void setup()
{
Serial.begin(9600);
pinMode(ledPin,OUTPUT);
}
void loop()
{
int val = analogRead(sensorPin);
int mV = (val * referenceMv) / 1023;
Serial.print(mV);
Serial.print(",");
int cm = getDistance(mV);
Serial.println(cm);
digitalWrite(ledPin,HIGH);
delay(cm * 10);
digitalWrite(ledPin,LOW);
delay(cm * 10);
delay(100);
}
const int TABLE_ENTRIES = 12;
const int INTERVAL = 250;
static int distance[TABLE_ENTRIES] = {150,140,130,100,60,50,40,35,30,25,20,15};
int getDistance(int mV)
{
if(mV > INTERVAL * TABLE_ENTRIES-1) // 1)
return distance[TABLE_ENTRIES -1];
else
{
int index = mV / INTERVAL; // 2)
float frac = (mV % 250) / (float)INTERVAL; // 3)
return distance[index] + ((distance[index]) * (frac*100));
}
}
/* IR 센서의 출력은 거리에 비례하지 않는다
* 이 때 적용되는 기술: 보간(interpolating)
* 전압을 거리로 변환하는 작업을 수행하는 함수
* int getDistance(int mv)
* 1) 값이 테이블에 지정된 범위 내에 있는 지 검사한다. 값이 범위 내에 없으면 가장 짧은 * 유효 거리가 리턴된다.
* 2) 값이 테이블 범위 내에 있으면 정수 나누기 연산을 통해 판독값보다 낮으면서 가장 가 * 까운 항목이 계산된다.
* 3) 판독값이 두 항목 사이에 있을 경우에는 모듈로 연산자를 사용해서 소수 값이 계산된다
소리 감지하기
/* microphone sketch*/
const int ledPin =13; // 핀 13의 LED가 켜진다.
const int middleValue = 512; // 아날로그 값 범위의 중간값
const int numberOfSamples = 128; // 한 번에 읽어올 판독값의 개수
int sample; // 마이크로폰에서 읽어온 값
long signal; // DC 오프셋을 제거한 이후의 판독값
long averageReading; // 해당 루프 동안 읽어온 값의 평균
long runningAverage = 0; // 계산된 값의 실행 평균
const int averagedOver = 16; // 새 값이 실행 평균에 영향을 미치는 속도
// 숫자가 클수록 느려진다.
const int threshold = 400; // 조명레벨
void setup() {
pinMode(ledPin,OUTPUT);
Serial.begin(9600);
}
void loop() {
long sumOfSquares = 0;
for (int i = 0; i < numberOfSamples; i++) { // 많은 값을 읽어와서 평균을 구한다.
sample = analogRead(0); // 값을 읽어온다
signal = (sample - middleValue); // 오프셋을 적용한다.
signal *= signal; // 양수가 되도록 값을 제곱한다.
sumOfSquares += signal; // 합계를 추가한다.
}
averageReading = sumOfSquares/numberOfSamples; //실행 평균을 계산한다.
runningAverage=(((averagedOver-1)*runningAverage)+averageReading)/averagedOver;
if(runningAverage>threshold) { // 평균이 임계값보다 큰가?
digitalWrite(ledPin,HIGH); // 그렇다면 LED를 켠다.
}else{
digitalWrite(ledPin,LOW); // 그렇지 않다면 LED를 끈다.
}
Serial.println(runningAverage); // 값을 확인하기 위해 인쇄한다.
}
RFID 태그 판독하기
/*RFID sketch*/
const int startByte = 10; // 각 태그 앞에 아스키 줄 바꿈 문자를 사용한다.
const int endByte = 13; // 각 태그 끝에 아스키 캐리지 리턴 문자를 사용한다.
const int tagLength = 10; // 태그의 자릿수
const int totalLength = tagLength + 2; // 태그 길이 + 시작 및 종료 바이트
char tag[tagLength + 1]; // 태그와 종료 널 포함
int bytesread = 0;
void setup()
{
Serial.print(2400); // RFID 판독기의 전송 속도로 설정한다.
pinMode(2,OUTPUT); // RFID ENABLE 핀에 연결된다.
digitalWrite(2,LOW); // RFID 판독기를 실행한다.
}
void loop()
{
if(Serial.available() >= totalLength) // 충분한 데이터가 있는지 검사한다.
{
if(Serial.read() == startByte)
{
bytesread = 0; //태그의 시작이므로 count를 0으로 재설정한다.
while(bytesread < tagLength) // 10자리 코드를 읽는다.
{
int val = Serial.read();
if((val == startByte)||(val == endByte)) // 코드의 끝을 검사한다.
break;
tag[bytesread] = val;
bytesread = bytesread + 1; // 다음 자릿수의 코드를 읽기 위해 준비한다.
}
if(Serial.read() == endByte) // 올바른 종료 문자인지 검사한다.
{
tag[bytesread] = 0; // 문자열을 종료한다.
Serial.print("RFID tag is: ");
Serial.println(tag);
}
}
}
}
로터리 이동 추적하기
/*rotary-movement sensor*/
const int encoderPinA = 4; // 인코더가 회전하고 있는 지의 여부
const int encoderPinB = 2; // 인코더가 회전하고 있는 방향
const int encoderStepsPerRevolution = 16; // 회전당 단계수
int angle = 0;
int val;
int encoderPos = 0;
boolean encoderALast = LOW; // 이전 핀의 상태를 기억한다.
void setup()
{
pinMode(encoderPinA,INPUT);
pinMode(encoderPinB,INPUT);
digitalWrite(encoderPinA, HIGH);
digitalWrite(encoderPinB, HIGH);
Serial.begin(9600);
}
void loop()
{
boolean encoderA = digitalRead(encoderPinA); // 인코더 핀 하나를 읽는다.
if ((encoderALast == HIGH) && (encoderPinA == LOW));
{
if(digitalRead(encoderPinB) == LOW)
{
encoderPos--;
}
else
{
encoderPos++;
}
angle=(encoderPos % encoderStepsPerRevolution)*360/encoderStepsPerRevolution;
Serial.print(encoderPos);
Serial.print(" ");
Serial.println(angle);
}
encoderALast = encoderA;
}
댓글 없음:
댓글 쓰기