Day 7: (Wed Sep 18) DC Motors and Mechanical Structures¶
Notes for 2019-09-18. See also the Fall 2019 Calendar.
Agenda¶
Assignments
Due Mon Sep 23: Demo 3: The Conversation.
Due Mon Sep 23: read
Investigating Rocks and Sand
In-class
demo3 sample from F18: A Man’s Best Friend
questions about demo3?
mechanical component show and tell
discussion of joinery and bearings
DC motor and hub distribution
discussion of DRV8833 dual H-bridge
see Figure 6
sample code (below)
Brief pair meetings.
Lecture code samples¶
(See also Lecture Sample Code).
feedback.ino
:
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 | // 1. apply proportional feedback using a dual H-bridge driver and analog position sensor
// 2. demonstrate non-blocking event-loop structure
// 3. demonstrate DRV8833 motor driver pulse width modulation
// 4. demonstrate a smoothing filter on an analog input
// Define DRV8833 control pin wiring as per CKS-1 shield board.
const int MOT_A1_PIN = 5;
const int MOT_A2_PIN = 6;
const int MOT_B1_PIN = 10;
const int MOT_B2_PIN = 9;
const int POS_SENSOR_PIN = A0;
/****************************************************************/
void setup(void)
{
// Configure the four DRV8833 control lines and set them to a quiescent state.
pinMode(MOT_A1_PIN, OUTPUT);
pinMode(MOT_A2_PIN, OUTPUT);
pinMode(MOT_B1_PIN, OUTPUT);
pinMode(MOT_B2_PIN, OUTPUT);
digitalWrite(MOT_A1_PIN, LOW);
digitalWrite(MOT_A2_PIN, LOW);
digitalWrite(MOT_B1_PIN, LOW);
digitalWrite(MOT_B2_PIN, LOW);
// Start the serial port for the console.
Serial.begin(115200);
}
/****************************************************************/
void loop(void)
{
static unsigned long last_update_clock = 0;
unsigned long now = micros();
unsigned long interval = now - last_update_clock;
last_update_clock = now;
poll_feedback_loop(interval);
}
/****************************************************************/
// Polling function for the feedback process: reads an analog position sensor at
// regular sampling intervals, calculates a new motor speed and configures the
// DRV8833 motor driver PWM outputs.
const long sample_interval = 10000; // 10 msec, 100 Hz sampling
long sample_timer = 0;
float position = 0.0; // filtered value of the input (unit normalization)
float target = 0.5; // target position (unit normalization)
void poll_feedback_loop(unsigned long interval)
{
sample_timer -= interval;
if (sample_timer <= 0) {
sample_timer += sample_interval;
int raw_value = analogRead(POS_SENSOR_PIN); // read the current input
float calibrated = ((float)raw_value) / 1024.0; // scale to normalized units
// first-order smoothing filter to reduce noise in the position estimate
float difference = calibrated - position; // compute the 'error' in the sensor reading
position += 0.2 * difference; // apply a constant gain to move the smoothed value toward the reading
// calculate a proportional position control update
float position_error = target - position; // compute the position error
float control_output = 2.0 * position_error; // apply a proportional position gain
int control_pwm = constrain((int)(256.0 * control_output), -255, 255);
set_motor_pwm(control_pwm, MOT_A1_PIN, MOT_A2_PIN);
}
}
/****************************************************************/
// Set the current speed and direction for either of the DRV8833 channels.
//
// Parameters:
// pwm : integer velocity ranging from -255 to 255.
// IN1_PIN : either MOT_A1_PIN or MOT_B1_PIN
// IN2_PIN : either MOT_A2_PIN or MOT_B2_PIN
//
// (Note: uses 'fast-decay' mode: coast not brake.)
void set_motor_pwm(int pwm, int IN1_PIN, int IN2_PIN)
{
if (pwm < 0) { // reverse speeds
analogWrite(IN1_PIN, -pwm);
digitalWrite(IN2_PIN, LOW);
} else { // stop or forward
digitalWrite(IN1_PIN, LOW);
analogWrite(IN2_PIN, pwm);
}
}
/****************************************************************/
|