Skip to content
TUWLAB.com
모든 게시물에 대하여 '링크'
방식의 퍼가기만 허용합니다.
한양대학교 전자통신컴퓨터공학부
바라미
  • 376
  • 2604126
DNS Powered by DNSEver.com
AVR

[전자동 커튼] 제어보드 펌웨어 핵심구문

Posted 2010. 02. 23 Updated 2014. 04. 20 Views 6157 Replies 0
  while(1)
 {
  switch( dStatus )
  {
   case STAT_IDLE :   // Standby
   {
    // CSW Reaction
    switch( CSW )
    {
     case CSW_L : 
     {
      ctrlBuzzer(200, 100);
      ctrlLED(LC_G, BL);
      dStatus = STAT_MOVS_L;
     }
     break; 

     case CSW_N : 
     {
     
     }
     break;

     case CSW_R : 
     {
      ctrlBuzzer(200, 100);
      ctrlLED(LC_G, BL);
      dStatus = STAT_MOVS_R;
     }
     break;
    }
   }
   break;

   case STAT_STOP :   // Move Completed
   {
    // CSW Reaction
    switch( CSW )
    {
     case CSW_L : 
     {

     }
     break;

     case CSW_N : 
     {
      ctrlLED(LC_G, ON);
      dStatus = STAT_IDLE;
     }
     break;

     case CSW_R : 
     {

     }
     break;
    }
   }
   break;

   case STAT_MOVS_L :  // Move Start Left
   {
    MDIR(DIR_L);
    clutchFail = ctrlClutch(CLU_E);
    if( clutchFail )
    {
     ctrlBuzzer(500, 100);
     ctrlBuzzer(500, 100);
     ctrlBuzzer(500, 100);

     ctrlLED(LC_Y, BL);
     dStatus = STAT_ERROR;
    }
    else
    {
     dStatus = STAT_MOVI_L;
    }

    // CSW Reaction
    switch( CSW )
    {
     case CSW_L : 
     {
      
     }
     break;

     case CSW_N : 
     {
      dStatus = STAT_MOVE_L;
     }
     break;

     case CSW_R : 
     {
      dStatus = STAT_MOVS_R;
     }
     break;
    }
   }
   break;

   case STAT_MOVS_R :  // Move Start Right
   {
    MDIR(DIR_R);
    clutchFail = ctrlClutch(CLU_E);
    if( clutchFail )
    {
     ctrlBuzzer(500, 100);
     ctrlBuzzer(500, 100);
     ctrlBuzzer(500, 100);

     ctrlLED(LC_Y, BL);
     dStatus = STAT_ERROR;
    }
    else
    {
     dStatus = STAT_MOVI_R;
    }

    // CSW Reaction
    switch( CSW )
    {
     case CSW_L : 
     {
      dStatus = STAT_MOVS_L;
     }
     break;

     case CSW_N : 
     {
      dStatus = STAT_MOVE_R;
     }
     break;

     case CSW_R : 
     {

     }
     break;
    }
   }
   break;

   case STAT_MOVI_L :  // Moving Left
   {
    if( gPosition==GPOS_L )
    {
     dStatus = STAT_MOVE_L;
    }

    // CSW Reaction
    switch( CSW )
    {
     case CSW_L : 
     {

     }
     break;

     case CSW_N : 
     {
      dStatus = STAT_MOVE_L;
     }
     break;

     case CSW_R : 
     {
      dStatus = STAT_MOVS_R;
     }
     break;
    }
   }
   break;

   case STAT_MOVI_R :  // Moving Right
   {
    if( gPosition==GPOS_R )
    {
     dStatus = STAT_MOVE_R;
    }

    // CSW Reaction
    switch( CSW )
    {
     case CSW_L : 
     {
      dStatus = STAT_MOVS_L;
     }
     break;

     case CSW_N : 
     {
      dStatus = STAT_MOVE_R;
     }
     break;

     case CSW_R : 
     {

     }
     break;
    }
   }
   break;

   case STAT_MOVE_L :  // Move End Left
   {
    clutchFail = ctrlClutch(CLU_D);
    MDIR(DIR_S);
    if( clutchFail )
    {
     ctrlBuzzer(500, 100);
     ctrlBuzzer(500, 100);
     ctrlBuzzer(500, 100);

     ctrlLED(LC_Y, BL);
     dStatus = STAT_ERROR;
    }
    else
    {
     ctrlBuzzer(100, 100);
     ctrlBuzzer(100, 100);

     // CSW Reaction
     switch( CSW )
     {
      case CSW_L : 
      {
       dStatus = STAT_STOP;
      }
      break;

      case CSW_N : 
      {
       dStatus = STAT_STOP;
      }
      break;

      case CSW_R : 
      {
       dStatus = STAT_MOVS_R;
      }
      break;
     }   
    }
   }
   break;   case STAT_MOVE_R :  // Move End Right
   {
    clutchFail = ctrlClutch(CLU_D);
    MDIR(DIR_S);
    if( clutchFail )
    {
     ctrlBuzzer(500, 100);
     ctrlBuzzer(500, 100);
     ctrlBuzzer(500, 100);

     ctrlLED(LC_Y, BL);
     dStatus = STAT_ERROR;
    }
    else
    {
     ctrlBuzzer(100, 100);
     ctrlBuzzer(100, 100);

     // CSW Reaction
     switch( CSW )
     {
      case CSW_L : 
      {
       dStatus = STAT_MOVS_L;
      }
      break;

      case CSW_N : 
      {
       dStatus = STAT_STOP;
      }
      break;

      case CSW_R : 
      {
       dStatus = STAT_STOP;
      }
      break;
     }   
    }
   }
   break;

   case STAT_ERROR : // Error
   {
    // Reset
    ((void (*)())0x0000)();
   }
   break;
  }
 }

제어보드에 올라가는 펌웨어중 핵심구문만을 옮긴 것이다.

부팅 과정에서 각종 장치를 테스트(이라고 해봐야 클러치 테스트)를 수행하고, 이 과정에서 아무 이상이 발견되지 않으면 바로 위와의 무한루프로 진입하게 된다.


이 부분은 상태 기계(State Machine)를 switch-case 구문을 활용한 코딩으로 옮겨놓은 것이다.

PDS(Position Detection Switch)CSW(Control SWitch)의 상태에 따라 각 State를 이동하게 된다.

겨우 스위치 입력 하나 받아서 모터 두 개 제어하는데 무슨 이런 복잡한 구문이 필요하냐고 생각할지도 모르지만, 항상 전원이 인가되어 실생활에 활용되는 장치의 경우 오동작은 곧 화재 등의 재해로 이어질 수 있기 때문에 펌웨어를 제작할때 여러 가지 예외 상황를 고려한 세심한 코딩이 필수적이다.

커튼 제어도 단순하게 말하면 DC모터 정, 역회전만 구현할 수 있으면 충분하다고 할 수 있지만, 사용자의 편의나 안전을 위해 실제로는 여러 가지를 고려하여 펌웨어를 작성해야 하기 때문이다.

 

예를 들어, CSW를 오른쪽(열림)으로 돌려놓은 상태에서 커튼이 오른쪽 끝에 도달한 상황을 가정해보자.

커튼이 오른쪽 끝에 도달하면 오른쪽 PDS를 누르게 되고, 프로세서에서는 이를 감지하고 메인모터의 구동을 정지시킬 수 있다.

단순하게는 오른쪽 PDS가 눌리지 않은 경우에만 메인모터를 작동시키면 되지만, 이렇게 단순 FeedBack방식으로 펌웨어를 구성하면 다소 보기 좋지 않은 문제가 발생할 소지가 있다. (이런 단순한 동작만을 수행하려면 예초부터 프로세서 사용하지 않고 게이트들 조합해서 회로를 구성했을 것이다.)

커튼이 완전히 열린 다음에도 CSW를 원위치 하기 전까지는 오른쪽 PDS 누름 → 클러치 뺌, 메인모터 정지 → 고무벨트의 탄성에 의해 약간 후퇴 → 오른쪽 PDS 빠짐 → 클러치 넣음, 메인모터 작동 → 오른쪽 PDS 누름 → ...

이런 작동, 정지, 작동, 정지 과정이 무한반복되게 될 것이다.

커튼이 완전히 열린 다음에도 메인모터가 계속 회전을 하기 때문에 과열 등의 우려고 있고, 사용자 편의의 측면에서 생각해보더라도 커튼이 완전히 열려 오른쪽 PDS를 한 번 누른 다음에는 작동을 멈추는 것이 좋다.

즉, CSW가 똑같이 오른쪽(열림)에 있더라도 커튼을 열기 전인지, 혹은 열고난 후인지에 따라서 작동 여부를 결정해야 하는 것이다.

이러한 동작을 수행하는데 제격인 프로그램 모델이 바로 상태 기계(State Machine)이다.

다음은 실제 코딩에 들어간 각 State의 의미와, 상호 전환 관계에 대한 설명이다.


STAT_IDLE : 대기

부팅 완료 후 바로 진입하는 State이다.

이 State에서는 CSW의 상태만 지속적으로 확인하며, CSW를 좌측으로 돌린 경우 STAT_MOVS_L(좌측 이동 시작) State로 점프하고,

CSW를 우측으로 돌린 경우 STAT_MOVS_R(우측 이동 시작) State로 점프한다.

 

STAT_MOVS_L : 좌측 이동 시작

왼쪽으로 이동 명령이 떨어진 경우 최초로 진입하는 State이다.

이 State에서는 메인모터를 작동시키고, 클러치를 넣는 동작을 수행한다. 클러치 제어구문이 시간 지연(Delay) 방식으로 작성되었기 때문에 클러치 작동중에는 키 입력을 받지 않는다.

CSW가 좌측에 계속 있는 경우 STAT_MOVI_L(좌측 이동 중) State로 점프하고, CSW가 클러치 조작 도중 중립으로 옮겨진 경우(즉, 스위치를 왼쪽으로 옮겼다가 바로 중립으로 되돌린 경우) STAT_MOVE_L(좌측 이동 완료) State로 점프하며,

CSW가 우측으로 옮겨진 경우 STAT_MOVS_R(우측 이동 시작) State로 점프한다.

 

STAT_MOVS_R : 우측 이동 시작

오른쪽으로 이동 명령이 떨어진 경우 최초로 진입하는 State이다.

이 State에서는 메인모터를 작동시키고, 클러치를 넣는 동작을 수행한다. 클러치 제어구문이 시간 지연(Delay) 방식으로 작성되었기 때문에 클러치 작동중에는 키 입력을 받지 않는다.

CSW가 좌측으로 옮겨진 경우 STAT_MOVS_L(좌측 이동 시작) State로 점프한다. 

CSW가 클러치 조작 도중 중립으로 옮겨진 경우(즉, 스위치를 오른쪽으로 옮겼다가 바로 중립으로 되돌린 경우) STAT_MOVE_R(우측 이동 완료) State로 점프하며, CSW가 우측에 계속 있는 경우 STAT_MOVI_R(우측 이동 중) State로 점프하고,

 

STAT_MOVI_L : 좌측 이동 중

이 State에서는 좌측 PDS의 상태를 지속적으로 확인하고, 좌측 PDS가 눌려진 경우 STAT_MOVE_L(좌측 이동 완료) State로 점프한다.

CSW가 중립으로 옮겨진 경우(즉, 중간에 작동 정지 명령을 내린 경우) STAT_MOVE_L(좌측 이동 완료) State로 점프하고, CSW가 우측으로 옮겨진 경우 STAT_MOVS_R(우측 이동 시작) State로 점프한다.

 

STAT_MOVI_R : 우측 이동 중

이 State에서는 우측 PDS의 상태를 지속적으로 확인하고, 우측 PDS가 눌려진 경우 STAT_MOVE_R(우측 이동 완료) State로 점프한다.

CSW가 좌측으로 옮겨진 경우 STAT_MOVS_L(좌측 이동 시작) State로 점프하고, CSW가 중립으로 옮겨진 경우(즉, 중간에 작동 정지 명령을 내린 경우) STAT_MOVE_R(우측 이동 완료) State로 점프한다.

 

STAT_MOVE_L : 좌측 이동 완료

이 State에서는 클러치를 빼고, 메인 모터를 정지시켜 커튼의 이동을 중단시킨다.

CSW가 좌측에 계속 있거나, 중립으로 옮겨진 경우 STAT_STOP(정지 완료) State로 점프하고, CSW가 우측으로 옮겨진 경우 STAT_MOVS_R(우측 이동 시작) State로 점프한다.

 

STAT_MOVE_R : 우측 이동 완료

이 State에서는 클러치를 빼고, 메인 모터를 정지시켜 커튼의 이동을 중단시킨다.

CSW가 좌측으로 옮겨진 경우 STAT_MOVS_L(좌측 이동 시작) State로 점프하고, CSW가 우측에 계속 있거나, 중립으로 옮겨진 경우 STAT_STOP(정지 완료) State로 점프한다.

 

STAT_STOP : 정지 완료

이동 완료 후 CSW가 원위치로 돌아가기 전까지 이 State에 머물게 된다.

지속적으로 CSW의 상태만을 확인하며, CSW가 중립 위치로 옮겨진 경우 STAT_IDLE(대기) State로 점프한다.

 

STAT_ERROR : 오류(클러치 제어 실패) 발생

클러치 제어 구문이 있는 State에서 클러치 제어 실패가 발생한 경우 다음 순간 무조건 이 State로 점프하여 MCU를 소프트웨어 리셋하고 부팅과정부터 다시 시작한다.

부팅 과정에서 클러치 테스트를 실시하기 때문에 다시 한 번 클러치 점검을 하며, 만약 이 과정에서도 클러치 제어 실패가 발생할 경우 클러치 수동제어모드로 전환된다.


TAG •
서비스 선택
이용중인 SNS 버튼을 클릭하여 로그인 해주세요.
SNS 계정을 통해 로그인하면 회원가입 없이 댓글을 남길 수 있습니다.
댓글
?
Powered by SocialXE

List of Articles
번호 분류 제목 글쓴이 최근 수정일 조회 수
» AVR [전자동 커튼] 제어보드 펌웨어 핵심구문 TUW 2014.04.20 6157
160 AVR [전자동 커튼] 최종 자료 정리 및 추후 개선사항 file TUW 2017.06.02 7680
159 AVR [AVR 강의] AVR 강의노트 file TUW 2021.12.28 12339
158 AVR [AVR 강의] AVR 강의자료 - 1. 사전준비 및 오리엔테이션 file TUW 2021.12.28 13172
157 AVR [AVR 강의] AVR 강의자료 - 2. 기본 입출력 file TUW 2021.12.28 18819
156 AVR [AVR 강의] AVR 강의자료 - 3. 인터럽트 file TUW 2017.06.02 21419
155 AVR [AVR 강의] AVR 강의자료 - 4. 타이머/카운터, PWM 3 file TUW 2017.06.02 23979
154 AVR [AVR 강의] AVR 강의자료 - 5. 아날로그-디지털 변환기(ADC) file TUW 2017.06.02 31029
153 AVR [AVR 강의] AVR 강의자료 - 6. 직렬통신(USART) file TUW 2017.06.02 20880
152 AVR [AVR 강의] AVR 강의용 예제 프로그램 모음 file TUW 2017.06.02 63317
151 Android android.process.acore 문제 해결방법 file TUW 2021.12.28 24731
150 Android 안드로이드 Hello, World?! file TUW 2017.06.02 17619
149 Linux Ubuntu 에서 VirtualBox로 Windows 7 설치 및 사용하기 1 file TUW 2017.06.02 23358
148 Linux VirtualBox에서 USB 인식 문제 해결하기 2 file TUW 2020.02.10 23684
147 Linux 좀 더 '진짜같이' VirtualBox 활용하기 - 심리스 모드 외 file TUW 2017.06.02 43348
146 Android 안드로이드 가상머신을 활용하여 PC에서 카카오톡 사용하기 file TUW 2017.06.02 20181
목록
Board Pagination Prev 1 2 3 4 5 6 7 ... 13 Next
/ 13

Powered by Xpress Engine / Designed by Sketchbook

sketchbook5, 스케치북5

sketchbook5, 스케치북5