Dc Motor With Pot Always Chasing Center Position (HOME)

Hello all. I am new to arduino. Looking forward to do some auto-self calibration for my program upon starting,or when there are at the beginning of the program starts. I am connecting a wiper motor shaft to a potentiometer, and read it's value to determine it's location.
My first question, how to do the self calibration upon start up, do I need to put the code inside the void Setup() function or it doesn't matter?
Secondly, how may I instruct the motor to chase it's home(center location) always, either when no input were taken or when a switch has just been released?

Here is my current method, the motor is moving and try to stop at center (I called it home). For the center(home) I maybe need more brilliant suggestion from you guys. I may draw a diagram if needed, please let me know.

int speedA = 95;
int positionPin = A0;
int switchA = 7; // pin 7 connected to a switch pin
int current_Location ;
int actual_Location;
//int new_init_Location;
int max_Location = 60;
int min_Location = 40;
int init_Location  = 50;
int max_Limit = 5;
int min_Limit = 5;

int LPWM_A_State ;
int RPWM_A_State;

//define pin connected to motor
int LPWM_A = 6;
int RPWM_A = 5;

void setup() {
	// define pinmode for motor pins
		pinMode(LPWM_A,OUTPUT);
		pinMode(RPWM_A,OUTPUT);
        pinMode(switchA,INPUT);
	}

void read()
{
      actual_Location = analogRead(positionPin);
      current_Location= map(actual_Location,0,1023,0,100);

// No button were pressed
   if (digitalRead(switchA) == LOW) 
   {
     analogWrite(LPWM_A,0);
     analogWrite(RPWM_A,0);
   }

// button A pressed
   if (digitalRead(switchA) == HIGH) 
   {
     analogWrite(LPWM_A,90); // move motor forward
     analogWrite(RPWM_A,0);
     LPWM_A_State = 1;
     RPWM_A_State = 0;
    }
// button has been released 
   if (digitalWrite(switchA) == LOW &&  LPWM_A_State ==1 && RPWM_A_State == 0 ) 
   {
   analogWrite(LPWM_A,0);
   analogWrite(RPWM_A,90); //reverse the motor backward
   LPWM_A_State = 0;
   RPWM_A_State = 1;
   }

// the motor is reversing after switch has been released, and need to stop at center. Looking for better idea, need improvements/suggestion.
   if(LPWM_A_State == 0 && RPWM_A_State == 1 && current_Location == init_Location) 
   {
    analogWrite(LPWM_A,0); // stop motor.
    analogWrite(RPWM_A,0);
    LPWM_A_State = 2;
    RPWM_A_State = 2;
   }
}

The code has more, TBH, I am also using a function for the motor move forward,reverse or stop.Current code is working, but without self-calibration. Thus, I'm looking forward for any ideas regarding self-calibration upon start up , and chasing back the motor to it's center location upon releasing switch/ no input received.

Thank you in advance.

Please take a few moments to explain what that means.

The basic mechanism you are making (motor shaft attached to a position potentiometer) is used in almost all hobby servos. There are many explanations on line describing how those work.

Why not just use a servo?

Pots dither and so do ADC's one read to the next.

Use a dead zone, make no moves < 3 and if that works try < 2, widen as needed.

Hi jremington, thanks for your respond. What I mean is whenever the program starts, if it's current location > init_Location, reverse the motor to it's center, and if the current location <init_location, move motor forward to the center as I want it to be in it's 'Home' position. And then, starts it's normal program to read the input.

I am working on a simple motion sim project. Right now I only have a spare wiper motor at home, so kind of thinking reusing it back for this purpose. Furthermore, it got some torque to lift my weight at a certain pivot, that's why I am using the cheap wiper motor at the moment.
BTW, thanks for the suggestions.

If you use PID motor control, then position seeking is completely automatic. Check out the Arduino PID library, and experiment with the examples.

Your startup code should present the analog read value corresponding to the neutral position directly to the motor position control function.

Wow, so PID is what I should've look into afterwards. Been eading a few post about using PIDs, and it's library. However it is still beyond my knowledge. But I can consider focusing on that now since that most likely will get my goal accomplished. Do I need to get extra hardware for the PID, or I can simply use it with by only including the library in the sketch?

PID is pretty easy to use, and there are many good tutorials on the web.

Here is one. Also read the Arduino PID library documentation carefully.

And another:

The only complication is choosing the values of Kp, Ki, and Kd, called "PID tuning". There are many tutorials on that as well.

Yes, it's true. The reading from the pot distorted a lot, I've tried to use deadzones as far as 5-10 sometimes. It does it's job in most of the cases. Do you have any suggestion for the calibrarions, on how to make the motor center whenever the program starts?
Thank you for your time.

No. The pot is the feedback to the PID algorithm.

1 Like

Get a better pot or go for optical or other sensing. I go back to joysticks in my online gaming days and forum discussions on hardware in sticks and IO cards pre-USB. I had an optically encoded stick that never dithered but did go winblows obsolete.

There is a lot of material out there, the Arduino Playground should be a ton of help.

By reading this post, it's become a little bit clearer on how the PID works. As my understanding, when we set the Setpoint of the PID is set to let say 100, and when compute finish, when I use the analogWrite(PIN_OUTPUT, Output_A) in the loop function, does it mean that the speed of my motor will be equal to Output_A, and the motor will be stop when the Pot reading reached the SetPoint = 100?

PID estimates the motor speed command from the difference between the current position and the setpoint position, and optionally using two other factors (I and D).

If you use "P-only" then the motor speed will be set to zero if the current position is equal to the setpoint position.

That is not necessarily the case if you use the I and D options.

Now there's a light at the end of the tunnel. Got clearer by your explanation. Thanks for your precious time.

Since I am using a single motor, and I have to control both forward and reverse direction accordingly, do I need to use 2 PID as one for DIRECT, and another is for REVERSE? Therefore if I got 2 motor that will drive both directions, do I need to set up to 4 PIDs, each for their own directions?

A single instance of PID commands speed in both directions.

You forgot to mention anything about how the motor is actually controlled, so please post a circuit diagram (hand drawn is best) and links to modules, like motor controllers, and to the motor power supply.

That's a very cool place to play around. Amazing links, thanks for sharing this. Might took a while to find what I am looking for. As I expect you will be more expert on integrating games with arduino, there should be a lot of fun over there.

If you have a constantly running feedback loop (which is what I believe you are doing), you don't have to make the motor do anything. The feedback loop will detect a difference between the pot position and the setpoint, then engage the motor until they are almost the same. Even a simple bang bang feedback loop will do that, as well as a PID. PID is just a "fancy" feedback loop.

So to make the motor center at the start, all you have to do is change the setpoint to the center position.

1 Like

The motor will be intentionally be instruct by a serial signal, but for this question I made it simpler by replacing the serial command with a switch, which is it's GND pin were attached to the Pin 7, and have a resistor connected in parallel to the same Pin 7. The other pin of the switch were attached to the 5v of the arduino.

Here is my hand drawn ,but I forgot to include the switch, which I've explained above. The middle pin of the Pot were connected to A0 on the arduino, outer pins to 5v and GND.

That's kinda cool. Exactly as what I am looking for. So it doesn't matter if I am not using a servo, this PID method able to drive the arm connected to the motor shaft, let say from 0 to 90, with a setpoint = 45? Eventhough it is just a dc/wiper motor with a cheap pot attached?

The image here is to illustrate more.
Thanks.

It appears from the first posted program that the LPWM and RPWM control the motor speed in forward and reverse directions.

Depending on the sign of the output from the PID controller (PID_output), choose the correct one, with speed = abs(PID_output). That is, make PID_output positive, if it happens to be negative.

You have to make sure that the PWM speed command is on the proper scale (0 to 255). The PID controller does not know how to do that, so most people use the Arduino function contrain() to make sure the analogWrite() value is confined to those limits.

That is correct, as the method I am using drives the motor forward when

(LPWM == HIGH && RPWM ==LOW); // forward .
(RPWM == HIGH && LPWM ==LOW); // reverse .

I might have to come up with a new sketch later on or tomorrow, when integrating PID with my current sketch has been done. Will let you guys know if I stuck somewhere. Thanks for your kind help. Very much appreciated.