잔상 LED디스플레이를 만들어 보았다.

 

일단 기본적인 회로(무지 간단하다 -_-;;)와 소스코드(무지 난잡하다 -_-;;)만 일단 올려두고

  

 

 

 

일단 2개의 기울기 센서를 이용하여 움직이는 방향이 '좌->우' 인지 '우->좌' 인지 확인이 가능하다.

 

일단 기울기 센서의 사진을 보자. 쎈서라기보단 스위치라 해야 옳다.

 

스위치가 off된 모습과 스위치가 on된 모습

 

이것은 빵판에 스위치를 연결한 모습

 

 

 

 

이것을 양 방향으로 (사진 참조) 연결해두면 어느 방향으로 움직이는지 확인이 가능하다.

 

움직이는 방향을 알았다면 이제 어떻게 출력을 내보낼지 결정해야지!!

 

 

이런 그림을 출력하고 싶다고 치자!! 원하는데로 그려도 좋다

 

좌에서 우로 움직이는 중이라면 적당한 시간 간격으로 (0,0,0,0,0,0,0,0,0,0,0) 부터 출력을 해주면 될것이다.

 

전부 off로 출력 했다가 처음 켜지는 순간은 (0,0,1,1,1,0,0,0,0,0,0) 되것지.

 

세로 한줄을 LED로 표현 주면 된다.

 

이는 아주 기본적인 원리 설명이고 좀더 디테일하게 들어가보자. 

 

 

 

LED 막대기(?)가 

 

Location 0 ~ Location 49까지 움직인다고 가정하자.

 

양 끝의 0~4, 46~49 위치에서는 방향이 바뀌는 위치다 보니 LED를 디스플레이 시키기 곤란한 점이 있다.

 

따라서 그 양 끝을 제외하고 디스플레이 한다.

 

막대가 Location 0에서 49까지 가는데 걸린 시간.( 인터럽트 발생시 시간을 측정하여 비교하면 된다)을 50으로 나눠서

 

각 1/50 부분마다 (편의상) 번호를 붙여놨다

 

젤 왼쪽 0~4, 오른쪽 45~49 번은 출력을 하지 않을 생각이다.

 

그리고 나머지 부분에서 순차적으로 출력을 할것

 

내가... 설명을 잘 못하는데...  정말 열심히 설명해준거다...

 

그래도 잘 모르겠다면.. 내가 참고한 사이트

 

http://depordiue.untoc.com/archive/200903 <- 참조바란다.. 나보다 훨씬 자세한 설명.. ㄳㄳ

 

암튼 내가 만든 아두이노용 소스를 보자.

 

소스에 대한 자세한 설명은 생략할 것이며...

 

제대로 동작한다는 보장 또한 하지 못하겠다.

 

이 소스는 개인적인 공부 하는데 사용되길 바라며...

 

혹시라도 학교 과제를 위해 카피하는 사람은 없길 바란다.

 

회로도는 무지 간단한데... 문제는 소스.. ㅠㅠ

 

 

 

 

/*********************************************************************/
/*                 After-Image LED Display                           */
/*                 create by Lee BH (Hubert Lee)                     */
/*                 31 - AUG - 09                                     */
/*                 Ver 0.1                                           */
/*                                                                   */
/*********************************************************************/

#define LEFT 0
#define RIGHT 1
#define WIDTH 15 //출력 문자영의 가로 도트수

int course;
unsigned int startTime=0;
unsigned int endTime=0;
unsigned int dispIntaval = 1000;
int ledPin[10] = {4,12,13,5,6,7,8,9,10,11};  // LED 출력 핀 순서
unsigned int timeDelay; // 왕복에 걸리는 시간 변수
int location; // 현재 위치를 추정하기 워한 변수
// 하트 모양을 출력 하기 위한 하트 모양의 배열
int font[WIDTH][10] = {{0,0,0,0,0,0,0,0,0,0}, //2
                    {0,0,0,0,0,0,0,0,0,0}, //3
                    {0,0,1,1,1,0,0,0,0,0}, //4
                    {0,1,1,1,1,1,0,0,0,0}, //5
                    {1,1,1,1,1,1,1,0,0,0}, //6
                    {1,1,1,1,1,1,1,1,0,0}, //7
                    {0,1,1,1,1,1,1,1,1,0}, //8
                    {0,0,1,1,1,1,1,1,1,1}, //9
                    {0,1,1,1,1,1,1,1,1,0}, //10
                    {1,1,1,1,1,1,1,1,0,0}, //11
                    {1,1,1,1,1,1,1,0,0,0}, //12
                    {0,1,1,1,1,1,0,0,0,0}, //13
                    {0,0,1,1,1,0,0,0,0,0}, //14
                    {0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0}, //15                   
                  };
                  
/* 왼쪽에서 움직일때 실행될 인터럽트 */
void fromLEFT()
{
  if ((millis() - startTime <= 90) || (course == LEFT)) return;//인터럽트 무시 조건(스위치의 진동에 의한 반복적인 인트럽트는 오작동을 유발할수 있어 인터럽트 무시 기준을 명시함
  endTime = millis(); //인터럽트 발생 시간 측정
  timeDelay = endTime - startTime; //왼쪽으로 오는데 걸린 시간 계산
  startTime = endTime; //되돌아 가기전 startTime을 목적에 맞게 세팅
  dispIntaval = timeDelay / (WIDTH + 10) ; //LED 상태를 바꿔줄 주기 설정
  course = LEFT; //왼쪽에서 출발함을 표시
  location = 0; //위치 초기화
}

void fromRIGHT()
{
  if ((millis() - startTime <= 90) || (course == RIGHT)) return;
  endTime = millis();
  timeDelay = endTime - startTime;
  startTime = endTime;
  dispIntaval = timeDelay / (WIDTH + 10);
  course = RIGHT;
  location = WIDTH + 10; //오른쪽 끝으로 위치 초기화
}

void setup()
{
  for(int i = 0; i <= 10 ; i++) pinMode(ledPin[i], OUTPUT); //출력 초기화
  attachInterrupt(0, fromLEFT, RISING); //인터럽트 등록
  attachInterrupt(1, fromRIGHT, RISING);
}
/* LED출력을 담당할 함수 */
/* 변수 val은 몇번째 font 배열의 몇번째 줄을 디스플레이 할것인지를 결정하는 인자값*/
void dispLed(int val)
{
  if (course == LEFT) for (int i = 9; i>= 0; i--) digitalWrite(ledPin[i], font[val][i]);
  if (course == RIGHT) for (int i = 0; i<= 10; i++) digitalWrite(ledPin[i], font[val][i]);
}

void loop()
{
  location = ( millis() - endTime) / dispIntaval; // 시간으로 위치 추정
  if (course == RIGHT) (location = (WIDTH + 9) - location); // 오른쪽에서 출발했을 경우 위치를 뒤집음
  if ((location >= 4) && (location < (WIDTH + 4 ))) dispLed(location-4);//양 끝쪽 불확실한 부분이 아닐경우 LED로 디스플레이
  delay(dispIntaval); //다음 위치에 도달할때까지 대기
}