질문게시판 > 스위치로 PI 모터 제어

TODAY23,318 TOTAL9,410,937
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 질문게시판 | 스위치로 PI 모터 제어

페이지 정보

작성자 바밤 작성일2024-11-11 19:33 조회448회 댓글0건

본문

	

ATmega128로 스위치 on됐을 때 PI제어를 하려고 해서 모터 한 개 있을 때까지는 확인이 됐습니다. 

모터 두 개 있을 때 소스코드가 어느부분에서 문제가 되는지 잘 모르겠어서 질문 남깁니다..!

OCR을 각 각 0,1번으로 써도 되는지 문제가 되면 어느부분을 수정하면 되는지 질문남겨요 ㅜㅜ

 

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

#include <stdio.h>

 

//#define F_CPU 16000000UL  // CPU 주파수 16MHz

 

// PID 제어 관련 변수

volatile int reference1 = 100;  // 목표 각속도

volatile int reference2 = 100;  // 모터 2의 목표 속도

volatile int current_speed1 = 0; // 현재 각속도

volatile int current_speed2 = 0; // 모터 2의 현재 속도

volatile double error1 = 0, error2 = 0;

volatile double integral1 = 0, integral2 = 0;

volatile double control1 = 0, control2 = 0;

 

// PID 제어 파라미터

volatile double Kp = 0.01;

volatile double Ki = 0.01;

 

// 엔코더 관련 변수

volatile unsigned int num1 = 0, num2 = 0;

volatile int start = 0;             // 스위치

 

void port_Init()

{

DDRA = 0xFF;  // 포트 A를 출력으로 설정

DDRB = 0xFF;  // 포트 B를 출력으로 설정 (PWM 신호 출력)

DDRD = 0x00;  // 포트 D를 입력으로 설정 (인터럽트 입력, encoder 신호)

DDRE = 0x00;  // PORTE의 PE0 핀을 입력으로 설정, 나머지 핀을 출력으로 설정

PORTA = 0xFF; // 포트 A 초기화

PORTE = 0x00; // PE0 핀을 풀다운 저항으로 설정 (기본값 LOW)

}

 

// 타이머 설정 (100ms 주기)

void Timer1_init()

{

TCCR1A = 0x00;

TCCR1B = 0x03; // 64분주

TIMSK = 0X04;  // Timer1 overflow interrupt

TCNT1 = 40536; // 16MHz에서 100ms 주기

}

 

// 외부 인터럽트 설정

void INT0_init()

{

EICRA = 0x03;  // INT0 rising edge

EIMSK = 0x01;  // INT0 활성화

}

 

 

// PWM 설정

void Timer0_init()

{

DDRB = 0x10;     // PB4를 출력으로 설정 (OC0)

TCCR0 = 0b01101010;  // Fast PWM 모드, 8분주, Clear OC0 on compare match

}

 

// PWM 설정 (모터 2)

void Timer2_init()

{

DDRB = 0x02; // PB7를 출력으로 설정 (OC2)

TCCR2 = 0b01101010; // Fast PWM 모드, 8분주, Clear OC2 on compare match

}

 

// UART 초기화

void usart_Init()

{

UBRR0H = 0;

UBRR0L = 103;         // 9600 baud rate 설정

UCSR0B = 0x18;        // 송신 가능, 수신 가능 설정

UCSR0C = 0x06;        // 데이터 비트 8비트, 패리티 없음, 1 스톱 비트 설정

}

 

// UART로 송신 함수

void usart_Transmit(unsigned char data)

{

while (!(UCSR0A & (1 << UDRE0))); // 송신 버퍼가 비어질 때까지 대기

UDR0 = data;                      // 데이터를 버퍼에 저장

}

 

// 문자열을 UART로 전송

void usart_Print(char* str)

{

while (*str)

{

usart_Transmit(*str++);

}

}

 

// PI 제어기

void PI_control1()

{

error1 = reference1 - current_speed1;

integral1 += error1;

control1 = Kp * error1 + Ki * integral1;

 

// 모터 속도 제한: 0~255

if (control1 > 255) control1 = 255;

if (control1 < 0) control1 = 0;

 

OCR0 = (int)control1;

}

 

// PI 제어기 (모터 2)

void PI_control2()

{

error2 = reference2 - current_speed2;

integral2 += error2;

control2 = Kp * error2 + Ki * integral2;

 

if (control2 > 255) control2 = 255;

if (control2 < 0) control2 = 0;

 

OCR2 = (int)control2;  // 모터 2의 PWM 신호

}

 

// 인터럽트: 엔코더 펄스 카운트

ISR(INT0_vect)

{

num1++;

num2++;

}

 

 

// 인터럽트: 100ms마다 각속도 계산 및 PID 제어 수행

ISR(TIMER1_OVF_vect)

{

// 100ms 동안의 엔코더 펄스 수를 이용하여 속도 계산

current_speed1 = (num1 * 10.0);  // 각속도 (1초 단위로 환산)

current_speed2 = (num2 * 10.0);  // 모터 2 속도

num1 = 0;

num2 = 0;

TCNT1 = 40536;

PI_control1();

PI_control2();

 

char buffer[200];

snprintf(buffer, sizeof(buffer), "current_speed1: %d %d %d, current_speed2: %d %d %d\r\n", current_speed1 / 100, current_speed1 % 100 / 10, current_speed1 % 10, current_speed2 / 100, current_speed2 % 100 / 10, current_speed2 % 10);

usart_Print(buffer);

_delay_ms(1000);

 

}

 

int main(void)

{

port_Init();

Timer0_init();

Timer1_init();

INT0_init();

usart_Init(); // UART 초기화

 

sei();  // 전역 인터럽트 허용

 

while (1)

{

 

// 스위치가 눌렸는지 확인하고 start 변수 업데이트

if (PINE & 0x01)  // PE0 핀에서 입력된 스위치 상태 확인

{

start = 1;  // 스위치가 켜져 있으면 start = 1로 설정

}

else

{

start = 0;  // 스위치가 꺼져 있으면 start = 0으로 설정

}

 

// start 값에 따라 모터 제어

if (start == 1)

{

OCR0 = (int)control1;  // 모터 속도 유지

OCR2 = (int)control2;

}

else

{

OCR0 = 0;  // 모터 정지

OCR2 = 0;

}

 

}

 

  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글 0

조회수 448

등록된 댓글이 없습니다.