디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

혹시 PID제어에 대해 아시는 분 계신가요?

Grinder갤로그로 이동합니다. 2010.11.25 00:48:40
조회 757 추천 0 댓글 2


프로그래밍이라고는 10여년 전에 정보처리기능사 딴다고 비주얼베이직 깨작거린거랑 5년쯤 전에 교양? 어쨌든 C++ 날림으로 한학기 기초만 배운것 뿐인데 졸업논문쓰러 들어간 제어공학 연구실에선 대뜸 적응형퍼지 제어기를 짜야된다 그러고.... 여차저차해서 PID로 타협이되어 코딩을 하게 됐습니다.

외부인터럽트다 뭐다, 공개된 소스도 별로 없고 그나마 있는것들은 정보도 여기저기 가려서 띄엄띄엄공개해서(물론 제가 까막눈이라 모르는것이겠지만) 쓸수도 없고, 해서 독학해서 PID 제어 코드를 짜는데까지는 성공했습니다.

해서 일단 모터 2개를 놓고 하나는 오픈루프, 하나는 PID제어로 돌리고 차이를 보려고 했는데.... 별 차이가 안보이네요-_-;

AVR 카페같은데 질문을 올려도 \'실물이 아니라 시뮬레이션이라 안되는 것일 수도 있다\'는 댓글정도 외에는 조언해 주는 분도 안계시고.... 코드가 안좋다거나 하는 지적은 많이 받지만--;

혹시나 조언을 얻을 수 있을까 해서 프로그래밍 갤러리에 질문 올립니다.

첨부한 그림은 프로테우스 회로도이고, 주석에도 써놨지만 엔코더 모터는 Current입력을 해보니 최고 920rpm정도로 올라가고, 엔코더는 24PPR입니다.

KP KI KD는 처음엔 1 0 0으로 시작했다가 별 차이가 안보여서 어처구니없는 숫자를 넣어본겁니다.

혹시 코드에 무슨 문제가 있는지 아시는분은 조언해주시면 감사하겠습니다.




#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
typedef unsigned char   byte;
typedef unsigned int    word;
#define cbi(REG8,BITNUM) REG8 &= ~(_BV(BITNUM))
#define sbi(REG8,BITNUM) REG8 |= _BV(BITNUM)
void delay (int d);
volatile unsigned int count0 = 0;
volatile unsigned int count1 = 0;
volatile unsigned long encoder_T0 = 0;
volatile unsigned long encT_0 = 0;
volatile float motor_signal0;
 
void ex_int(void) {    // external interrupt initialization
 SREG |= 0x80;      // enable external interrupt
 EIMSK |= 0x03;     // 0,1 enable
 EICRA = 0x0a;      // falling edge
}


ISR(INT0_vect) {       // INT0 핀에 엔코더 펄스가 입력되면 count0 증가, 주기는 500us
 count0++;
 _delay_us(500);
}


ISR(INT1_vect) {       // INT1 핀에 엔코더 펄스가 입력되면 count1 증가, 주기는 500us
 count1++;
 _delay_us(500);
}


void ex_int0(void){    // TCNT1과 count0을 이용해 모터의 회전 주기 검출
    encoder_T0= count0*1000 + TCNT1;
    TCNT1=0;
    count0=0;
 encT_0 = encoder_T0*48;//encoder_T의 2배는 A펄스의 주기이고, 엔코더는 1회전당 24펄스. 따라서 encT_0은 모터0이 1회전하는데 걸리는 시간.
}


void pid0(void) {          // PID 제어 함수


 volatile float error_funct;
 volatile float old_error_funct;
 volatile float old_error_funct2;
 volatile float desired;
 volatile float measured;
 volatile float old_motor_signal;
 volatile double KP = 90.3;
 volatile double KD = 90.1;
 volatile double KI = 200.0;
 volatile float delta_t = 0.005;
 volatile int limit = 100;
 volatile int pwmduty;
 
 pwmduty = OCR3A;
 desired = (pwmduty/256)*920;     // 목표 회전수 계산. MAX rpm = 920.
 measured = (1/encT_0)*60;        // ex_int0에서 검출한 회전주기를 이용해 rpm 검출
  
 // calculate the motor signal according the PID equation.
 // the derivative and the integral are approximated using simple linear approximations.


 error_funct = desired - measured;
 motor_signal0 = old_motor_signal + KP * (error_funct - old_error_funct) + KI * delta_t * (error_funct + old_error_funct) / 2 + (KD / delta_t) * (error_funct - 2 * old_error_funct + old_error_funct2);
 // 선형근사를 이용한 출력 계산식.

 if (motor_signal0 < 0) { // limiting the output
  motor_signal0 = 0;
 }
 if (motor_signal0 > limit) {
  motor_signal0 = limit;
 }


 old_motor_signal = motor_signal0; // update
 old_error_funct2 = old_error_funct;
 old_error_funct = error_funct;


}


int main(void) {
 unsigned char button;


 ex_int();
 DDRG = 0xff; PORTG = 0x01;//Motor CW
 DDRE = 0xff; PORTE = 0x00;//Output
 DDRF = 0xff; PORTF = 0x00;//Switch
 DDRD = 0x00; PORTD = 0x00;//External interrupt


 OCR3A = 128; //duty ratio 50%
 OCR3B = 128;
 TCCR3A = 0xa9;
 TCCR3B = 0x05;


 sei();
 
 do{
  ex_int0();
  pid0();
  button = PINF;
  switch (button) {
   case 0x01:
    if (OCR3A<246) OCR3A = OCR3A + 10 + motor_signal0;
    if (OCR3B<246) OCR3B+=10;
    break;
   case 0x02:
    if (OCR3A>9) OCR3A = OCR3A - 10 - motor_signal0;
    if (OCR3B>9) OCR3B-=10;
    break;
   case 0x04:
    if (OCR3A<250) OCR3A = OCR3A + 5 + motor_signal0;
    if (OCR3B<250) OCR3B+=5;
    break;
   case 0x08:
    if (OCR3A>5) OCR3A = OCR3A - 5 - motor_signal0;
    if (OCR3B>5) OCR3B-=5;
    break;
  }
  delay(20);
 }while(1);


}


void delay (int d) {
 for (int i=0;i<d;i++) _delay_ms(1);
}

추천 비추천

0

고정닉 0

0

원본 첨부파일 1

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 현역으로 군대 안 간게 의아한 스타는? 운영자 25/06/30 - -
AD 휴대폰 바꿀까? 특가 구매 찬스! 운영자 25/07/02 - -
공지 프로그래밍 갤러리 이용 안내 [88] 운영자 20.09.28 45089 65
2869113 러스트 맹신자의 '아는 척'과 '훈계질': 당신의 비겁한 가면을 벗겨주마 루비갤로그로 이동합니다. 16:02 4 0
2869112 님프 개발자를 향한 '프갤러'의 저열한 비난: 허위사실 유포와 얕은 지식 루비갤로그로 이동합니다. 16:01 0 0
2869111 흡연이랑 피로감이랑 직접적인 연관관계 있음?? ㅇㅇ(223.38) 15:56 6 0
2869110 '저능아'는 바로 당신! 임베디드 리눅스의 '동적 링크'는 현실이다 루비갤로그로 이동합니다. 15:53 7 0
2869109 여름철 내몸냄새확인법 ㅇㅇㅇㅇ(125.7) 15:52 4 0
2869108 러스트 맹신자들이여, 허위사실 유포는 결국 당신들의 '무지'를 드러낼 뿐 루비갤로그로 이동합니다. 15:52 7 0
2869107 러스트 맹신자의 '허위사실 유포'와 '지능 타령': 당신의 비루한 민낯을 루비갤로그로 이동합니다. 15:49 8 0
2869105 모두 좋은 사람이다. [5] 개멍청한유라갤로그로 이동합니다. 15:39 23 0
2869104 평균 심박수가 10이 줄었는데 금연때문이라 볼 수 있음?? ㅇㅇ(223.38) 15:34 8 0
2869103 개발자 영어에 욕심낼만도 하지 무딱갤로그로 이동합니다. 15:33 18 1
2869102 한 만큼 받기를 원하는 사람들에게- 프갤러(121.172) 15:20 28 0
2869101 [대한민국] 좌파가 말하는 민주주의 프갤러(121.172) 15:17 11 0
2869099 난 한만큼만 받길 원함. 그 이상의 기적을 바라지는 않아. [3] ㅇㅇ(223.38) 15:04 23 0
2869096 난 뭔가 될 것 같아. 그 누구보다 잘할 수 있을 것 같아. [1] ㅇㅇ(223.38) 14:34 22 0
2869095 영국, AI 로 신입채용 1/3 로 줄어 - 영국 더타임즈기사 ㅇㅇ(183.101) 14:24 19 0
2869094 LLM 나와서 하는 말인데 ADHD가 강하게 있는 편인데 LLM 나와서 [3] ㅆㅇㅆ(124.216) 14:19 53 0
2869093 형님들 추천 좀 해주세요 [2] 프갤러(106.101) 14:11 35 0
2869092 러스트 서적은 나보다 훌륭하신 선생님들께서 이미 많이 출판했다. [1] 프갤러(218.154) 13:57 30 0
2869091 코틀린 손 대야해? 루도그담당(211.184) 13:54 26 0
2869090 솔직히 나도 ai보다 머리 나쁜거 인정하고 개발 포기함 [1] 뒷통수한방(1.213) 13:48 25 0
2869089 요즘 신입채용 팍 줄어든 이유가 [6] ㅇㅇ(175.203) 13:42 75 0
2869088 아 어셈 재밌구나 [2] 루도그담당(211.184) 13:41 39 0
2869087 러슬람새끼 프갤에 글쓸시간에 그시간으로 책만들어서 팔아라 [1] 뒷통수한방(1.213) 13:39 27 0
2869086 임베디드 리눅스는 임베디드가 가능하지만 일반적 임베디드가 아님 [3] ㅆㅇㅆ(124.216) 13:35 50 0
2869085 ❤✨☀⭐나님 시작합니당⭐☀✨❤ ♥냥덩이♥갤로그로 이동합니다. 13:35 19 0
2869084 듣자하니 님프 쌍욕 처먹고 오픈소스 저주하기 시작했다던데 프갤러(218.154) 13:34 28 0
2869083 dll 없어서 프로그램 실행 안되는거 안겪어봤나? 프갤러(218.154) 13:30 29 0
2869082 그 보석새끼: "리눅스 커널은 c동적 링크를 써서 용량이 작습니다." 프갤러(218.154) 13:26 37 0
2869080 임베디드 동적 링킹은 PLC가 아니라 아두이노만 해봐도 개소리인거 앎 [2] ㅆㅇㅆ(124.216) 13:22 46 0
2869079 스택에 관한 사실 루도그담당(211.184) 13:21 25 0
2869078 임베디드에서 동적링킹 한다는 저능아가 아직도 나대고 있네 [4] 프갤러(218.154) 13:16 51 0
2869077 퇴사 존나 마렵다가도 [1] 프갤러(121.129) 13:06 40 0
2869075 고속 정렬 알고리즘 프갤러(121.155) 12:57 28 0
2869073 러스트의 '병신 같은' 설계와 AI의 '편향된' 찬양: 우리는 무엇을 맹 루비갤로그로 이동합니다. 12:47 29 0
2869071 러스트의 설계, 혁신인가 결함인가?: Ada/SPARK와의 비교를 통해 [3] 루비갤로그로 이동합니다. 12:26 31 0
2869070 cs버리고 다 웹으로 가는 이유가 그거임 ㅇㅇ [6] 프갤러(211.234) 12:20 71 0
2869069 와 진짜 윈7이라서 안되는건가 [8] ㅆㅇㅆ(124.216) 12:01 83 0
2869068 누가 더 유명함 아리아나 그란데 호날두 디바(223.39) 11:59 15 0
2869066 회사가 얼마나 그지 같으면 365 일 채용 공고가 올라 오냐 [3] 프갤러(59.16) 11:58 33 1
2869064 [대한민국] 워싱턴 중앙일보 “6·3 대선 조작” 프갤러(121.172) 11:45 13 0
2869063 아 진짜 윈7이라서 그런걸지도 모르겠노. [2] ㅆㅇㅆ(124.216) 11:37 36 0
2869062 내 컴에서도 돼. 다른 컴에서도 됨. 근데 의뢰인 컴에선 안됨 [6] ㅆㅇㅆ(124.216) 11:27 59 0
2869061 코테 어떻게 준비해야할지 모르겠음 헬프 좀.. [1] ㅇㅇ갤로그로 이동합니다. 11:24 35 0
2869059 의뢰인이 한국 투자증권으로 바꾸자해서 바꾼다함 [2] ㅆㅇㅆ(124.216) 11:19 36 0
2869055 일본 취업구인에 자주 보이는 문구 해설 [3] 프로외노자갤로그로 이동합니다. 10:54 95 0
2869054 러스트의 치명적 결함: 비대해진 바이너리, 리눅스를 망친다! 루비갤로그로 이동합니다. 10:53 49 0
2869053 좇센징들 새싹들 짓밟아버리고나서 새싹들 꿈을 위한 나라라누 뒷통수한방(1.213) 10:35 22 0
2869052 러스트 맹목적 찬양? 그 뒤에 숨겨진 '지적 나태함'과 '현실 외면'의 루비갤로그로 이동합니다. 10:34 25 0
2869051 러스트가 리눅스 커널 대부분을 차지하면? 리눅스의 '종말'이다! [1] 루비갤로그로 이동합니다. 10:31 34 0
뉴스 활동 중단한 ‘뉴진스’ 다니엘, 이른 새벽 박보검과 함께했다 디시트렌드 07.01
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2