달력

5

« 2024/5 »

  • 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

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 //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 //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를 쓰기로 하였다.

:
Posted by youjin.A