DC motor position control with potentiometer
Dependents: Ackermann steering baseControl_ackermannCar
Revision 0:b20808175db0, committed 2018-11-07
- Comitter:
- worasuchad
- Date:
- Wed Nov 07 16:51:16 2018 +0000
- Commit message:
- DC motor position control with potentiometer
Changed in this revision
LamborSteer.cpp | Show annotated file Show diff for this revision Revisions of this file |
LamborSteer.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r b20808175db0 LamborSteer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LamborSteer.cpp Wed Nov 07 16:51:16 2018 +0000 @@ -0,0 +1,183 @@ +#include "LamborSteer.h" +#include "mbed.h" + +LamborSteer::LamborSteer(PinName _cw_pin, PinName _ccw_pin, PinName _enablerPin, PinName _sensor_pin, int _offset) +: cw_pin(_cw_pin), ccw_pin(_ccw_pin), enabler_pin(_enablerPin), sensor_pin(_sensor_pin) +{ + if (s_index == MAX_SERVOS) + { + return; + } + + index = s_index; + + _m_servos[s_index++] = this; + + tolerance = 15; + + /* New */ + offset = _offset; + active = true; + + cw_pin = 0; + ccw_pin = 0; +} + +// timer interrupt routine +void LamborSteer::timer_int_routine() +{ + for (int i = 0; i < s_index; i++) + { + if (_m_servos[i]->active) + { + _m_servos[i]->update(); + } + } +} + + +void LamborSteer::detach() +{ + stop(); + + active = false; +} + +void LamborSteer::write(int degrees) +{ + // map degrees to potentiometer value + int pot_value = map(degrees, MIN_ANGLE, MAX_ANGLE, MIN_POT_VALUE, MAX_POT_VALUE); + + write_pot_value(pot_value); +} + +void LamborSteer::update() +{ + int current_position = get_position(); + + // Guard servo's min and max bounds + if (current_position < MIN_POT_VALUE) + { + write(MIN_ANGLE); + } + + if (current_position > MAX_POT_VALUE) + { + write(MAX_ANGLE); + } + + // Gap between curent and wanted positions + int gap = abs(current_position - wanted_position); + + // If gap is within tolerance then stop + if (gap < tolerance) + { + stop(); + + return; + } + + // set speed according to gap remaining + speed = 100; //125 + + if (gap > 50) + { + speed = 100; //165 + } + if (gap > 75) + { + speed = 100; //205 + } + if (gap > 100) + { + speed = 100; //255 + } + + // Determine direction + if (current_position < wanted_position) + { + run_cw(); + } + + if (current_position > wanted_position) + { + run_ccw(); + } +} + +servo_status LamborSteer::read() +{ + // Get current postion, wanted position and speed + servo_status current_status; + + int current_angle = map(get_position(), MIN_POT_VALUE, MAX_POT_VALUE, MIN_ANGLE, MAX_ANGLE); + int wanted_angle = map(wanted_position, MIN_POT_VALUE, MAX_POT_VALUE, MIN_ANGLE, MAX_ANGLE); + + current_status.current_angle = current_angle; + current_status.wanted_angle = wanted_angle; + current_status.speed = speed; + + return current_status; +} + +/*************** Private stuff **************/ + +void LamborSteer::write_pot_value(int value) +{ + // Constrain value to servo's min and max bounds + //int constrained_value = constrain(value, MIN_POT_VALUE + tolerance, MAX_POT_VALUE - tolerance); + if(value > MAX_POT_VALUE - tolerance) + { + constrained_value = MAX_POT_VALUE - tolerance; + } + else if(value < MIN_POT_VALUE + tolerance) + { + constrained_value = MIN_POT_VALUE + tolerance; + } + else + { + constrained_value = value; + } + // set destination + wanted_position = constrained_value; +} + +// Run motor clockwise at current speed +void LamborSteer::run_cw() +{ + cw_pin = 1; + ccw_pin = 0; + + enabler_pin.write(speed / 255.0f); +} + +// Run motor counter clockwise at current speed +void LamborSteer::run_ccw() +{ + cw_pin = 0; + ccw_pin = 1; + + enabler_pin.write(speed / 255.0f); +} + +// Stop the motor, set speed to 0 +void LamborSteer::stop() +{ + cw_pin = 0; + ccw_pin = 0; + + enabler_pin.write(0); +} + +// Get current offset potentiometer position +int LamborSteer::get_position() +{ + return (sensor_pin.read()*1023) + offset; // Read the analog input value (value from 0.0 to 1.0) + // And convert to 0 - 1023 +} + +// Mapping +long LamborSteer::map(long x, long in_min, long in_max, long out_min, long out_max) +{ + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} \ No newline at end of file
diff -r 000000000000 -r b20808175db0 LamborSteer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LamborSteer.h Wed Nov 07 16:51:16 2018 +0000 @@ -0,0 +1,54 @@ +#ifndef LAMBORSTEER_H +#define LAMBORSTEER_H + +#include "mbed.h" + +#define MAX_SERVOS 2 +#define MIN_POT_VALUE 10 +#define MAX_POT_VALUE 1000 // 800 +#define MIN_ANGLE 10 +#define MAX_ANGLE 400 // 170 + +typedef unsigned char uint8_t; + +typedef struct { + int wanted_angle; + int current_angle; + uint8_t speed; +} servo_status; + +class LamborSteer +{ +public: + LamborSteer(PinName _cw_pin, PinName _ccw_pin, PinName _enablerPin, PinName _sensor_pin, int _offset); + //void attach(); + void timer_int_routine(); + void detach(); + void write(int degrees); + void update(); + servo_status read(); + + bool active; + int index; +private: + int offset; + uint8_t speed; + int wanted_position; + int tolerance; + int constrained_value; + + void write_pot_value(int degrees); + void run_cw(); + void run_ccw(); + void stop(); + int get_position(); + long map(long x, long in_min, long in_max, long out_min, long out_max); + DigitalOut cw_pin; + DigitalOut ccw_pin; + PwmOut enabler_pin; + AnalogIn sensor_pin; +}; + +static int s_index; // number of registered servo's +static LamborSteer* _m_servos[2]; // array containing registered servo's +#endif