[아두이노를 활용한 데이터 입출력] 4. 코드 작성, 하드웨어 구성

앞에서 공부한 내용을 바탕으로 코드를 작성했다.

 

1. 4개의 LED로 구현한 2진 카운터

delay() 함수 대신 millis() 함수를 이용하여 counter_time_previous, counter_time_current를 비교해서

1초의 시간 간격마다 카운터를 1씩 증가하도록 만들었다.

 

따로 counterLED()함수를 만들어 카운터에 해당하는 숫자를 boolean형으로 만들어 LED로 2진 표현을 할 수 있도록 하였다. 

또한 4자리 이진수는 15가 최대이므로, counter가 16이 되면 0으로 초기화시키도록 했다.

 

2. 가변저항을 이용하여 아날로그값 읽기

아날로그 입력을 할 수 있는 핀 A0을 가변저항을 위한 핀으로 정의해뒀다.

analogRead()함수를 이용하여 가변저항의 값을 얻어 그 값을 Serial.print()를 통해 시리얼 모니터로 확인할 수 있다.

 

3. 아날로그 값을 이용해 LED 밝기 조절

LED의 밝기를 가변저항을 통해 얻은 아날로그 값으로 조절한다.

analogRead()는 0~1023값을 반환하므로 analogWrite()에 사용하기 위해서,

map()함수를 이용하여 0~255사이의 값으로 변환한다.

 

4. 아날로그 값을 이용해 모터의 속도를 조절

모터의 이동 시간간격을 아날로그 값으로 조정한다.

map()함수를 이용하여 5~300 사이의 값으로 변환하였다.

값이 클수록 시간 간격이 커지므로 모터의 속도는 느려진다.

 

 

 

	#include <Servo.h>

	static const int LED_pins[] = {2,3,4,5}; //카운터를 위한 LED
	static const int controlled_LED = 6; //밝기 조절 LED
	static const int vResistor = A0; //A0핀에 가변저항
	static const int servoPin = 11; //PWM 출력이 가능한 핀

	unsigned long counter_time_previous, counter_time_current;
	unsigned long counter_interval = 1000; //1초 간격으로 카운트
	int counter = 0;

	Servo myServo;
	unsigned long servo_time_previous, servo_time_current;
	int servo_interval = 10; //현재 이동시간 간격
	int servo_angle = 0; //현재 모터 각도
	int angle_step = 1; //모터 각도의 증감


	void setup() {
	  //시리얼 통신
	  Serial.begin(9600);

	  //카운터
	  for(int i =0;i<4;i++){
	    pinMode(LED_pins[i],OUTPUT);
	    digitalWrite(LED_pins[i], LOW);
	  }
	  
	  
	  //LED
	  pinMode(controlled_LED,OUTPUT);
	  digitalWrite(controlled_LED, LOW);

	  //가변저항
	  pinMode(vResistor, INPUT);

	  //서보모터
	  myServo.attach(servoPin);
	  myServo.write(servo_angle);

	  delay(100);
	  counter_time_previous = millis();
	  servo_time_previous = millis();
	}


	void counterLED(int c){
	  boolean on_off; //LED의 state

	  for(int i =0;i<4;i++){
	    on_off = c & (0x1 <<i); //c를 2진수로 LED로 표기
	    if(on_off){
	      digitalWrite(LED_pins[i],HIGH);
	    }
	    else{
	      digitalWrite(LED_pins[i],LOW);
	    }
	  }
	}

	void loop() {

	    counter_time_current = millis();
	    servo_time_current = millis();

	    //카운터
	    if(counter_time_current - counter_time_previous >= counter_interval){ //1초 경과
	      counter_time_previous = counter_time_current;
	      if(++counter==16) counter = 0; //4자리 이진수는 최대 15까지 출력, 16이 되면 0으로 초기화
	    }
	    counterLED(counter);

	    //가변저항을 통해 아날로그 값 읽기
	    int Analog_value = analogRead(vResistor);
	    Serial.print("가변저항 값: ");
	    Serial.println(Analog_value);

	    //LED
	    int value = map(Analog_value,0,1023,0,255); //0~1023을 0~255로 변환 
	    analogWrite(controlled_LED,value);

	    //서보모터
	    int new_interval = map(Analog_value,0,1023,5,300);
	    
	    if(new_interval != servo_interval){
	      servo_interval = new_interval; //이동 시간 간격 조정
	    }
	    if(servo_time_current - servo_time_previous >= servo_interval){
	      servo_time_previous = servo_time_current;

	      servo_angle += angle_step; //현재 각도를 조정
	      if(servo_angle > 180){
	        servo_angle = 180;
	        angle_step *= -1;
	      }
	      else if(servo_angle < 0){
	        servo_angle = 0;
	        angle_step *= -1;
	      }
	      //0~180도 사이로 회전이 가능하기 때문에
	      //범위를 넘어가면 방향 전환

	      myServo.write(servo_angle);
	    }

	}

 

 

하드웨어 구성

위의 코드에서 설정한 핀 번호에 근거해 회로를 구현했다.

 

사용한 하드웨어:

LED 5(붉은색 4, 노란색 1), 220Ω 저항 5, 로터리형 15mm 가변저항 10KΩ, DGservo 9g

 

 

 

 

 

결과 영상

 

 

728x90