2016. 2. 8. 02:57
보드를 바꾼 후 ESC에 400Hz제어를 시도했지만... 작품/쿼드콥터2016. 2. 8. 02:57
400Hz PWM 파형을 만듬
아두이노에서는 16bit카운터가 하나밖에 없어서 ESC를 제어하기 위해 PWM파형을 400Hz로 출력하는 데 많은 문제가 있다.
이것은 프로그램상의 문제였는데.. 결국에는 실패하고 50Hz를 사용하기로 하였다.
하지만 메가2560은 16bit 카운터가 4개가 있었기 때문에 400Hz를 출력해도 프로그램상 아무 문제가 없었다.
그래서 FAST PWM모드를 이용한 카운터 인터럽트로 400Hz를 만들었다.
아래 코드는 단순히 핀에서 400Hz PWM이 나오도록 한 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /////////////////BLDC Motor///////////////// #define MAX_THROTTLE 4760 #define MIN_THROTTLE 1040 #define MAX_PWM 4000 #define MIN_PWM 1040 #define MOTOR1 11 //motor pin number #define MOTOR2 12 //motor pin number #define MOTOR3 13 //motor pin number #define MOTOR4 5 //motor pin number //////////////////////////////////////////// class motor { private: int pin; public: void attach(int); void write(int); }; void motor::attach(int motorPin) { pin = motorPin; TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1) | _BV(WGM11); //16bit-Timer/Counter1 FAST PWM TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); TCCR3A = _BV(COM3A1) | _BV(WGM31); //16bit-Timer/Counter3 FAST PWM TCCR3B = _BV(WGM33) | _BV(WGM32) | _BV(CS30); ICR1 = 40000; ICR3 = 40000; } void motor::write(int pwm) { switch(pin) { case MOTOR1 : OCR1A = pwm; break; case MOTOR2 : OCR1B = pwm; break; case MOTOR3 : OCR1C = pwm; break; case MOTOR4 : OCR3A = pwm; break; default : Serial.println("wrong motor pin"); } } void setup() { pinMode(MOTOR1, OUTPUT); pinMode(MOTOR2, OUTPUT); pinMode(MOTOR3, OUTPUT); pinMode(MOTOR4, OUTPUT); motor motor1; motor motor2; motor motor3; motor motor4; motor1.attach(MOTOR1); motor2.attach(MOTOR2); motor3.attach(MOTOR3); motor4.attach(MOTOR4); motor1.write(MAX_THROTTLE); motor2.write(MAX_THROTTLE); motor3.write(MAX_THROTTLE); motor4.write(MAX_THROTTLE); } void loop() { // put your main code here, to run repeatedly: } | cs |
하지만..
하지만 우리의 esc인 ipeaka esc 22a님께서 400Hz가 너무 빠른지 못받아 들이신다.
아래 코드는 400Hz에다가 초기에 최대 듀티비와 최소 듀티비를 변하게해서 ESC를 callibration하는 코드를 추가한 것이다.
callibration을 할 때 max를 주문 "띠 띠띠"소리 나는 거랑 min을 주면 "띠 띠~띠~띠"소리 나는 설정이 안된다...ㅠ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | /////////////////BLDC Motor///////////////// #define MAX_THROTTLE 4760 #define MIN_THROTTLE 1040 #define MAX_PWM 4000 #define MIN_PWM 1040 #define MOTOR1 11 //motor pin number #define MOTOR2 12 //motor pin number #define MOTOR3 13 //motor pin number #define MOTOR4 5 //motor pin number int throttle = MIN_THROTTLE; //////////////////////////////////////////// class motor { private: int pin; public: void attach(int); void write(int); }; motor motor1; motor motor2; motor motor3; motor motor4; void motor::attach(int motorPin) { pin = motorPin; pinMode(pin, OUTPUT); TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1) | _BV(WGM11); //16bit-Timer/Counter1 FAST PWM TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); TCCR3A = _BV(COM3A1) | _BV(WGM31); //16bit-Timer/Counter3 FAST PWM TCCR3B = _BV(WGM33) | _BV(WGM32) | _BV(CS30); ICR1 = 60000; ICR3 = 60000; } void motor::write(int pwm) { switch(pin) { case MOTOR1 : OCR1A = pwm; break; case MOTOR2 : OCR1B = pwm; break; case MOTOR3 : OCR1C = pwm; break; case MOTOR4 : OCR3A = pwm; break; default : Serial.println("wrong motor pin"); } } //----------------------------------------------------------------- //esc조절 하기 void callibration(void) { Serial.println("Calibrate ESC? 'y' or 'n'."); while (!Serial.available()); char cali = Serial.read(); if(cali == 'y'){ Serial.println("send max throttle"); motor1.attach(MOTOR1); motor2.attach(MOTOR2); motor3.attach(MOTOR3); motor4.attach(MOTOR4); motor1.write(MAX_THROTTLE); motor2.write(MAX_THROTTLE); motor3.write(MAX_THROTTLE); motor4.write(MAX_THROTTLE); delay(5000); Serial.println("send min throttle"); motor1.attach(MOTOR1); motor2.attach(MOTOR2); motor3.attach(MOTOR3); motor4.attach(MOTOR4); motor1.write(MIN_THROTTLE); motor2.write(MIN_THROTTLE); motor3.write(MIN_THROTTLE); motor4.write(MIN_THROTTLE); delay(2000); Serial.println("callibration complete"); }else if(cali == 'n'){ motor1.attach(MOTOR1); motor2.attach(MOTOR2); motor3.attach(MOTOR3); motor4.attach(MOTOR4); motor1.write(MIN_THROTTLE); motor2.write(MIN_THROTTLE); motor3.write(MIN_THROTTLE); motor4.write(MIN_THROTTLE); } Serial.println("If you want Program keep going. Press any key."); while (!Serial.available()); } //----------------------------------------------------- void send_val(void) { if(Serial.available()){ char c = Serial.read(); if(c=='q'){ throttle += 1; Serial.print("throttle = ");Serial.println(throttle); }else if(c=='w'){ throttle -= 1; Serial.print("throttle = ");Serial.println(throttle); }else if(c=='e'){ throttle= MAX_THROTTLE; Serial.print("throttle = ");Serial.println(throttle); }else if(c=='r'){ throttle= MIN_THROTTLE; Serial.print("throttle = ");Serial.println(throttle); } } } //제어값을 받어서 모터 구동 void run_motors(int val) { int motor1Power, motor3Power; // Motors on the X axis //=>; changing their speeds will affect the pitch int motor2Power, motor4Power; // Motors on the Y axis //=>; changing their speeds will affect the roll motor1Power = val; motor2Power = val; motor3Power = val; motor4Power = val; motor1.write(motor1Power);motor3.write(motor3Power); motor2.write(motor2Power);motor4.write(motor4Power); } //----------------------------------------------------------- void setup() { Serial.begin(115200); callibration(); } //---------------------------------------------------------------------// // // main // //--------------------------------------------------------------------// void loop() { // put your main code here, to run repeatedly: send_val(); run_motors(throttle); } | cs |
220Hz로 낮추면 어쩔때는 되고 어떨때는 안되서 ... 하드웨어 적인 문제때문에 결국은 50Hz를 쓰기로 하였다.
'작품 > 쿼드콥터' 카테고리의 다른 글
쿼드콥터 하드웨어 완성! (2) | 2016.02.08 |
---|---|
ESC, IMU, 무선조종기 수신기 각각을 테스트하다 (0) | 2016.02.08 |
아두이노 메가2560으로 MCU를 교체하다 (0) | 2016.02.08 |
무선 조종기와 카메라 테스트 (0) | 2016.02.08 |
롤 제어 (0) | 2016.02.08 |