Implement virtual Endstops with H-Bridge MC33887

Hey Guys,
I need your help.
I would like to run a DC motor with a MC33887 H bridge. Attached to the Motor is a 5K Poti, due to production tolerances and malefunction I have to "calibrate" the poti.

My idea is to drive the motor to one direction until the current increases to a threshold of something about 2A.
Then read the value of the poti and save this to the variabl pmin.
Change the direction of the motor and drive it to the upper level until the current goes over 2A. Save the poti value to pmax.

The MC33887 has a current feedback pin: "Current feedback output providing ground referenced1/375th ratio of H-bridge high-side current"

Can somebody please help me with the code to do this in the right way?

Thanks in advance!

not to clear on your requirements but maybe something like this as a starter:

//define digital output pins
#define EN 4
#define IN1 5
#define IN2 6
#define D1 7
#define D2 8

//define Analog Input pins
#define FB A0
#define POT A1

#define Current_Ratio 0.123 //needs to be updated to correct value e.g for 1A current what is the ADC value read?

void setup() {

  Serial.begin(115200);

  pinMode(EN, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);

  digitalWrite(EN, LOW); //Output State: Hi-Z
}

void loop() {
float current;

  digitalWrite(EN, HIGH);

  //Forward movement. Invert the HIGH and LOW for reverse direction
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);

  Serial.print("Current Draw (A): ");

  current = (analogRead(FB) * Current_Ratio) * 375; //375 as per current feedback spec (could be calculated into Current_ratio! :) )

  Serial.println(current, 2);

}

Rado1512:
Attached to the Motor is a 5K Poti,

Please post a link to the datasheet for the motor.

Do you mean that the potentiometer shaft is attached to the motor shaft?

...R

Thanks for the fast reply!
Acctualy there is no Datasheet for the motor, it is a 12V dc Motor which drives a powervalve of a one cylinder two stroke engine.
The poti is not directly attached to the motor shaft, it is part of the gearing and directly attached to the shaft of the last gear. I can post a picture after work.

does this make any sens?

//define digital output pins
#define EN 4
#define IN1 5
#define IN2 6
#define D1 7
#define D2 8

//define Analog Input pins
#define FB A0
#define POT A1

#define Current_Ratio 0.123 //needs to be updated to correct value e.g for 1A current what is the ADC value read?

int pmin = 0;
int pmax = 0;
int flag = 0;


void setup() {
  pinMode(EN, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);

  digitalWrite(EN, LOW); //Output State: Hi-Z
}

void loop() {
float current;

  
  //Forward movement. Invert the HIGH and LOW for reverse direction
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(EN, HIGH);
  current = (analogRead(FB) * Current_Ratio) * 375; //375 as per current feedback spec (could be calculated into Current_ratio! :) )
  
  if (current >= 2) {
	  digitalWrite(EN, LOW);
	  pmin = analogRead(POT);
    }
  
  while ( pmin != 0 && flag == 0) {
		digitalWrite(IN1, LOW);
		digitalWrite(IN2, HIGH);
		digitalWrite(EN, HIGH);
  		current = (analogRead(FB) * Current_Ratio) * 375;
  
		if (current >= 2) {
			digitalWrite(EN, LOW);
			pmax = analogRead(POT);
			flag = 1;
		}
    }
}

Rado1512:
does this make any sens?

//define digital output pins

#define EN 4
#define IN1 5
#define IN2 6
#define D1 7
#define D2 8

//define Analog Input pins
#define FB A0
#define POT A1

#define Current_Ratio 0.123 //needs to be updated to correct value e.g for 1A current what is the ADC value read?

int pmin = 0;
int pmax = 0;
int flag = 0;

void setup() {
  pinMode(EN, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);

digitalWrite(EN, LOW); //Output State: Hi-Z
}

void loop() {
float current;

//Forward movement. Invert the HIGH and LOW for reverse direction
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(EN, HIGH);
  current = (analogRead(FB) * Current_Ratio) * 375; //375 as per current feedback spec (could be calculated into Current_ratio! :slight_smile: )
 
  if (current >= 2) {
  digitalWrite(EN, LOW);
  pmin = analogRead(POT);
    }
 
  while ( pmin != 0 && flag == 0) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(EN, HIGH);
  current = (analogRead(FB) * Current_Ratio) * 375;
 
if (current >= 2) {
digitalWrite(EN, LOW);
pmax = analogRead(POT);
flag = 1;
}
    }
}

Makes sense to me from what you described in your first post. but I cannot say for 100%! :slight_smile:

I guess you should give it a go to find out BUT...

before that you need to find out/Calculate the CORRECT value of "Current_Ratio" and I would suggest that you initially print out the calculated current to serial monitor to see if that reasonably matches the ACTUAL current value (which I hope you have a multimeter to be able to read that out!)

Good luck! :wink:

Rado1512:
The poti is not directly attached to the motor shaft, it is part of the gearing and directly attached to the shaft of the last gear.

That sounds like how a hobby servo works. In a hobby servo the potentiometer is used to provide feedback for the angular position of the servo arm.

If that is the case does this statement from your Original Post

My idea is to drive the motor to one direction until the current increases to a threshold of something about 2A.
Then read the value of the poti and save this to the variabl pmin.

mean that you want to drive the motor until it exerts a certain force (using the 2 amp current as a proxy for the force) and then record the angle of the shaft at which that occurs using the potentiometer.

I can envisage how you could write a program to do that but I have my doubts as to whether future moves to the same potentiometer setting would reliably give you the same force. Why not just base all your actions on the motor load current?

…R

Actually it is a Servo Motor. I would Like to find the mecanical endstop and make sure the motor stall.
I look for the stalling in two positions, opened and closed and I do this everytime the ignition is turned on. So for one ride the values won't shift, I think.
My second guess is that I can check the system with that prosedure. If pmin and pmax are to close together the powevalve is stuck.

Looking back to Reply #4, I wouldn't bother with this complexity

current = (analogRead(FB) * Current_Ratio) * 375;
if (current >= 2) {

I would just do some tests to find the value from analogRead() that corresponds to 2 amps and use that directly

analogReadCurrentVal = analaogRead(FB);
if (analogReadCurrentVal >= xxxx) {

...R