본문 바로가기
정나우/STM32

STM32로 산업용 모터 제어하기

by 정_나우 2023. 2. 10.

겨울 방학 세미나를 위해 STM32로 산업용 모터를 제어하는 것을 공부해봤습니다.

 

공부한 내용을 정리하고 기록하기 위해 작성합니다.

 

순서는 크게 전장과 STM32로 나누었습니다.


모터를 돌리기 위해 필요한 구성요소를 알아보려면 우선 모터의 작동원리에 대해 알 필요가 있습니다.

 

자석으로 인해 자기력이 만들어지고 (왼 => 오)

코일에 전류를 흘려주게 되면

 

플레밍의 오른손법칙에 의해 전자기력이 발생하여 회전을 하게 되는 원리입니다.

 

이때 코일이 그림에서 90도 회전하게 되면 더 이상 토크가 발생하지 않게 되는데 

이를 해결하기 위해 코일을 하나 더 배치하여 십자 모양을 만들게 되면 코일 하나에 토크가 발생하지 않을 때에도

나머지 코일 하나가 전자기력을 받아 회전하게 되므로 토크가 발생하지 않는 문제를 해결할 수 있습니다.

 

이와 같은 원리로 코일을 무수히 많이 배치하게 되면

흔히 볼 수 있는 모터의 구조가 되게 됩니다.

 

정류자와 브러시전류의 방향을 일정하게 유지하는 역할을 하는 부품입니다.

코일은 회전하는데 항상 같은 방향으로 전류가 흐르게 되면 전자기력이 발생하는 방향이 계속 바뀌게 되므로

정류자의 중간이 끊긴 원통 모양으로 인해 코일에서는 항상 같은 방향으로 전류가 흐르게 됩니다.

 

하지만 이런 원리로 모터를 회전시키려면 정류자와 코일은 항상 접지되어 있으면서 회전을 하기 때문에 마찰이 발생할 수 밖에 없어서 이것이 모터의 수명을 크게 좌지우지하게 됩니다.

 

그래서 요즘에는 이런 기계식이 아닌 전기식으로 모터를 회전시켜 브러시를 없앤 BLDC모터를 많이 사용하곤 합니다.


아무튼 결국 모터의 방향, 세기, 속도 등을 조절하려면 모터에 공급하는 전류를 제어할 수 있어야 합니다.

 

하지만 우리는 모터를 원하는 만큼의 속도나 세기를 만들기 위해 어느 정도의 전류를 줘야할지 모르기 때문에

우리는 PLC라는 컨트롤러에서 명령을 내리면 서보앰프에서 그 명령을 받아 적당한 전류를 서보모터에 공급하게 됩니다.

결국 모터를 돌리기 위해서는 크게 PLC, 서보앰프, 서보모터가 필요하게 됩니다.


구성요소는 다음과 같았고

 

이제 전장 설계를 시작하겠습니다.

 

미쓰비시 산업용 모터의 매뉴얼을 참고하여 전원을 공급하기 위한 전장을 설계합니다.

단상220V => 차단기 => 전자 접촉기 => 노이즈 필터 => 서보 앰프 순서로 전원이 공급됩니다.

 

실제로 만든 사진입니다.

부품을 하나씩 간단히 설명하면

 

차단기는 사용자가 수동으로 전원 공급 제어를 할 수 있게 만든 장치입니다. 추가로 과전류 발생시 자동으로 차단하는 기능이 있습니다.

 

전자접촉기는 전자접촉기 밑쪽에 있는 코일에 전류를 공급하면 전자기력이 발생하면서 위쪽에 회로가 닫히게 되어 연결이 되는 방식의 전기 장치입니다. 전자접촉기 연시 과전류가 발생하면 자동으로 차단하는 기능이 있습니다.

 

산업용 모터를 제어하기 위해서는 큰 전류를 사용하기 때문에 굉장히 위험합니다.

그래서 사고를 방지하기 위해 전류를 차단하는 여러 장치를 설치하는 것입니다.

 

이외에도 한 곳에서 나온 전선을 여러 곳으로 빠져나가게 하기 위해 단자대를 사용했고,

여러 전기장치를 거쳤기 때문에 노이즈가 발생했으므로 노이즈 필터로 서보앰프에 깔끔한 전원이 들어가도록 했습니다.

 

이 외에도 매뉴얼을 보고 서보앰프에 전원을 연결하고

 

엔코터 케이블과 모터 전원 리드선, 중계 단자대를 연결해주었습니다.

 


전원 공급과 관련된 배선을 거의 끝이 났고

이제 중계 단자대 배선을 보겠습니다.

저는 속도/토크 제어를 할 거기 때문에 속도제어와 토크제어 배선도를 참고했습니다.

 

기본적인 구동을 위해서는 빨간 네모를 친 부분만 먼저 연결해주면 됩니다.

 

두 모드의 배선도를 자세히 보면 크게 차이가 없고 속도제어에 선이 몇개 더 있는 것을 확인할 수 있습니다.


배선도의 주의사항 12번을 보면 내부전원을 사용하는 경우 VDD와 COM을 연결하라고 나와있습니다.

 

중계 단자대의 다양한 신호를 사용하기 위해서 전원을 각각의 신호선에 연결해줘야 하는데

외부 전원을 써도 되고 내부전원을 써도 됩니다.

저는 내부 전원을 쓰기 위해 오른쪽 그림처럼 VDD(3번)과  COM(13번)을 연결해주었습니다.

서보앰프의 내부 접속도를 보면 더욱 이해가 잘 될 겁니다.

그리고 주의사항 6번을 보면 비상정지신호, 정/역전 스트로크 엔드를 반드시 단락하고 되어있습니다.

 

비상정지신호는 잠시 치워두고 정/역전 스트로크 엔드에 대해서 설명하자면

리니어모터 같은 경우는 처음과 끝이 정해져 있기 때문에 그 한계점을 지나서도 모터를 회전시키면 부품이 고장나게 됩니다.

이를 방지하기 위해 정/역전 스트로크 엔드를 이용해서 정방향 역방향 회전의 끝에 도달했을 때 신호를 줘서 모터의 회전을 멈추게 하는 겁니다.

하지만 저는 회전의 제한이 없는 상황이므로 그냥 단락(연결)해서 작동에 이상이 없게 해주었습니다.

 

또한, 정역전개시 신호를 연결해줘야 모터가 회전을 하는데

기본 회전 방향을 정하는 것이라고 생각하면 됩니다.

둘 중에 하나만 연결을 하면 되기 때문에 저는 ST1을 연결해주었습니다.

 

정리를 하면 LSP, LSN, ST1을 SG와 스위치 없이 바로 연결해주었습니다.

 

이제는 스위치를 연결해야 하는 신호선을 보겠습니다.

 

비상정지 스위치는 평소에 연결되어 있다가 누르는 순간 연결이 끊기게 됩니다.

서보ON은 일반 스위치를 연결하면 됩니다.

리셋은 평소에는 끊겨있다가 스위치를 누른 순간에만 연결되는 스위치를 연결해줍니다.

속도선택2라고 나와있는 SP2는 속도/토크 모드에서는 모드 선택 스위치이기 때문에 셀럭트 스위치를 연결해줍니다.

이런 내용들은 매뉴얼을 잘 찾아보면 나와있습니다.

 

매뉴얼을 참고해서 다음과 같이 중계단자대 배선을 완료했습니다.

 

이렇게 배선작업이 완료됐습니다.

 

이 글만 보면 되게 금방한 것 같지만

사용해야 하는 도구와 부품도 많고 깔끔하게 만드려면 계속 수정을 해야하는 작업이 많아

시간을 꽤나 써서 고생한 기억이 나네요.


이제는 STM32 파트로 넘어가겠습니다.

 

STM32는 쉽게 말하면 아두이노의 업그레이드 버전이라고 이해하면 됩니다.

 

아두이노에서는 그냥 간단한 명령어로 제어했던 것을 좀 더 아랫단에서 명령함으로써 더욱 정교하고 빠르게 제어할 수 있게 됩니다.

 

STM32의 장점은 가격대비 성능이 좋고

STM32에서 제공하는 프로그램을 이용하 명령어를 작성할 때 GUI(그래픽)기반으로 초기 설정을 하면 코드를 알아서 작성해주기 때문에 입문자가 사용하기에 적합합니다.

 

우리가 STM32로 해야할 것은 서보앰프로 들어가는 아날로그 지령을 만드는 것입니다.

 

그런데 한 가지 문제가 있습니다.

 

STM32로는 아날로그 출력을 0~3.3V까지 할 수 있는데

 

미쓰비시 모터의 매뉴얼을 보면 -10V~10V를 제공해야 모터를 온전히 사용할 수 있는 것을 확인할 수 있습니다.

STM32의 아날로그 출력선을 바로 연결하게 된다면

최대 출력의 30%밖에 사용하지 못 할테고, 방향도 한 방향만 쓸 수 밖에 없게 됩니다.

 

이런 문제를 해결하기 위해 아날로그 모터 드라이버를 변압기처럼 이용

0~3.3V를 -12V~12V로 바꾼 다음 서보앰프로 신호가 갈 수 있도록 만들어주었습니다.


모터드라이버 내용은 잠시 치워두고 우선 STM32로 아날로그 출력과 디지털 출력을 하는 법에 대해 알아보겠습니다.

 

1. Cube IDE를 설치합니다.

(이전 버전을 사용하면 잘 안 되는 경우가 있습니다. 저는 현재기준 제일 최신 버전인 1.11.2를 사용했습니다.)

https://www.st.com/en/development-tools/stm32cubeide.html

 

2. 프로그램을 열어서 새 프로젝트를 열어줍니다. (File → New → STM32 Project)

 

3. Board Selector → F429ZI 검색 → Board list에서 더블 클릭 → Next

   STM32에서는 다양한 보드를 제공합니다. 

   그리고 자동으로 코드를 작성하고 핀을 배정하기 위해서는 사용자가 어떤 보드를 사용하는지 알려줘야 합니다.

   필자는 F429ZI 모델을 썼지만 다른 모델을 사용했다면 그 모델을 검색해서 똑같이 진행하면 됩니다.

 

4. Project 이름 설정 후 나머지는 다 기본값으로 설정 후 Next

 

5. Timers → TIM6 → Actiavted 체크

    Parameter Settings → Prescaler 83, Counter Period 9,999 설정

   타이머는 내가 원하는 시간에 정확하게 신호를 주기 위해 존재합니다.

   그리고 내가 사용하고자 하는 기능에 따라 이용 가능한 타이머가 따로 있습니다.

   아날로그 출력을 사용할 때는 기본 타이머인 TIM6, 7을 이용하면 됩니다.

 

  Prescaler와 Counter Period를 83, 9999로 설정한 이유는 

  F429ZI 보드의 통신 주기 식이 8.4 x 10^7 / ((Precaler +1) x (Counter Period +1)) 이기 때문에

  주기를 1,000으로 맞추기 위함입니다.

 

  보드별로 통신 주기 식이 다르기 때문에 확인 후 원하는 통신 주기를 만들어 주면 됩니다.

 

6. NVIC Interrupt Table → Enabled

좀전에 언급한 타이머를 이용하는 방식을 인터럽트 방식이라고 하는데

이 방법을 사용하기 위해 인터럽트를 Enabled 해줍니다.

 

7. Analog → DAC → OUT1 Configuration 체크

이 모델에서는 아날로그 출력을 두 개 사용 가능한데

(디지털과 다르게 아날로그는 만들기 위해 복잡한 회로가 들어가기 때문에 사용 갯수 제한이 있습니다.)

 

그 중에서 하나를 사용하도록 설정해줍니다.

 

8. 아날로그 출력을 위한 모든 설정이 끝났습니다. 

    Ctrl + s 를 눌러 코드를 생성합니다.

    main.c로 이동해 main문 안에 다음과 같은 내용을 추가합니다.

HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
HAL_TIM_Base_Start_IT(&htim6);

 

9. main문 밖에 인터럽트 콜백 함수를 추가합니다.

   위에서는 메인문에서 tim6를 발동시킨다는 내용을 넣은 거고

   지금은 tim6가 발동되었을 때 실행될 내용을 작성하는 것입니다.

 

   코드를 간단히 설명하자면 DAC_ALIGN_8B_R은 최대값을 2^8인 256으로 설정한다는 뜻입니다.

   하지만 0부터 시작이기 때문에 사실은 입력 가능한 범위는 0~255입니다.

   그리고 0~255 중에 100이면 40%정도이기 때문에 3.3V x 0.4 → 1.32V가 아날로그 출력 핀에서 나오게 됩니다.

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM6)
    {
    	HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_8B_R, 100);
    }
}

 

10. Pinout & Configuration에서 DAC_OUT 핀 번호를 체크합니다. 

저는 PA_4가 아날로그 출력핀으로 설정되었네요.


이제 디지털 출력에 대해 알아보겠습니다.

 

1. Pinout & Configuration에서 사용 중이 아닌(Reset_State) 임의의 핀을 GPIO_Output으로 설정

   아날로그와 달리 디지털은 사용자가 직접 핀을 지정해줍니다.

   저는 PB3핀을 디지털 핀으로 설정해주었습니다.

    

2.  System Core → GPIO → 설정한 핀 번호 → GPIO Pull-up/Pull-down → Pull-up

     디지털은 0또는 1이기 때문에 0V 혹은 3.3V를 출력해야 합니다.

     하지만 실상은 3.3V가 아니라 3.2V처럼 3.3V가 아닌 애매한 출력이 나옵니다.

     그래서 이런 0이나 3.3V가 아닌 다른 신호가 나왔을 때 이를 0으로 처리할지 1로 처리할지를 결정하는 과정입니다. 

     Pull-up으로 설정했기 때문에 애매한 신호는 모두 1로 처리하게 됩니다.

 

3. Ctrl + s를 눌러 코드 생성 → main문 안 while 문에 디지털 코드 작성

while (1)
  {
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
  }

핀 번호가 PB3기 때문에 GPIOB, GPIO_PIN_3, 로 설정했습니다.

1 신호를 보낼 땐 SET, 0일 땐 RESET을 써줍니다.


프로그램 설정은 끝입니다.

 

이제 STM32의 핀번호 배치도를 확인해서 모터드라이버와 연결해줍니다.

PA_4는 아날로그 출력, PB_3는 디지털출력입니다.

 

단상 220V 전원을 SMPS를 통해 12V로 나오게 만든 뒤 모터드라이버와 연결해주었고

아날로그 출력을 VR, 디지털 출력을 Dir에 연결해줍니다.

그리고 STM32의 GND를 VR과 Dir에 옆에 있는 GND와 연결해줍니다.

 

이제 0~3.3V가 0~12V로 매핑되었고

Dir 신호를 통해 + -를 바꿀 수 있어 -12V ~ 12V의 전류를 공급 가능하게 되었습니다.

 

모터드라이버의 출력은 M1, M2에서 하기 되므로

매뉴얼을 보고 지령을 내리는 핀과 그라운드에 각각 연결해줍니다.

저는 M1을 속도지령과 토크지령에 동시에 연결해주었습니다.


이제 모터를 돌리기 위한 모든 준비가 끝났습니다.

 

이제 약간의 설정만 더 해주면 됩니다.

 

일단 서보앰프에 전원을 인가한 뒤 파리미터 값을 바꿔서 속도와 토크 제어모드로 설정해줍니다.

매뉴얼을 참고하여 0번 파라미터의 값을 3번으로 설정해줍니다.

 

0일 땐 속도모드

1일 땐 토크모드 임을 확인했습니다.

 

STM32를 컴퓨터와 연결한 뒤 프로그램을 실행합니다.

이때 Run으로 실행을 하게 되면 작성한 코드가 계속 실행되는데

 

우리는 속도와 방향을 계속 바꾸기 위해 Debug 기능을 사용할 겁니다.

 

Debug 기능을 사용하기 위해서는 약간의 추가 설정이 필요합니다.

 

 

변수 두 개를 등록하고 아날로그, 디지털 출력 함수에 변수를 넣고 약간의 코드를 추가합니다.

 

디버그 실행 → Live Expressions에 변수 등록 → Resume → 변수를 바꿔가며 모터가 작동하는지 확인 

 

잘 작동하는 것을 확인할 수 있습니다.

 

댓글