

2Motor_CTRL 파일 제거
@c85883539392766fc3bac5693ad2052e7d608f22
--- 2Motor_CTRL.ino
... | ... | @@ -1,213 +0,0 @@ |
1 | -// July 30th 10:17 Updated | |
2 | - | |
3 | -// === 1번 모터 핀 정의 === | |
4 | -#define DIR_1 8 // DIR1 (드라이버 갈색 2번, 점퍼선 주황색) | |
5 | -#define ST_1 9 // START/STOP1 (드라이버 핑크 4번, 점퍼선 초록색) | |
6 | -#define PWM_1 45 // SPEED_IN1 (드라이버 주황색 6번, 점퍼선 노란색) | |
7 | -#define ENCA_1 2 // A상 (드라이버 보라색, 점퍼선 파란색) | |
8 | -#define ENCB_1 3 // B상 (드라이버 회색, 점퍼선 흰색) | |
9 | - | |
10 | -// === 2번 모터 핀 정의 === | |
11 | -#define DIR_2 22 // DIR2 (드라이버 갈색 16번, 점퍼선 주황색) | |
12 | -#define ST_2 24 // START/STOP2 (드라이버 핑크 17번, 점퍼선 초록색) | |
13 | -#define PWM_2 44 // SPEED_IN2 (드라이버 주황색 8번, 점퍼선 노란색) | |
14 | -#define ENCA_2 18 // A상 (드라이버 보라색, 점퍼선 파란색) | |
15 | -#define ENCB_2 19 // B상 (드라이버 회색, 점퍼선 흰색) | |
16 | - | |
17 | -// === 목표 RPM (부호 포함) === | |
18 | -int setRPM1 = 100; | |
19 | -int setRPM2 = 0; | |
20 | - | |
21 | -// === PID 계수 (모터별 개별 설정) === | |
22 | -double kp1 = 0.5, ki1 = 3.0, kd1 = 0.085; | |
23 | -double kp2 = 0.0, ki2 = 0.0, kd2 = 0.0; | |
24 | - | |
25 | -// === 모터 상태 변수 === | |
26 | -// 모터 1 | |
27 | -volatile long encoderPos1 = 0; | |
28 | -double rpm1 = 0; | |
29 | -int calPWM1 = 0; | |
30 | -double error1 = 0, prevError1 = 0, integral1 = 0, derivative1 = 0; | |
31 | - | |
32 | -// 모터 2 | |
33 | -volatile long encoderPos2 = 0; | |
34 | -double rpm2 = 0; | |
35 | -int calPWM2 = 0; | |
36 | -double error2 = 0, prevError2 = 0, integral2 = 0, derivative2 = 0; | |
37 | - | |
38 | -// 제어 주기 | |
39 | -const unsigned long interval = 100; // 단위: ms | |
40 | -unsigned long prevTime = 0; | |
41 | -double dt = interval / 1000.0; // ms → 초(s) 단위로 변경 | |
42 | - | |
43 | -// === 인터럽트 핸들러 === | |
44 | -// 모터 1 | |
45 | -void doEncoderA1() { | |
46 | - if (digitalRead(ENCB_1) == LOW) encoderPos1++; | |
47 | - else encoderPos1--; | |
48 | -} | |
49 | -void doEncoderB1() { | |
50 | - if (digitalRead(ENCA_1) == HIGH) encoderPos1++; | |
51 | - else encoderPos1--; | |
52 | -} | |
53 | - | |
54 | -// 모터 2 | |
55 | -void doEncoderA2() { | |
56 | - if (digitalRead(ENCB_2) == LOW) encoderPos2--; | |
57 | - else encoderPos2++; | |
58 | -} | |
59 | -void doEncoderB2() { | |
60 | - if (digitalRead(ENCA_2) == HIGH) encoderPos2--; | |
61 | - else encoderPos2++; | |
62 | -} | |
63 | - | |
64 | -// === RPM 계산 함수 === | |
65 | -double calculateRPM(long counts) { | |
66 | - return ((double)counts / (4096.0 * 2)) * (60.0 / dt); | |
67 | -} | |
68 | - | |
69 | -// === PID 계산 함수 (모터별 계수 전달) === | |
70 | -int computePID(double currentRPM, double &error, double &prevError, | |
71 | - double &integral, double &derivative, int targetRPM, | |
72 | - double kp, double ki, double kd) { | |
73 | - error = targetRPM - currentRPM; | |
74 | - integral += (error * dt); | |
75 | - derivative = (error - prevError) / dt; | |
76 | - | |
77 | - double output = (kp * error) + (ki * integral) + (kd * derivative); | |
78 | - prevError = error; | |
79 | - return (int)output; | |
80 | -} | |
81 | - | |
82 | -// === 실시간 입력 (R숫자 L숫자 형식으로 입력, 음수 가능) === | |
83 | -void serialSetRPM() { | |
84 | - if (Serial.available()) { | |
85 | - String input = Serial.readStringUntil('\n'); | |
86 | - input.trim(); | |
87 | - | |
88 | - int rIndex = input.indexOf('R'); | |
89 | - int lIndex = input.indexOf('L'); | |
90 | - | |
91 | - if (rIndex == -1 && lIndex == -1) { | |
92 | - Serial.println("입력 오류: 'R' 또는 'L'이 포함되어야 합니다. 예: R100 L-80"); | |
93 | - return; | |
94 | - } | |
95 | - | |
96 | - bool validInput = false; | |
97 | - | |
98 | - // === R 처리 === | |
99 | - if (rIndex != -1) { | |
100 | - int end = (lIndex != -1 && lIndex > rIndex) ? lIndex : input.length(); | |
101 | - String rValStr = input.substring(rIndex + 1, end); | |
102 | - rValStr.trim(); | |
103 | - | |
104 | - if (rValStr.length() == 0) { | |
105 | - Serial.println("오류: R 뒤에 숫자가 없습니다. 예: R100"); | |
106 | - } else { | |
107 | - int rpmVal = rValStr.toInt(); | |
108 | - if (String(rpmVal) != rValStr) { | |
109 | - Serial.print("오류: R에 잘못된 숫자 형식 → "); Serial.println(rValStr); | |
110 | - } else if (abs(rpmVal) > 400) { | |
111 | - Serial.println("오류: R 값은 -400 ~ 400 사이여야 합니다."); | |
112 | - } else { | |
113 | - setRPM1 = rpmVal; | |
114 | - Serial.print("모터1 (R) 목표 RPM → "); Serial.println(setRPM1); | |
115 | - validInput = true; | |
116 | - } | |
117 | - } | |
118 | - } | |
119 | - | |
120 | - // === L 처리 === | |
121 | - if (lIndex != -1) { | |
122 | - int end = (rIndex != -1 && rIndex > lIndex) ? rIndex : input.length(); | |
123 | - String lValStr = input.substring(lIndex + 1, end); | |
124 | - lValStr.trim(); | |
125 | - | |
126 | - if (lValStr.length() == 0) { | |
127 | - Serial.println("오류: L 뒤에 숫자가 없습니다. 예: L-80"); | |
128 | - } else { | |
129 | - int rpmVal = lValStr.toInt(); | |
130 | - if (String(rpmVal) != lValStr) { | |
131 | - Serial.print("오류: L에 잘못된 숫자 형식 → "); Serial.println(lValStr); | |
132 | - } else if (abs(rpmVal) > 400) { | |
133 | - Serial.println("오류: L 값은 -400 ~ 400 사이여야 합니다."); | |
134 | - } else { | |
135 | - setRPM2 = rpmVal; | |
136 | - Serial.print("모터2 (L) 목표 RPM → "); Serial.println(setRPM2); | |
137 | - validInput = true; | |
138 | - } | |
139 | - } | |
140 | - } | |
141 | - | |
142 | - if (!validInput) { | |
143 | - Serial.println("R숫자 L숫자 형식으로 입력해주세요. 예: R100 L-80"); | |
144 | - } | |
145 | - } | |
146 | -} | |
147 | - | |
148 | - | |
149 | -void setup() { | |
150 | - Serial.begin(57600); | |
151 | - | |
152 | - // 모터 1 핀 설정 | |
153 | - pinMode(DIR_1, OUTPUT); pinMode(PWM_1, OUTPUT); pinMode(ST_1, OUTPUT); | |
154 | - pinMode(ENCA_1, INPUT_PULLUP); pinMode(ENCB_1, INPUT_PULLUP); | |
155 | - attachInterrupt(digitalPinToInterrupt(ENCA_1), doEncoderA1, RISING); | |
156 | - attachInterrupt(digitalPinToInterrupt(ENCB_1), doEncoderB1, RISING); | |
157 | - | |
158 | - // 모터 2 핀 설정 | |
159 | - pinMode(DIR_2, OUTPUT); pinMode(PWM_2, OUTPUT); pinMode(ST_2, OUTPUT); | |
160 | - pinMode(ENCA_2, INPUT_PULLUP); pinMode(ENCB_2, INPUT_PULLUP); | |
161 | - attachInterrupt(digitalPinToInterrupt(ENCA_2), doEncoderA2, RISING); | |
162 | - attachInterrupt(digitalPinToInterrupt(ENCB_2), doEncoderB2, RISING); | |
163 | - | |
164 | - // 브레이크 해제 | |
165 | - digitalWrite(ST_1, LOW); | |
166 | - digitalWrite(ST_2, LOW); | |
167 | - | |
168 | - prevTime = millis(); | |
169 | - | |
170 | - Serial.println("R±RPM | L±RPM 입력"); | |
171 | -} | |
172 | - | |
173 | -void loop() { | |
174 | - unsigned long now = millis(); | |
175 | - | |
176 | - if (now - prevTime >= interval) { | |
177 | - prevTime += interval; | |
178 | - | |
179 | - // 모터 1 | |
180 | - noInterrupts(); long currentPos1 = encoderPos1; encoderPos1 = 0; interrupts(); | |
181 | - rpm1 = calculateRPM(currentPos1); | |
182 | - calPWM1 = computePID(rpm1, error1, prevError1, integral1, derivative1, abs(setRPM1), kp1, ki1, kd1); | |
183 | - digitalWrite(DIR_1, setRPM1 >= 0 ? HIGH : LOW); | |
184 | - calPWM1 = constrain(abs(calPWM1), 0, 255); | |
185 | - analogWrite(PWM_1, calPWM1); | |
186 | - | |
187 | - // 모터 2 | |
188 | - noInterrupts(); long currentPos2 = encoderPos2; encoderPos2 = 0; interrupts(); | |
189 | - rpm2 = calculateRPM(currentPos2); | |
190 | - calPWM2 = computePID(rpm2, error2, prevError2, integral2, derivative2, abs(setRPM2), kp2, ki2, kd2); | |
191 | - digitalWrite(DIR_2, setRPM2 >= 0 ? HIGH : LOW); | |
192 | - calPWM2 = constrain(abs(calPWM2), 0, 255); | |
193 | - analogWrite(PWM_2, calPWM2); | |
194 | - | |
195 | - // 시리얼 출력 | |
196 | - // Serial.print("R:"); Serial.println(setRPM1); | |
197 | - // Serial.print("RPM:"); Serial.println(rpm1, 2); | |
198 | - // Serial.print("PWM:"); Serial.println(calPWM1); | |
199 | - // Serial.println(" "); | |
200 | - // Serial.print("L:"); Serial.println(setRPM2); | |
201 | - // Serial.print("RPM:"); Serial.println(rpm2, 2); | |
202 | - // Serial.print("PWM:"); Serial.println(calPWM2); | |
203 | - // Serial.println("--------------------"); | |
204 | - | |
205 | - // Serial Plotter용 출력 (탭으로 구분) | |
206 | - Serial.print(setRPM1); Serial.print('\t'); | |
207 | - Serial.println(rpm1, 2); | |
208 | - // Serial.print(setRPM2); Serial.print('\t'); | |
209 | - // Serial.println(rpm2, 2); | |
210 | - } | |
211 | - | |
212 | - serialSetRPM(); | |
213 | -} |
--- TEST
... | ... | @@ -1,75 +0,0 @@ |
1 | -//test motor with arduino, check hallsensor | |
2 | - | |
3 | -// test run motor with arduino | |
4 | - | |
5 | -const int PWM = 10; // MD200T 6번 (SPEED_IN2) 노랑 | |
6 | -const int DIR = 8; // MD200T 2번 (DIR2) 주황 | |
7 | -const int ST = 9; // MD200T 4번 (START/STOP2) 초록 | |
8 | - | |
9 | -void setup() { | |
10 | - Serial.begin(9600); | |
11 | - | |
12 | - pinMode(PWM, OUTPUT); | |
13 | - pinMode(DIR, OUTPUT); // 회전 방향 (시계 방향 = HIGH) | |
14 | - pinMode(ST, OUTPUT); // 브레이크 (해제 = LOW) | |
15 | - | |
16 | - digitalWrite(ST, HIGH); | |
17 | - delay(2000); // 전원 안정화 | |
18 | -} | |
19 | - | |
20 | -void loop() { | |
21 | - | |
22 | - digitalWrite(ST, LOW); // 브레이크 해제 | |
23 | - digitalWrite(DIR, LOW); // 반시계 회전 | |
24 | - analogWrite(PWM, 0); | |
25 | - // delay(10000); | |
26 | - // digitalWrite(ST, HIGH); // 멈춤 | |
27 | - // delay(4000); | |
28 | - | |
29 | - // digitalWrite(ST, LOW); | |
30 | - // digitalWrite(DIR, HIGH); // 시계 회전 | |
31 | - // analogWrite(PWM, 125); | |
32 | - // delay(10000); | |
33 | - // digitalWrite(ST, HIGH); | |
34 | - // delay(4000); | |
35 | -} | |
36 | - | |
37 | - | |
38 | -// check hallsensor | |
39 | - | |
40 | - | |
41 | -// 홀센서 핀 번호 | |
42 | -const int Hu = 4; | |
43 | -const int Hv = 3; | |
44 | -const int Hw = 2; | |
45 | - | |
46 | -const int PWM = 10; // MD200T 6번 (SPEED_IN2) 노랑 | |
47 | -const int DIR = 8; // MD200T 2번 (DIR2) 주황 | |
48 | -const int ST = 9; // MD200T 4번 (START/STOP2) 초록 | |
49 | - | |
50 | -void setup() { | |
51 | - Serial.begin(9600); | |
52 | - | |
53 | - pinMode(Hu, INPUT); | |
54 | - pinMode(Hv, INPUT); | |
55 | - pinMode(Hw, INPUT); | |
56 | - | |
57 | - pinMode(PWM, OUTPUT); | |
58 | - pinMode(DIR, OUTPUT); // 회전 방향 (시계 방향 = HIGH) | |
59 | - pinMode(ST, OUTPUT); | |
60 | - digitalWrite(ST, HIGH); // 브레이크 (해제 = LOW) | |
61 | - delay(2000); // 전원 안정화 | |
62 | -} | |
63 | - | |
64 | -//모터를 직접 손으로 돌리면서 체크 | |
65 | -void loop() { | |
66 | - int hu = digitalRead(Hu); | |
67 | - int hv = digitalRead(Hv); | |
68 | - int hw = digitalRead(Hw); | |
69 | - | |
70 | - Serial.print("Hu: "); Serial.print(hu); | |
71 | - Serial.print(" | Hv: "); Serial.print(hv); | |
72 | - Serial.print(" | Hw: "); Serial.println(hw); | |
73 | - | |
74 | - delay(200); // 0.2초 간격 출력 | |
75 | -}(파일 끝에 줄바꿈 문자 없음) |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?