Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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