Professional Documents
Culture Documents
Balance an inverted pendulum with a DC motor
Balance an inverted pendulum with a DC motor
#include <Arduino.h>
#define PWM_PIN 10
#define DIR_PIN 8
#define A 35.98
#define B 2.22
#define C 2.79
void encoderHandler();
void refEncoderHandler();
void setup() {
pinMode(OUTPUT_A, INPUT_PULLUP);
pinMode(OUTPUT_B, INPUT_PULLUP);
pinMode(REF_OUT_A, INPUT_PULLUP);
pinMode(REF_OUT_B, INPUT_PULLUP);
pinMode(PWM_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
digitalWrite(DIR_PIN, LOW);
Serial.begin(9600);
lastTimeMicros = 0L;
}
void driveMotor(float u) {
digitalWrite(DIR_PIN, u > 0.0 ? LOW : HIGH);
analogWrite(PWM_PIN, fabs(u));
}
if (log_prescaler % 20 == 0) {
Serial.print(theta, 4);Serial.print("\ ");
Serial.print(w, 4);Serial.print("\ ");
Serial.print(x, 4);Serial.print("\ ");
Serial.print(v, 4);Serial.print("\ ");
Serial.print(control, 4);Serial.print("\ ");
Serial.println(u, 4);
}
log_prescaler++;
}
void loop() {
now = micros();
dt = 1.0 * (now - lastTimeMicros) / 1000000;
x = getCartDistance(encoderValue, PPR);
v = (x - last_x) / dt;
last_x = x;
last_theta = theta;
lastTimeMicros = now;
log_state(control, u);
delay(5);
}
/**
* Motor encoder handler
*/
void encoderHandler() {
int MSB = (PINE & (1 << PE5)) >> PE5; //MSB = most significant bit
int LSB = (PINE & (1 << PE4)) >> PE4; //LSB = least significant bit
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded
value
/**
* Pendulum encoder handler
* Encoder attached to pins:
* Phase A - 18 PD3
* Phase B - 19 PD2
*/
void refEncoderHandler() {
int MSB = (PIND & (1 << PD3)) >> PD3; //MSB = most significant bit
int LSB = (PIND & (1 << PD2)) >> PD2; //LSB = least significant bit
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
int sum = (lastRefEncoded << 2) | encoded; //adding it to the previous encoded
value