Hall Effects Sensor with DC Motor - Used as Encoder

Hello everyone, I am using a 4 hall effects sensors to measure the speed of 2 motors (2 sensors per motor). I am new to the whole idea of encoders, so I am lost. I know the motor pins (figure 1) , but I am blurry on how to connect it to an arduino mega (the board I am using) and what the code is like. . .

Figure 1:

I would really appreciate some help. Thanks.

Sorry about the image, here it is.

Figure 10

Sorry---again

I'm sure the data sheet of your motor will have instructions. Look for it.

Based on your limited info: I see wires for TWO Hall sensors, not one.

Such a sensor will typically output a roughly 50% duty cycle pulse signal, one complete pulse (high + low) is probably two complete rotations as the sensor switches upon a magnet passing (in one specific direction normally which make the second point interesting:)

Two sensors would allow for a quadrature type encoder, indicating direction. Or maybe it's one sensor that produces the pulses for one direction, and the other sensor for the other.

OK so now go and find the data sheet of that motor, and I'm curious to know how my guesses measure up against reality.

Or just connect an Arduino or scope or voltmeter and start looking at pulses of the two sensors.

Wrong989:
Sorry---again

That's ok. Be sure that you're absolutely sure that the given wiring diagram is correct. What I mean is .... I've seen some of these online photos where they show (such as in the picture you provided) labels for the various wires, but the labels were incorrect.

Eg...... the following link here .... incorrect... https://www.openimpulse.com/blog/wp-content/uploads/wpsc/downloadables/JGA25-371-technical-drawing-21.jpg

This one.... correct... https://sc01.alicdn.com/kf/HTB1e6dRGpXXXXctaXXXq6xXFXXX3/200666655/HTB1e6dRGpXXXXctaXXXq6xXFXXX3.jpg

The above are links associated with JGA25-371

Now..... for your motor, not sure what kind it is. But since you got the diagram, then we can only assume the wiring is correct for now.

What you need to do now is to get some details about what supply voltage this hall sensor can handle....eg 5V DC?

Thank you for a quick reply.

wvmarle:

I clearly noted:

Wrong989:
4 hall effects sensors to measure the speed of 2 motors (2 sensors per motor).

And the datasheet only includes info for the motor NOT the sensor, but thanks for the advice.

Southpark:

I'm sure it's correct but thanks for asking. The hall effects sensor is meant for use with arduino, so I know it is 5V-it's not 3.3V or other voltage.

Thank you for understanding that I am new to this subject. :slight_smile:

Wrong989:
And the datasheet only includes info for the motor NOT the sensor, but thanks for the advice.

You just showed an image of one motor. I was looking at that one motor. You anyway have to try and get one motor working first, before worrying about the rest.

Also do find the data sheet, and post it here. It must have info on the sensors (including the power requirements and the expected output). Without that info, it's a matter of trying and hoping for the best.

The hall effects sensor is meant for use with arduino, so I know it is 5V-it's not 3.3V or other voltage.

That's a very dangerous assumption.

Not only are there 3.3V Arduinos around (the processor itself can work with less than 2V), there are sensors that are commonly used with Arduinos which would be very dead very fast if connected to 5V. The opposite is also true: many 5V sensors can also work with 3.3V.

Hi,
Can you tell us the part number/manufacturer/supplier of the motor please.
A link to the purchase site or the data/spec sheet would be of help.

What are you using to control the motors, that the Mega is controlling?

Thanks.. Tom... :slight_smile:

wvmarle:

Data Sheet only has info on motors, NOT sensor, anyway here it is:

TomGeorge:

L298N controls motor speed.
See data sheet for more info.

DataSheetforGearMotor.pdf (141 KB)

That data sheet is indeed of the motor only.

I can't help to notice that the image you posted before has a black box with a bunch of wires on the bottom of the motor, that's absent in the data sheet's image. That's apparently a separate part holding the encoder, and you'll have to hunt down the data sheet of that. It does look well integrated so I wouldn't be surprised if it's also built by the motor's manufacturer.

Hi,
Image from Aliexpress site;

Have you got the motor running, you don't need the encoder to do this, and it will be a good start as you are new to controllers.

Can you please post a copy of your current circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Have you googled arduino motor encoder tutorial

There are quite a few tutorials on connecting encoders.
Including this one, which looks almost like your motor assembly.

Thanks.. Tom... :slight_smile:

Can you post a link to where you bought the motor so we can see if there is any reference to the encoder unit.
Used a few similar to these in the past and 5v was no problem with most having a hall unit rated to at least 24v but as said above, essential to check.

I got it to work! Thanks anyway.

Wrong989:
I got it to work! Thanks anyway.

What did you do, to keep in the spirit of the forum please show us what you have done to get your project to work.
Thanks.. Tom.. :slight_smile:

So sorry for late reply, I haven't looked at this forum for long time. Hardware was same, just wired it up normally with my diagram (shown earlier in this topic). Code to read encoder magnetic ticks (just change pins if needed [pinMode(blah]):

const int MOT1_ENC1 = 21;
const int MOT1_DIRECT = 20;
const int MOT2_ENC1 = 19;
const int MOT2_DIRECT = 18;

volatile int MOT1_ENC1_TICKS = 0;
volatile int MOT2_ENC1_TICKS = 0;

void ISR_A() {
  if (digitalRead(MOT1_ENC1) == digitalRead(MOT1_DIRECT)) {
    MOT1_ENC1_TICKS++;
  } else {
    MOT1_ENC1_TICKS--;
  }
}

void ISR_B() {
  if (digitalRead(MOT2_ENC1) == digitalRead(MOT2_DIRECT)) {
    MOT2_ENC1_TICKS++;
  } else {
    MOT2_ENC1_TICKS--;
  }
}

void setup() {
//  pinMode(IN1, OUTPUT);
//  pinMode(IN2, OUTPUT);
//  pinMode(IN3, OUTPUT);
//  pinMode(IN4, OUTPUT);
//  pinMode(ENA, OUTPUT);
//  pinMode(ENB, OUTPUT);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(MOT1_ENC1), ISR_A, CHANGE);
  attachInterrupt(digitalPinToInterrupt(MOT2_ENC1), ISR_B, CHANGE);
}

void loop() {
  Serial.println(MOT1_ENC1_TICKS);
  Serial.println(MOT2_ENC1_TICKS);
  Serial.println(" ");
}

Code I used with PID speed corrections, and code to run and ultrasonic sensor alongside your motors. Customize as wanted:

//#include <NewPing.h>

//#define TRIGGER_PIN  49
//#define ECHO_PIN     48
//#define MAX_DISTANCE 500

const int ENA = 13;
const int ENB = 12;

const int IN1 = 53;
const int IN2 = 52;
const int IN3 = 51;
const int IN4 = 50;

const int MOT1_ENC1 = 21;
const int MOT1_DIRECT = 20;
const int MOT2_ENC1 = 19;
const int MOT2_DIRECT = 18;

volatile long MOT1_TICKS = 0;
volatile long MOT2_TICKS = 0;

//volatile int MotorState = 0;
//volatile int UltrasonicState = 0;

//int ticks = 0;
//int Speed = 0;
//int SpeedPID = 0;
//long PIDtimer = 0;

//unsigned long waitForUltrasonic = 50;
//unsigned long timeOld = 0;
//unsigned long currentMillis = 0;

//float DURATION;
//float DISTANCE;

//NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void ISR_A() {
 if (digitalRead(MOT1_ENC1) == digitalRead(MOT1_DIRECT)) {
   MOT1_TICKS++;
 } else {
   MOT1_TICKS--;
 }
}

void ISR_B() {
 if (digitalRead(MOT2_ENC1) == digitalRead(MOT2_DIRECT)) {
   MOT2_TICKS++;
 } else {
   MOT2_TICKS--;
 }
}

void Move_Forward(int Speed) {
 MOT1_TICKS = 0;
 MOT2_TICKS = 0;
 digitalWrite(IN1, HIGH);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, HIGH);
 digitalWrite(IN4, LOW);
 analogWrite(ENA, Speed);
 analogWrite(ENB, Speed);
 MotorState = 1;
}

void Turn_Right(int Speed) {
 MOT1_TICKS = 0;
 MOT2_TICKS = 0;
 digitalWrite(IN1, HIGH);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, HIGH);
 analogWrite(ENA, Speed);
 analogWrite(ENB, Speed);
 MotorState = 1;
}

void Turn_Left(int Speed) {
 MOT1_TICKS = 0;
 MOT2_TICKS = 0;
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, HIGH);
 digitalWrite(IN3, HIGH);
 digitalWrite(IN4, LOW);
 analogWrite(ENA, Speed);
 analogWrite(ENB, Speed);
 MotorState = 1;
}

void Stop() {
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, LOW);
 analogWrite(ENA, 0);
 analogWrite(ENB, 0);
}

void MotorStateMachine() {
 switch (MotorState) {
   case 0:
     break;
   case 1:
     if (MOT1_TICKS >= ticks || MOT2_TICKS >= ticks) {
       Stop();
       MotorState = 0;
       break;
     }
     if (PIDtimer < millis()) {
       PIDtimer += 70;
       SpeedPID = Speed + PID(MOT2_TICKS - MOT1_TICKS);
       constrain(SpeedPID, 0, 255);
       analogWrite(ENB, SpeedPID);
     }
     break;
   case 2:
     Stop();
     MotorState = 0;
     break;
   case 3:
     Stop();
     delay(500);
     ticks = CMtoTicks(30);
     Turn_Right(180);
     MotorState = 4;
     break;
   case 4:
     if (MOT1_TICKS >= ticks || MOT2_TICKS >= ticks) {
       Stop();
       MotorState = 5;
       break;
     }
     if (PIDtimer < millis()) {
       PIDtimer += 70;
       SpeedPID = Speed + PID(MOT2_TICKS - MOT1_TICKS);
       constrain(SpeedPID, 0, 255);
       analogWrite(ENB, SpeedPID);
     }
     break;
   case 5:
     delay(500);
     ticks = CMtoTicks(1000);
     UltrasonicState = 1;
     MotorState = 6;
     Move_Forward(180);
     break;
   case 6:
     if (MOT1_TICKS >= ticks || MOT2_TICKS >= ticks) {
       Stop();
       MotorState = 7;
       break;
     }
     if (PIDtimer < millis()) {
       PIDtimer += 70;
       SpeedPID = Speed + PID(MOT2_TICKS - MOT1_TICKS);
       constrain(SpeedPID, 0, 255);
       analogWrite(ENB, SpeedPID);
     }
     break;
   case 7:
     Stop();
     ticks = 0;
     MotorState = 0;
     UltrasonicState = 0;
     Stop();
     break;
   default:
     break;
 }
}
//void UltrasonicStateMachine() {
 //switch (UltrasonicState) {
   //case 0:
     //break;
   //case 1:
     //currentMillis = millis();
     //if ((currentMillis - timeOld) >= waitForUltrasonic) {
       //timeOld = millis();
       //DURATION = sonar.ping();
       //DISTANCE = (DURATION / 2) * 0.0344;
       //if (DISTANCE <= 30 && DISTANCE > 0) {
         //MotorState = 3;
         //UltrasonicState = 0;
       //}
     //}
     //break;
   //default:
     //break;
 //}
//}

int PID(int error) {
 static int I = 0;
 static int error_last = 0;
 static float Kp = 3.9;
 static float Ki = .001;
 static float Kd = .1;
 float PID;
 I += error;
 PID = Kp * error + Ki * I + Kd * (error - error_last);
 error_last = error;
 return int(PID);
}

int CMtoTicks(int cm) {
 static int circumference = 65;
 static int ticksPerCircum = 695;
 float ticksPerCM = ticksPerCircum / circumference;
 float CMtoTicks_dec = ticksPerCM * cm;
 int CMtoTicks = CMtoTicks_dec;
 return CMtoTicks;
}

void setup() {
 pinMode(IN1, OUTPUT);
 pinMode(IN2, OUTPUT);
 pinMode(IN3, OUTPUT);
 pinMode(IN4, OUTPUT);
 pinMode(ENA, OUTPUT);
 pinMode(ENB, OUTPUT);
 attachInterrupt(digitalPinToInterrupt(MOT1_ENC1), ISR_A, CHANGE);
 attachInterrupt(digitalPinToInterrupt(MOT2_ENC1), ISR_B, CHANGE);
 //Put code to execute once here:
 UltrasonicState = 1;
 ticks = CMtoTicks(1000);
 Move_Forward(180);
}

void loop() {
 MotorStateMachine();
 UltrasonicStateMachine();
}