Hall sensor - do I get something wrong?

Hi to all,

I am trying to create a project using a hall sensor to measure the rotations of a wheel. After 5 rotations I would like to have a HIGH output on a pin 3 (which will be switched LOW with another sensor). I use the digital output of KY-024 linear magnetic hall sensor attached to an Arduino Uno device. I created the following sketch.

const int inputPin = 2;                     // Digital input pin
const int outputPin = 3;                    // Digital output pin
int consecutiveTrueHighCount = 0;           // Counter for consecutive true HIGH events
const int requiredConsecutiveTrueHigh = 5;  // Number of consecutive true HIGH events required

void setup() {
  pinMode(inputPin, INPUT);
  pinMode(outputPin, OUTPUT);
  digitalWrite(outputPin, LOW);  // Set the initial state of the output pin to LOW
  Serial.begin(9600);
}

void loop() {
  static int consecutiveHigh = 0;
  int currentState = digitalRead(inputPin);

  if (currentState == HIGH) {
    consecutiveHigh++;
  } else if (currentState == LOW && consecutiveHigh > 0) {
    consecutiveTrueHighCount++;
    consecutiveHigh = 0;
  }

  if (consecutiveTrueHighCount == requiredConsecutiveTrueHigh) {
    digitalWrite(outputPin, HIGH);  // Set the output pin to HIGH
    Serial.println("Consecutive True HIGH reached!");
    // Reset the counter after reaching the required consecutive true HIGH events
    consecutiveTrueHighCount = 0;
  }

  delay(10);  // Adjust the delay as needed based on your application
}

...hope I managed to paste the code in a format as it should be.

I am a bit confused because the if I approach a magnet to the sensor, 5 times I might or might not get the required HIGH output on pin 3 (LED light for test). Sometimes I get the high after approaching the sensor more than 5 times (6-9) sometimes the HIGHT ouutput is not triggered at all.

What am I doing wrong? I just do not understand why I have this confusing output.

Should I use the analog outtput instead?

If I need to add anything else let me know.

you are just using the current state of the sensor. What you need to do is to use the state where the input becomes high not when it is.

This means that the loop can trigger this state several times on the same state.

Look at the state change example in the IDE. For how to do this.

Print the "consecutiveTrueHighCount" after line 20
to know if when approaching the magnet the counting is occurring correctly.
Serial.println(consecutiveTrueHighCount);

i can recommend to use analog input and watch it in serial plotter while rotating, i think diagram will have a double top.

Hi,

Are you sure that the end of the magnet is pointing at the hall effect device and that you are approaching the face of the Hall Effect device with the part number printed on it?

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

Thanks Grumpy_Mike!

Makes absolutely sense!!!
I changed the code with your suggested approach and it works just perfect!

Yes, magnet points in the right direction.

I changed the approach of code as per Grumpy_Mike's suggestion and it works fine!

Hi all and thank you very much for the help so far. I am trying to build a small device which starts at every 9th rotation of a wheel and stops when a signal comes in from pin 6.

This is my code:

const int rotationPin = 2;  
const int ejectorStartPin = 5;
const int ejectorStopPin =6;

// Variables will change:
int rotationCounter = 0;  // counter for the number of button presses
int sensorState = 0;        // current state of the button
int lastSensorState = 0;    // previous state of the button

void setup() {
  // initialize the button pin as a input:
  pinMode(rotationPin, INPUT);
  // initialize the LED as an output:
  pinMode (ejectorStartPin, OUTPUT);
  pinMode (ejectorStopPin, INPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // read the pushbutton input pin:
  sensorState = digitalRead(rotationPin);

  // compare the buttonState to its previous state
  if (sensorState != lastSensorState) {
    // if the state has changed, increment the counter
    if (sensorState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      rotationCounter++;
      Serial.println("on");
      Serial.print("number of rotation: ");
      Serial.println(rotationCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  lastSensorState = sensorState;


  if (rotationCounter % 9 == 0) {
      digitalWrite(ejectorStartPin, HIGH);
  } 

  if (digitalRead(ejectorStopPin) == HIGH) {
    delay (500);
    digitalWrite(ejectorStartPin, LOW);
  }
}

Everything works fine except for one thing.
The ejector is always receives a HIGH signal while the rotation counter measures a rotation that is a multiple of 9 - as it is programmed, but I am not able to switch it to LOW with the signal from pin6 unless the rotation counter shows a value that is not a multiple of 9.

In other words if the rotation counter stays on 9, 18, 27, etc. the ejector will be on and I am not able to swicth it off with pin 6.

Can you help me how to fix it?

What about

Previously declaring
boolean ejectorStarted=false;

EDIT: Note that if the count stays at 9 forever, this may cycle the ejector. You may want to change the last line to something like

if(rotationCounter %9 != 0) {
   ejectorStarted=false;
}

You need to do some testing...

Thanks for the suggestions, I tested it and the ejector stops on HIGH from ejectorStopPin only if the rotation counter value is other than a multiple of 9 any other suggestion?

Correct, that is how you have coded it.
Each time round the loop the "ejectorStartPin" goes LOW only for a fraction of a second before it is put high again by the logic. This is because the lines that deal with the "ejectorStartPin" are just tagged on the end of the loop function and always get called.

You only want to do this when you get a change of state of the rotation pin, not every time through the loop.

Thanks Grumpy_Mike for putting me in the right direction! Sorry for annoying everyone with basic questions but coming from a completely different background I need some time to understand the logic of how Arduino works.

No need to apologist at all. Your basic questions are just what you need to know and we are all happy to guide you through them.

Hi, All,

I started the assembly of the unit after doing the test on the breadboard - and the whole thing collapsed. Does the length of the wires change the way hall sensor operates? I used an SA-15 unit for testing. Then I removed the hall sensor from the unit and replaced it with a more solid one. Still worked. Then added cc. 4 meters of wire to the circuit (between the sensor and the SA-15 unit and now it doesn't ot work. Can you guide me if there is a way to get rid of th whole SA-15 unit? How can I calculate what size of resistors I should add to the circuit to make it work?

No surprise here that is a long way for an electronic signal.
You probably need a differential buffer on the send end and receive end to go that far.

it would be good to see a schematic of your hardware, along with a description of what you are actually trying to achieve.

Your description is very zoomed in with no detail about why you want to do this.

What does that mean?

I do not understand the purpose of the SA-15 unit, what are you going to do with the information it gives you?

Please see attached the drawing of my project.
drawing.pdf (207.7 KB)

I am building a device that is connected to an ATV. The purpose is to eject a tube every 20 meters while the ATV moves on a field. On the wheel, I attach a magnet, and the rotation of the wheel is measured by a hall sensor. Every 20 meters a signal should start an electric motor that is attached to a revolver-type chamber (similar to a revolver gun). On this chamber, there is another magnet and another hall sensor that detects the movement of the chamber to stop the motor so every time just one tube is dropped from the revolver chamber.
I used this hall sensor for the test circuit and programming

but I would like to use a more protected one so I tried to use this one:

https://eu.mouser.com/ProductDetail/Littelfuse/55100-3H-02-A?qs=nyo4TFax6Nff4PypTg%2FOjg%3D%3D&gad_source=1&gclid=CjwKCAiAg9urBhB_EiwAgw88mRHKhWJswg2b3Jt6Br0NzvtNqj5dmoX6qtFy5lpcGLNhPt7SzOFhMRoCJb8QAvD_BwE&_gl=1*s05qdy*_ga*Mjc3NjU0Njc2LjE3MDIzMjU3Mzc.*_ga_15W4STQT4T*MTcwMjMyNTczNi4xLjAuMTcwMjMyNTczOS41Ny4wLjA.

but it seems that I should add something.

Let me know if you need anything else.

Hi, @aster33
@aster33 schematic;

Its best to post your images as jpg or png.

What relay are you using for the DC motor?

The 220R pull down resistor, it would be better as 1K or 10K.

Do you have a DMM? (Digital MultiMeter)

Thanks.. Tom.. :grinning: :+1: :coffee: :australia:

OK, I will do jpg or png in the future!

I use this relay:

I have a DMM

Thanks, Peter

Hi,
That relay;
image

Coil = 62R, Coil Voltage = 5V

Coil current = V / R = 5 / 62 = 80mA

You are overloading the output pin of the controller?

What model controller are you using?

Tom.. :grinning: :+1: :coffee: :australia:

I use an Arduino Uno. I see what you mean! Thanks for the tip. I did not damage it yet, but I should change the circuit to avoid it. Do you have any idea how can I overcome this 40 mA difference or I should dump the idea of using a relay? Would a capacitor help?