DC motor position control with potentiometer
Dependents: Ackermann steering baseControl_ackermannCar
LamborSteer.cpp
- Committer:
- worasuchad
- Date:
- 2018-11-07
- Revision:
- 0:b20808175db0
File content as of revision 0:b20808175db0:
#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; }