From 5ce9b87315444ad6988eb1099a9af8f19e5a2b27 Mon Sep 17 00:00:00 2001 From: unlockable Date: Thu, 6 Jul 2023 23:40:30 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E5=96=BD=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Homework/Homework5/Encoder/Encoder.ino | 30 +++-- Homework/Homework5/Homework5/Homework5.ino | 129 +++++++++++++++++++++ 2 files changed, 149 insertions(+), 10 deletions(-) create mode 100644 Homework/Homework5/Homework5/Homework5.ino diff --git a/Homework/Homework5/Encoder/Encoder.ino b/Homework/Homework5/Encoder/Encoder.ino index 5d180d0..4afca4c 100644 --- a/Homework/Homework5/Encoder/Encoder.ino +++ b/Homework/Homework5/Encoder/Encoder.ino @@ -14,10 +14,13 @@ int current_rpm = 0; double output_level = 0; double err = 0, diff_err = 0, accumulate_err = 0; -const double Kp = 0.4, Ki = 0, Kd = 0.5; -const int goal_rpm = 100; +const double Kp = 0.6, Ki = 0.15, Kd = 0.1; +int goal_rpm = 100; void setup() { + count = 0; + current_rpm = 0; + output_level = 0; pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(ENABLE, OUTPUT); @@ -45,13 +48,18 @@ void loop() { // break; // } // } + // Serial.print(goal_rpm); + goal_rpm = 100; + // delay(3000); + // Serial.print(goal_rpm); + // goal_rpm = 150; + // delay(3000); } void resetCountAndPrint() { - current_rpm = (double)count * 60 * 1000 * 1000 / RESET_COUNT_PERIOD_IN_US / - REDUCTION_RATIO / EDGES_PER_CYCLE / 4; + current_rpm = (double)count * 60 * 1000 * 1000 / RESET_COUNT_PERIOD_IN_US / REDUCTION_RATIO / EDGES_PER_CYCLE / 4; count = 0; - output_level += calculatePID(); + output_level = calculatePID(); if (output_level > 255) { output_level = 255; } else if (output_level < -255) { @@ -62,17 +70,19 @@ void resetCountAndPrint() { digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); analogWrite(ENABLE, -output_level); - } - else { + } else { digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); analogWrite(ENABLE, output_level); } - Serial.print("goal:"); + // Serial.print("goal:"); + Serial.print('$'); Serial.print(goal_rpm); - Serial.print(" rpm:"); - Serial.println(current_rpm); + // Serial.print(" rpm:"); + Serial.print(", "); + Serial.print(current_rpm); + Serial.println(";"); } double calculatePID() { diff --git a/Homework/Homework5/Homework5/Homework5.ino b/Homework/Homework5/Homework5/Homework5.ino new file mode 100644 index 0000000..4afca4c --- /dev/null +++ b/Homework/Homework5/Homework5/Homework5.ino @@ -0,0 +1,129 @@ +#include + +const byte IN1 = 10; +const byte IN2 = 11; +const byte ENABLE = 6; +const byte ENCO_B = 3; +const byte ENCO_A = 2; + +const unsigned long RESET_COUNT_PERIOD_IN_US = 50000; +const int EDGES_PER_CYCLE = 13; +const int REDUCTION_RATIO = 20; +int count = 0; +int current_rpm = 0; +double output_level = 0; + +double err = 0, diff_err = 0, accumulate_err = 0; +const double Kp = 0.6, Ki = 0.15, Kd = 0.1; +int goal_rpm = 100; + +void setup() { + count = 0; + current_rpm = 0; + output_level = 0; + pinMode(IN1, OUTPUT); + pinMode(IN2, OUTPUT); + pinMode(ENABLE, OUTPUT); + digitalWrite(IN1, HIGH); + digitalWrite(IN2, LOW); + pinMode(ENCO_B, INPUT); + pinMode(ENCO_A, INPUT); + Serial.begin(9600); + Timer1.initialize(); + Timer1.setPeriod(RESET_COUNT_PERIOD_IN_US); + Timer1.attachInterrupt(resetCountAndPrint); + attachInterrupt(digitalPinToInterrupt(ENCO_A), onEncoAChange, CHANGE); + attachInterrupt(digitalPinToInterrupt(ENCO_B), onEncoBChange, CHANGE); + analogWrite(ENABLE, output_level); +} + +void loop() { + // if (Serial.available()) { + // switch (Serial.read()) { + // case 's': + // analogWrite(ENABLE, 50); + // break; + // case 'p': + // analogWrite(ENABLE, 0); + // break; + // } + // } + // Serial.print(goal_rpm); + goal_rpm = 100; + // delay(3000); + // Serial.print(goal_rpm); + // goal_rpm = 150; + // delay(3000); +} + +void resetCountAndPrint() { + current_rpm = (double)count * 60 * 1000 * 1000 / RESET_COUNT_PERIOD_IN_US / REDUCTION_RATIO / EDGES_PER_CYCLE / 4; + count = 0; + output_level = calculatePID(); + if (output_level > 255) { + output_level = 255; + } else if (output_level < -255) { + output_level = -255; + } + + if (output_level < 0) { + digitalWrite(IN1, LOW); + digitalWrite(IN2, HIGH); + analogWrite(ENABLE, -output_level); + } else { + digitalWrite(IN1, HIGH); + digitalWrite(IN2, LOW); + analogWrite(ENABLE, output_level); + } + + // Serial.print("goal:"); + Serial.print('$'); + Serial.print(goal_rpm); + // Serial.print(" rpm:"); + Serial.print(", "); + Serial.print(current_rpm); + Serial.println(";"); +} + +double calculatePID() { + diff_err = goal_rpm - current_rpm - err; + err = goal_rpm - current_rpm; + accumulate_err += err; + return Kp * err + Ki * accumulate_err + Kd * diff_err; +} + +void onEncoAChange() { + if (LOW == digitalRead(ENCO_A)) { + if (LOW == digitalRead(ENCO_B)) { + count--; + } + if (HIGH == digitalRead(ENCO_B)) { + count++; + } + } else { + if (HIGH == digitalRead(ENCO_B)) { + count--; + } + if (LOW == digitalRead(ENCO_B)) { + count++; + } + } +} + +void onEncoBChange() { + if (LOW == digitalRead(ENCO_B)) { + if (HIGH == digitalRead(ENCO_A)) { + count--; + } + if (LOW == digitalRead(ENCO_A)) { + count++; + } + } else { + if (LOW == digitalRead(ENCO_A)) { + count--; + } + if (HIGH == digitalRead(ENCO_A)) { + count++; + } + } +} \ No newline at end of file