반응형
5. 모터 제어 소프트웨어 코드 구성
PWM부터 PID까지, 코드로 구현하는 모터 제어의 전과정
모터 제어는 단순한 “ON/OFF” 신호를 넘어서, 여러 하드웨어와 소프트웨어 모듈이 유기적으로 동작해야 합니다.
이번엔 실제로 **MCU(Microcontroller Unit)**에서 동작하는 모터 제어 코드를 어떻게 구성하는지 알아보겠습니다.
🧩 1. 전체 흐름 요약 – 제어 블록 구조
모터 제어는 일반적으로 아래의 구조를 따라 구성됩니다.
text
복사편집
[Sensor 입력] → [Target 계산] → [PID 제어] → [PWM 출력] → [Motor 동작]
✅ 각 블록 설명
블록설명
Sensor 입력 | 위치/속도 센서(Hall, Encoder 등) 또는 전류 측정 |
Target 계산 | 목표 속도, 위치, 토크 설정 (명령 입력 또는 내부 로직) |
PID 제어 | 목표값과 현재값의 차이를 바탕으로 보정 값 계산 |
PWM 출력 | 보정 값을 PWM 신호로 변환하여 모터 드라이버에 전달 |
Motor 동작 | 실제 회전 발생 |
⚙️ 2. 기본 코드 구성 예시 (C 언어 기준)
📁 주요 파일 구성
/MotorControl
┣ MotorControl.c ← 제어 메인 루틴
┣ MotorControl.h ← 함수 선언 및 상수 정의
┣ PWM_Driver.c/h ← PWM 초기화 및 설정
┣ Sensor_Driver.c/h ← 센서 읽기 (Hall, ADC 등)
┣ PID_Controller.c/h ← PID 연산 처리
┣ MotorControl.c ← 제어 메인 루틴
┣ MotorControl.h ← 함수 선언 및 상수 정의
┣ PWM_Driver.c/h ← PWM 초기화 및 설정
┣ Sensor_Driver.c/h ← 센서 읽기 (Hall, ADC 등)
┣ PID_Controller.c/h ← PID 연산 처리
🧪 3. 예제 코드 ① – PWM 출력 초기화 (Timer 기반)
void PWM_Init(void) {
// 예: Timer 채널 설정, 주기 및 듀티 설정
TMR01 = 0x03FF; // PWM 주기 설정 (예: 10kHz)
PWM01_DutyCycle(50); // 초기 듀티: 50%
TMR_Start(); // Timer 시작
}
// 예: Timer 채널 설정, 주기 및 듀티 설정
TMR01 = 0x03FF; // PWM 주기 설정 (예: 10kHz)
PWM01_DutyCycle(50); // 초기 듀티: 50%
TMR_Start(); // Timer 시작
}
🧠 4. 예제 코드 ② – 센서 데이터 읽기
int Get_RotorSpeed(void) {
int hallA = Read_HallSensorA();
int hallB = Read_HallSensorB();
int speed = Hall_to_Speed(hallA, hallB);
return speed;
}
int hallA = Read_HallSensorA();
int hallB = Read_HallSensorB();
int speed = Hall_to_Speed(hallA, hallB);
return speed;
}
📈 5. 예제 코드 ③ – PID 제어 함수
float PID_Compute(float target, float current) {
static float integral = 0.0f;
static float previous_error = 0.0f;
float error = target - current;
integral += error;
float derivative = error - previous_error;
float output = Kp * error + Ki * integral + Kd * derivative;
previous_error = error;
return output;
}
static float integral = 0.0f;
static float previous_error = 0.0f;
float error = target - current;
integral += error;
float derivative = error - previous_error;
float output = Kp * error + Ki * integral + Kd * derivative;
previous_error = error;
return output;
}
🔄 6. 예제 코드 ④ – 주기 제어 루프 (Scheduler 사용)
void MotorControl_Loop(void) {
int actual_speed = Get_RotorSpeed();
float control_output = PID_Compute(target_speed, actual_speed);
PWM01_DutyCycle(control_output); // 0~100% 범위
}
🧠 실전 팁
항목팁
PWM 분해능 | 최소 10bit 이상 권장 (0~1023) |
PID 튜닝 | Kp부터 조정하고, Ki/Kd는 천천히 적용 |
센서 노이즈 제거 | 이동 평균 필터(Moving Average) 추천 |
보호 로직 | 과전류, 과속 방지 클램핑 코드 필요 |
✅ 정리
모터 제어 코드는 다음과 같은 단계를 통해 작성됩니다:
- PWM 설정 – 전기 출력을 제어할 핵심 신호
- 센서 데이터 수집 – 현재 상태를 정확히 측정
- PID 연산 – 목표와의 차이를 보정
- 제어 루프 실행 – 실시간 반복 주기 설정
- 안정성과 성능 확보 – 필터링 및 보호 로직 추가
다음 편에서는 이 코드들을 기반으로 한 FOC(Field-Oriented Control) 흐름도 소개와 함께,
센서리스 방식에서 어떻게 위치를 추정하는지도 설명드릴게요.
반응형
'모터제어' 카테고리의 다른 글
7.IPM vs SPM 모터 구조 및 제어 방식 비교 (0) | 2025.04.05 |
---|---|
6. FOC (Field-Oriented Control) – 고성능 BLDC 제어의 핵심 (0) | 2025.04.05 |
4.모터제어방식 (0) | 2025.04.05 |
3.모터의종류 (0) | 2025.04.05 |
2.모터관련 용어 정리 (0) | 2025.03.30 |