[54호]Trash Can Do It!(스마트 쓰레기통)
2018 ICT 융합 프로젝트 공모전 참가상
Trash Can Do It!(스마트 쓰레기통)
글 | 단국대학교 정성윤, 김민우, 김종욱, 전현우, 김지호
1. 심사평
칩센 생활 친화적인 아이디어입니다. 개요의 내용과 다르게 쓰레기를 자동 압축하는 부분이 메인 기능으로 보입니다. 최근 이슈가 되는 분리수거 문제에 더 접근 해결책을 제시하였으면 어땠을까 합니다.
뉴티씨 쓰레기통 뚜껑을 사람이 접근 시 자동으로 개폐하고, 쓰레기양에 따라 스스로 압축하는 스마트 쓰레기통을 구현하셨습니다. 쓰레기통의 찬 양 등도 서버 측에 알려줄 수 있도록 조금만 개선되면 더 좋으리라고 생각됩니다. 기계와의 전자와의 연동은 쉽지 않은 것인데, 이러한 부분까지도 잘 구현해 낸 부분을 좋은 점수를 드립니다. 앞으로도 이렇게 다른 분야를 서로 연결하여 작품으로 만드는 등의 작품을 많이 만드시면 큰 도움이 되시리라 생각합니다.
위드로봇 기존의 압축 쓰레기통에 인식 기능까지 추가한 부분이 인상적입니다. 보고서 상에서 인식률이나 동작 시 단점에 대한 보완책이 보이지 않아 아쉽네요.
2. 작품 개요
저희 팀은 일상에 불편함을 해결해주고 친환경적인 작품을 만들고 싶어 ‘Trash Can Do It!’을 만들게 되었습니다. 많은 사람들은 꽉 찬 쓰레기통을 밟다 신발이 더러워지는 경험이나, 뚜껑이 있는 쓰레기통을 열다 손에 오물이 묻은 경험이 있을 것입니다. 자동으로 열리는 쓰레기통이 있으면 이런 불쾌함이나 찝찝함을 해결시켜 줄 수 있을 거라 생각합니다.
그리고 뉴스를 통해 쓰레기를 처리하는데 연간 100억원 정도의 큰 비용이 든다는 사실을 접했습니다. 금전적인 문제뿐만 아니라 쓰레기를 처리하는 과정에서 화학 물질이 발생하여 대기와 토지 오염 등 많은 환경 문제도 발생합니다. 최근 미세먼지를 보며 대기오염의 심각함을 느낍니다.
저희 팀은 쓰레기를 압축해 주고 버리는 쓰레기의 종류를 분석할 수 있으면 처리 비용 절감과 환경 문제 해결에 작게라도 기여할 수 있을 거라 생각하여, ‘Trash Can Do It!’이라는 작품을 제작하게 되었습니다.
3. 주요 동작 및 특징
‘Trash Can Do It!’은 사람과의 거리에 따라 투입구를 개폐할 수 있는 기능, 쓰레기가 적정량 이상 차면 스스로 압축을 하는 기능이 있습니다.
전체 외형은 방수가 되고, 외부 충격에 대해 강도가 있어야 하기 때문에 아크릴판으로 주문 제작 하였습니다. 개패구가 열고 닫히게 하는 기능은 서보모터를 사용해 구현하였습니다. 그리고 압축부는 베벨기어를 연결부로 사용하여 스텝모터와 볼스크류를 연결해 설계하였습니다.
소프트웨어는 초음파 센서 값을 기준으로 알고리즘을 구성하였습니다. 두 개의 초음파 센서가 각각 Trigger와 Echo 신호를 주고받으며 거리를 측정합니다. 그리고 Echo가 트리거의 신호를 타이밍에 맞추어 감지하게 하기 위해 외부 인터럽트를 사용하였고, 잡음을 제거하기 위해 IIR 필터를 사용하여 값의 정확성을 높였습니다. 투입구의 경우 디지털 방식의 서보모터를 사용했습니다. 서보모터에 알맞은 PWM 파형을 주어 적절한 각도로 투입구를 개패할 수 있게 하였습니다. 압축부 역시 초음파 센서를 사용하였습니다. 초음파 센서가 적정량 이상의 쓰레기를 감지하면, 인터럽트를 이용해 모터에 1-2상을 주어 유니폴라 스텝 모터를 굴렸습니다. 스텝 모터가 작동하면 볼스크류가 내려오며 볼스크류에 연결된 아크릴 압축판이 쓰레기를 압축시킵니다. 그리고 압축을 하는 동안 카운트를 해주다 일정 거리 이상 내려오면 FLAG 변수를 이용해 상을 반대로 주어 압축부가 원래 위치로 되돌아오게 설계하였습니다. 그리고 ‘Trash Can Do it!’의 가장 큰 장점은 딥러닝을 사용하여 스스로 학습할 수 있다는 것입니다. 먼저 여러 장에 사진을 찍어 Neural Network Algorithm을 통해 이미지 처리를 해줍니다. 그렇게 하면 학습된 자료를 바탕으로 물체가 무엇을 의미하는지 이해하고 분류시켜서 쓰레기인지 아닌지 결론짓게 됩니다. 그리고 그 결과 값을 서버를 통해 안드로이드 APP으로 넘겨줘 스마트폰을 통해 확인할 수 있게 하였습니다.
3.1. 하드웨어
1. 센서부
센서는 4핀 초음파 센서인 HC-SR04를 사용하였습니다. 이 초음파 센서를 선택한 이유는 전원부를 설계할 때 레귤레이터를 LM2576T를 사용하여 Output이 5V로 출력됩니다. 그래서 필요한 전력이 5V이하인 센서를 선택하였고, MCU를 TMS2809를 사용하였기 때문에 GPIO핀을 이용해 제어가 가능하기 때문입니다. 그리고 Max Range와 Min Range 역시 각각 4m, 2cm로 쓰레기 적재량 측정과 물체와의 거리를 측정하는데 적합할 것 같아 선택했습니다. 다가오는 물체를 감지하는 초음파 센서는 입구부분에 직접 구멍을 뚫어 방해 받지 않게 설계 하였습니다. 그리고 내부 초음파 센서는 비어있을 때의 깊이를 적절히 측정하는 각도를 조절하여 설치하였습니다.
2. 모터부
(1) 스텝모터
스텝모터의 경우 유니폴라 스텝모터인 SST42D2120을 사용하였습니다. 유니폴라 스텝모터는 회로가 간단하며 고속 회전시 토크가 높은 특징을 가지고 있습니다. 저희는 모터로 압축판을 내려 쓰레기를 압축해야 하기 때문에 힘이 센 유니폴라 모터를 선택하였습니다. 그리고 회로가 간단하여 상을 주기 쉽고 인터럽트를 이용한 제어가 쉬워 선택하게 되었습니다. 모터드라이브는 모터의 전압을 줬을 때 최대 46V까지의 높은 전압을 견딜 수 있는 SLA7026M을 사용하여 제어하였습니다.
(2) 서보모터
투입구에는 서보모터 Tower Pro 90s를 사용하였습니다. 이 서보모터는 3개의 핀을 갖고 있고 각각 줄 색깔에 따라 빨간색은 VCC, 갈색은 Ground, 주황색은 PWM 핀으로 사용합니다. 회전 각도는 좌우로 180도 까지 회전 가능하고 PWM 핀에 주는 Pulse에 따라 각도가 변경됩니다. 저희 작품은 줄을 연결해 투입구를 연결하므로 180도까지 회전이 가능한 서보 모터를 선택 했습니다. 그리고 투입구인 아크릴판 무게를 제보고 고장 없이 투입구를 열고 닫을 수 있게, 토크가 4.8V에서 1.8 kgf·cm인 이 서보모터를 선택하게 되었습니다.
3. 압축부
압축부는 회전 운동을 직선 운동으로 바꿔야 했기 때문에 볼스크류를 사용하였습니다. 그리고 모터의 회전 원 운동을 볼스크류의 상하 직선 운동으로 바꾸어 주기 위해 둘 사이 베벨기어를 연결하였습니다. 그리고 압축판의 경우 원형 모양의 아크릴판을 주문 제작하여 만들었고, 압축판과 볼스크류 연결부 사이에는 환봉을 이용해 ㄱ자로 구현하였습니다.
4. 하드웨어 설계
하드웨어는 쓰레기통이므로 외부의 충격에 강해야 하고, 오물이 묻으면 방수가 되고 쉽게 닦아내야 한다고 생각했습니다. 그래서 아크릴판으로 주문 제작 하였습니다. 하드웨어를 구상하면서 가장 큰 문제는 봉투를 달아야 하는 문제와, 압축할 때 봉투가 찢어지는 문제였습니다. 볼스크류에 압축판을 바로 연결하면 봉투를 볼스크류 때문에 봉투를 걸 수 없었습니다. 그래서 하드웨어를 설계할 때 볼스크류 연결부에 환봉을 달아 ㄱ자로 설계해 봉투를 달 공간을 확보했습니다. 그리고 봉투를 옆면에 고정하면 압축부가 내려가면서 봉투가 찢어지는 문제가 있었는데 이는 용수철을 달아서 압축하면 같이 봉투도 같이 내려가게 설계하여 해결 했습니다. 전체적으로 구상한 하드웨어는 solid works 라는 3D 모델링 프로그램을 통해 구현했고, 이후 청계천에 있는 아크릴사에 주문 제작 하였습니다.
3.2. 소프트웨어
1. 센서부
HC-SR04는 4개의 핀중 가운데 2개의 핀을 각각 Echo핀과 Trigger핀으로 사용합니다. Trigger핀에 센서 스펙에 알맞은 신호를 보내주면 Echo핀에서 거리 값이 펄스로 나오게 됩니다. HC-SR04는 10us의 펄스를 Trigger 신호로 보내면 초음파가 반사되어 돌아오는 시간에 비례한 펄스가 다시 Echo핀에서 출력됩니다.
그래서 MCU에서 Trigger, Echo핀은 각각 GPIO핀 2개를 이용하여 Trigger핀에 출력 핀으로 설정한 GPIO핀을 연결하고, Echo핀에 입력 핀으로 설정한 GPIO핀을 연결하여 펄스를 주고받으며 거리를 측정하게 하였습니다.
위에 Trigger핀은 펄스를 아무 때나 쏘면 되지만, Echo핀은 언제 펄스가 들어올지 모르기 때문에 외부 인터럽트를 사용해 펄스가 뜨면(rising) 곧바로 감지할 수 있게 하였습니다. 그리고 물체가 접근하는지 감지하기 위해 설치한 초음파 센서와 쓰레기의 적재량을 감지하는 초음파 센서 두 개를 우선순위 없이, 동시에 사용하면 하나의 초음파에 인터럽트가 멈추는 오류가 발생하기 때문에 두 외부 인터럽트 사이에 우선순위를 두어 오류가 나지 않도록 알고리즘을 구성 하였습니다.
이렇게 구성한 후 뿌려본 결과 노이즈가 생겨 값이 불규칙적으로 올라가는 것을 관찰할 수 있었습니다. 그래서 노이즈를 제거하기 위해 IIR필터를 사용하였습니다. IIR필터는 디지털 필터의 한 종류로 구현식의 형태가 반복 됩니다. 그래서 함수의 응답이 무한히 반복되어 필터 딜레이가 짧다는 장점이 있습니다. 초음파 센서 값에 대한 응답이 빠르지 않아 값이 중간에 튕기는 현상이 있어 IIR필터를 사용해 딜레이를 줄여 주었습니다. 그리고 또 초음파 센서 값이 0부터 시작하여 처음에 사람이 가까이 가지 않아도 투입구가 열리는 문제가 있었습니다. 그래서 타이머 인터럽트를 사용하여 1초 동안 작동시킨 후에 초음파 센서의 값을 받게 하도록 설계하였습니다.
2. 모터부
(1) 스텝모터
스텝모터의 제어방식에는 1상 여자 방식, 2상 여자 방식, 1-2상 여자 방식이 있습니다. 제어방식에 따라 입력 pulse와 step의 특성이 달라집니다. 1상은 출력토크가 낮다는 단점이 있었고, 2상은 1상에 비해 2배의 전원 용량이 필요하나, 토크가 높아 난조가 일어날 확률이 낮습니다. 따라서 1상과 2상을 반씩 합쳐 놓아 부드러우면서 토크가 적당히 쎈 1-2상 여자 방식을 사용해 안정성을 높였습니다.
스텝모터의 기본 원리는 상을 순서대로 ON 시키면서 회전을 하는 것입니다. 사용한 모터는 2상 4선식 모터로 A, B, A’, B’를 각각 GPIO 0번 1번 2번 3번 핀에 연결하고 1-2상에 맞게 GPIO핀을 ON시켜 상을 만들어 모터를 굴렸습니다. 그리고 스텝모터는 상을 반대로 주면 거꾸로 회전하므로 모터의 상을 바꾸어 원래 원래 자리로 돌아가게 구성하였습니다. 이렇게 만들어 놓은 상은 interrupt를 이용해 쓰레기가 차면 실행되게 하였습니다.
모터의 1-2상과 뒤집은 상은 각각 구조체 flag를 사용하여 묶어놓아, 내부 적재량이 많아지면 모터를 정 방향으로 굴려주는 flag.motor_start=1로 변경하여 압축을 하고, 어느 정도 압축을 하면 flag.motor_start=0으로 변경 합니다. 그리고 역방향으로 상을 주는 flag.motor_up=1로 바꿔 압축판을 원위치에 올려놓은 후 flag.motor_up=0으로 바꿔 작동을 멈추게 알고리즘을 구성 하였습니다.
(2) 서보모터
서보모터의 경우 위에서 설명한 듯이 PWM 펄스를 조절해 각도를 제어 합니다. 작품에서 사용한 서보모터의 경우 20ms 주기로, 1-2ms의 Duty cycle을 가지고 있어, 1.5ms의 펄스를 주면 0도, 2ms의 펄스를 주면 90도, 1ms의 펄스를 주면 -90도를 움직이게 됩니다. 그래서 InitEPWM_Servo라는 함수를 만들어 주어 조건에 맞게 PWM 사용 환경을 만들어 준 후, GPIO 4번 핀을 PWM으로 설정하여 CMPA 레지스터로 알맞은 펄스를 주는 방식으로 제어했습니다.
3. 쓰레기통 전체 알고리즘 설계
전체 알고리즘은 초음파 센서 값을 기준으로 구성하였습니다. 전면부의 경우 초음파 센서 값에 적절한 PWM 파형을 서보모터에 주어 알맞은 각도로 열고 닫히게 하였습니다. 압축부 역시 초음파 센서 값을 기준으로 소스를 구성하였습니다. 압축부에서 초음파 센서가 쓰레기가 찼다고 감지하면 압축부가 내려오게 하였습니다. 그러나 이 경우 사람이 손을 넣으면 압축부가 내려오는 문제가 있어서 해결하기 위해 사람이 가까이 있을 때는 손을 넣어도 압축하지 않게 소스를 구성하였습니다. 그리고 압축이 시작되면 카운트를 하는 변수가 증가하고, 일정 시간이 지나면 압축판이 다시 올라오도록 구성하였습니다.
4. Neural Network Algorithm
쓰레기통에 들어가는 쓰레기 이미지 처리를 위해 딥러닝을 활용하게 되었습니다. 딥러닝을 활용하여 쓰레기 이미지 처리를 할 뿐만 아니라 학습 된 자료를 바탕으로 스스로 쓰레기를 분류할 수도 있습니다. 딥러닝이라 불리는 인공신경망은 사람의 뇌의 작동방식을 모방하여 작동하는 알고리즘입니다. 이를 통해서 스스로 물체가 무엇을 의미하는지 이해하고 분류시켜서 쓰레기인지 아닌지 결론짓게 됩니다.
이미지 인식 문제는 각 물체마다 있는 특성을 따로 찾아내어, 이를 쉽게 찾아낼 수 있는 필터를 찾는 것이 주된 문제가 됩니다. 이때 인공신경망을 사용하면 이러한 특성을 찾아낼 수 있는 방법을 스스로 학습하게 됩니다. 물체를 종류별로 30장 정도 찍어서 폴더에 저장시키면, 콘볼루션 뉴럴 네트워크라고 불리는 이미지 인식 알고리즘을 통해 학습을 하게 됩니다. 이를 위해서 inception_v3 이라는 CNN 구조의 알고리즘을 사용하였습니다. CNN은 convolution neural network의 줄임말이며, convolution 레이어를 이용한 인공신경망을 뜻합니다.
convolution 레이어는 입력된 이미지에서 특징을 추출합니다. 이 레이어는 특징을 추출하는 기능을 하는 필터와, 이 값을 비선형 값으로 바꾸는 활성화 함수로 이루어져 있습니다. 필터는 원하는 특징이 이미지 데이터에 있는지 없는지 검출해주는 함수입니다. 필터를 사용해 자신이 분류하고자 하는 물체의 특징을 포착하여 다른 물체와 구분을 하게 합니다. 이렇게 필터를 지난 데이터는 활성화 함수를 지나 결과값을 출력하게 됩니다. 활성화 함수는 결과값을 0과1로 표현하지 않고 0~1 값에 골고루 분포되게 합니다. 이를 통해 입력된 이미지가 자신이 원하는 물체일 확률을 계산할 수 있습니다.
기존처럼 각각의 데이터를 각각 다른 방식으로 분류하는 방법을 스스로찾는 것은 어렵습니다. 어떤 데이터에 어떤 방식이 동작하는지 일일이 찾아야 하기 때문입니다. CNN의 일종인 inception_v3를 통해 자동적으로 데이터를 분류하는 방식을 찾아내어서 시간을 획기적으로 줄일 수 있습니다.
inception_v3 알고리즘에서 먼저 학습시킬 이미지 경로를 지정해 둡니다. 이 이미지 경로를 통해 폴더 구조를 살펴보고, 이미지에 대한 리스트를 생성하게 됩니다. 이런 이미지를 행렬화 시켜서 CNN에 넣음으로써, 커널은 점점 주어진 이미지를 통해 필터링하는 방법을 향상시킵니다.
각각의 필터는 경계선 추출과 같이 이미지를 분류하는데 효율적인 방법을 제공합니다. 이런 필터를 여러가지 크기로 복합적으로 사용해 이미지의 특징을 잘 잡아내려고 한 것이 inception_v3 알고리즘입니다.
일반적으로 새로운 데이터를 통해 분류 알고리즘을 설계하는 데에는 시간이 오래 걸립니다. 노드에 들어가는 가중치를 처음부터 학습시킬뿐만 아니라 검증에도 오랜 시간이 걸리기 때문입니다. 이를 해결하기 위해서 inception_v3 아키텍쳐를 기반으로 전이학습을 하였습니다.
전이학습된 알고리즘은 비슷한 분류 문제에서 새롭게 아키텍쳐를 설계하는 것보다 효율적으로 문제를 해결할 수 있습니다. 이렇게 전이학습된 알고리즘을 통해 미리 분류된 사진을 학습시키면 결과 수식이 나오는데, 이를 분류하는 알고리즘에 새로 집어넣습니다. 웹캠에서 일정 시간마다 사진을 찍어 분류 알고리즘에 전송하면, 알고리즘이 상위 5개 물체 중에서 가장 확률이 높은 물체 순으로 저장합니다. 저장된 정보는 서버를 통해 애플리케이션으로 전송됩니다. 모바일 애플리케이션을 통해 방금 들어갔던 물체가 특정한 쓰레기인지 아닌지 알 수 있습니다.
3.3. 전체 시스템 구성
3.4. 개발 환경(개발 언어, Tool, 사용 시스템 등)
저는 작품을 만들며 개발 언어로는 C언어로 사용하였습니다. 전자전기공학부 학생으로서 1학년 교육과정에서 C언어를 배웠고, 제가 개발한 환경인 sourse insight에서 C를 지원하기 때문에 이 언어를 선택하였습니다. 그리고 개발 툴은 texas instrument사에서 제작한 tms320f2809를 사용 하였습니다. 제어는 위에서 언급한 듯이 C언어를 지원하고, 비교적 디버깅이 쉬운 개발환경을 갖고 있는 source insight를 선택하였습니다. 그리고 PC에서 컴파일 한 파일은 teraterm 이라는 프로그램을 이용해 sci 통신으로 tms320f2809에 전달했습니다. 파이썬을 사용해 딥러닝 프로그램을 제작하였습니다. 이미지 인식 알고리즘을 제작하는데 텐서플로우를 사용하였고, 이를 애플리케이션으로 만드는데 안드로이드를 사용하였습니다.
4. 기타(회로도, 소스코드)
4.1. 소스코드
1. 제어에 필요한 변수 선언
typedef volatile struct{
Uint32 EchoWidth; // 에코 핀에서 나오는 펄스의 길이를 저장하는 저장하는 임시변수
int32 RealEchoWidth; // 에코 펄스가 폴링 되면 EchoWidth의 값을 대입
_iq17 RealEchoCM; //
Uint16 FlagEcho; // 에코를 받는 상황인지 확인하는 플래그
Uint16 FlagSonicON; // 초음파를 壤箏?상황인지 확인하는 플래그 ( 트리거 )
}UltraSonic;
__STRUCT_EXT__ UltraSonic Usonic;
__STRUCT_EXT__ UltraSonic Usonic2;
typedef struct flag_variable{
Uint16 u16section ;
Uint16 DIR:1 ;
Uint16 cover_close;
Uint16 motor_start;
Uint16 motor_up;
Uint16 m_t;
}flag_val;
__STRUCT_EXT__ flag_val flag;
2. 제어문 : main문
void main(void)
{
System_Init();
Variable_Init();
//LOAD
g_Tint1_Tic = 0 ;
g_Tint2_Tic = 0 ;
GpioDataRegs.GPACLEAR.bit.GPIO7 = 1;
GpioDataRegs.GPADAT.bit.GPIO9 = 0;
GpioDataRegs.GPACLEAR.bit.GPIO10 = 1;
GpioDataRegs.GPADAT.bit.GPIO11 = 0;
XIntruptRegs.XINT1CR.bit.ENABLE = 1;
XIntruptRegs.XINT1CR.bit.POLARITY = 1 ; // Rising edge
XIntruptRegs.XINT2CR.bit.ENABLE = 1;
XIntruptRegs.XINT2CR.bit.POLARITY = 1 ; // Rising edge
StartCpuTimer0();
//flag.motor_up=1;
StartCpuTimer2();
Usonic.RealEchoCM = _IQ17( 30.000 ) ;
interrupt void XINT_Sonic(){
volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER1.all ;
IER &= MINT1 ;
PieCtrlRegs.PIEIER1.all &= MG14 ;
PieCtrlRegs.PIEACK.all = 0xFFFF ;
EINT;
if( XIntruptRegs.XINT1CR.bit.POLARITY == 1 ){ // Rising 인 경우
Usonic.EchoWidth = 0 ;
Usonic.FlagEcho = 1 ; // Rising
XIntruptRegs.XINT1CR.bit.POLARITY = 0 ; // Falling 인 경우
}
else{
if( Usonic.EchoWidth < 20000 ){// max 5m -> 29411 cut 20000
Usonic.RealEchoWidth = Usonic.EchoWidth;
}
else{
Usonic.RealEchoWidth = -1 ;
}
Usonic.FlagEcho = 0 ; // Falling
XIntruptRegs.XINT1CR.bit.POLARITY = 1 ; // rising
}
PieCtrlRegs.PIEIER1.all = TempPIEIER ;
}
3. 제어문 : 외부interrupt
volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER1.all ;
IER &= MINT1 ;
PieCtrlRegs.PIEIER1.all &= MG17 ;
PieCtrlRegs.PIEACK.all = 0xFFFF ;
EINT;
if( g_u32Time >= (Uint32)2000000 ){ g_u32Time = (Uint32)2000000 ; }
else{ g_u32Time++ ;}
++g_Tint1_Tic ;
if( Usonic.FlagEcho ){
++Usonic.EchoWidth; // max 5m -> 29411
}
if( Usonic.FlagSonicON ){
if( g_Tint1_Tic == 10 ){ // SET Width (micro sec)
GpioDataRegs.GPACLEAR.bit.GPIO7 = 1 ;
Usonic.FlagSonicON = 0 ;
g_Tint1_Tic = 0;
}
}
else{
if( g_Tint1_Tic == 50000 ){ // CLEAR Width (micro sec){
GpioDataRegs.GPASET.bit.GPIO7 = 1 ;
Usonic.FlagSonicON = 1 ;
g_Tint1_Tic = 0 ;
}
}
++g_Tint2_Tic ;
if( Usonic2.FlagEcho ){
++Usonic2.EchoWidth; // max 5m -> 29411
}
if( Usonic2.FlagSonicON ){
if( g_Tint2_Tic == 10 ){ // SET Width (micro sec)
GpioDataRegs.GPACLEAR.bit.GPIO10 = 1 ;
Usonic2.FlagSonicON = 0 ;
g_Tint2_Tic = 0;
}
}
else{
if( g_Tint2_Tic == 50000 ){ // CLEAR Width (micro sec){
GpioDataRegs.GPASET.bit.GPIO10 = 1 ;
Usonic2.FlagSonicON = 1 ;
g_Tint2_Tic = 0 ;
}
}
PieCtrlRegs.PIEIER1.all = TempPIEIER ;
}
4. 제어문 : Timer interrupt
interrupt void motor_ISR(){
IER &= MINT14 ;
EINT;
if(flag.motor_start == ON)
{
u_cnt ++;
EPwm3Regs.CMPA.half.CMPA = (Uint16) 2600;
}
if(flag.motor_start == 2)
{
u_cnt ++;
EPwm3Regs.CMPA.half.CMPA = (Uint16) 2600;
}
if(flag.motor_up== ON)
{
u_cnt=33001;
u_cnt2 ++;
EPwm3Regs.CMPA.half.CMPA = (Uint16) 2600;
}
/*else if(flag.motor_start == OFF)
{
u_cnt = 0;
}*/
#if 1
if(flag.motor_start==1){
if( flag.u16section == 1 ){
GpioDataRegs.GPASET.bit.GPIO0 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 ;
flag.u16section = 2 ;
}
else if( flag.u16section == 2 ){
GpioDataRegs.GPASET.bit.GPIO0 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 ;
GpioDataRegs.GPASET.bit.GPIO2 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 ;
flag.u16section = 3 ;
}
else if( flag.u16section == 3 ){
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 ;
GpioDataRegs.GPASET.bit.GPIO2 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 ;
flag.u16section = 4 ;
}
else if( flag.u16section == 4 ){
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 ;
GpioDataRegs.GPASET.bit.GPIO1 = 1 ;
GpioDataRegs.GPASET.bit.GPIO2 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 ;
flag.u16section = 5 ;
}
else if( flag.u16section == 5 ){
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 ;
GpioDataRegs.GPASET.bit.GPIO1 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 ;
flag.u16section = 6 ;
}
else if( flag.u16section == 6 ){
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 ;
GpioDataRegs.GPASET.bit.GPIO1 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 ;
GpioDataRegs.GPASET.bit.GPIO3 = 1 ;
flag.u16section = 7 ;
}
else if( flag.u16section == 7 ){
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 ;
GpioDataRegs.GPASET.bit.GPIO3 = 1 ;
flag.u16section = 8 ;
}
else if( flag.u16section == 8 ){
GpioDataRegs.GPASET.bit.GPIO0 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 ;
GpioDataRegs.GPASET.bit.GPIO3 = 1 ;
flag.u16section = 1 ;
}
else;
}
#endif
#if 1
if(flag.motor_up==1){
if( flag.u16section == 8 ){
GpioDataRegs.GPASET.bit.GPIO0 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 ;
flag.u16section = 1 ;
}
else if( flag.u16section == 7 ){
GpioDataRegs.GPASET.bit.GPIO0 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 ;
GpioDataRegs.GPASET.bit.GPIO2 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 ;
flag.u16section = 8 ;
}
else if( flag.u16section == 6 ){
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 ;
GpioDataRegs.GPASET.bit.GPIO2 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 ;
flag.u16section = 7 ;
}
else if( flag.u16section == 5 ){
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 ;
GpioDataRegs.GPASET.bit.GPIO1 = 1 ;
GpioDataRegs.GPASET.bit.GPIO2 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 ;
flag.u16section = 6 ;
}
else if( flag.u16section == 4 ){
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 ;
GpioDataRegs.GPASET.bit.GPIO1 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO3 = 1 ;
flag.u16section = 5 ;
}
else if( flag.u16section == 3 ){
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 ;
GpioDataRegs.GPASET.bit.GPIO1 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 ;
GpioDataRegs.GPASET.bit.GPIO3 = 1 ;
flag.u16section = 4 ;
}
else if( flag.u16section == 2 ){
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 ;
GpioDataRegs.GPASET.bit.GPIO3 = 1 ;
flag.u16section = 3 ;
}
else if( flag.u16section == 1 ){
GpioDataRegs.GPASET.bit.GPIO0 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO1 = 1 ;
GpioDataRegs.GPACLEAR.bit.GPIO2 = 1 ;
GpioDataRegs.GPASET.bit.GPIO3 = 1 ;
flag.u16section = 2 ;
}
else;
#endif
}
}
4.2. 회로도
모터드라이브 SLA7026M 회로도