1

I have a small project where I connected a Hall sensor (see picture) to an Arduino Mega. The blue wire is connected to pin 45, the red wire to +5V, and the black wire to GND.

Hall-Sensor AZDelivery KY-003

At the beginning I initialize the pin used to read the sensor as follows.

#define HALL_PIN 45

void setup()
{
  pinMode(HALL_PIN, INPUT);
}

I have written a function to read out the sensor. While there is no magnet nearby, the sensor returns HIGH. If a magnet approaches in the correct orientation, the sensor returns LOW. The function should return true if a magnet is nearby, i.e. if the read value is LOW.

I have noticed that my program logic sometimes does not work reliably after seemingly irrelevant changes to the code. After commenting out more and more code to narrow down the problem, I came across the following discovery.

Implementation 1:

In the first implementation, I initially read out the value of the Hall sensor. Next, I send the value to the serial port. The serial monitor in the Arduino IDE outputs the number 1 (HIGH). This is the expected behavior as during testing there is no magnet nearby. Based on the subsequent program behavior I can confirm that the function returns false. I can let the Arduino run for minutes and the behavior remains stable.

bool readHallSensor()
{
  int s = digitalRead(HALL_PIN);

  Serial.println(s); // The serial monitor outputs 1 (HIGH) 
    
  return s == LOW; // Returns false
}

Implementation 2:

With the second implementation I do not write the read value to the serial port. As expected, the serial monitor in the Arduino IDE remains empty. The function, however, now returns true. Apart from commenting out the marked line and flashing the sketch to the Arduino, I did not make any changes (again no magnet nearby). Also in this case I can let the Arduino run for minutes and the behavior is stable.

bool readHallSensor()
{
  int s = digitalRead(HALL_PIN);

  // Serial.println(s); // No output to the serial monitor
    
  return s == LOW; // Returns true
}

My first suspicion was that the delay caused by writing to the serial port is what makes the difference. I asked an electrical engineer whether Hall sensors might need short breaks between successive readings. He denied my assumption, and indeed, if I simply insert a delay(300); after reading the value (without writing to the serial port) the behavior does not change and is identical to implementation 2.

I can switch back and forth between the two implementations and flash them to the Arduino as many times as I like. The behavior is always as described above for both cases. I cannot make any sense of this, as the behavior seems to lack any (programming) logic. Has anyone ever made similar observations and can give me a hint what might cause this? Thank you in advance.


I haven't found the problem yet, but I have come a step closer. The issue has reappeared in a similar project on the same Arduino. I use a new Hall sensor with pull-up, which is read out wrong again under certain circumstances (always read out as LOW, no matter if a magnet is nearby). The problem seems to occur only when I use a certain pin. The pin in question on my Arduino Mega this time is pin 37. If I connect the Hall sensor to another pin (I have tested 34 and 36), it works fine. If I connect a previously working Hall sensor to pin 37, it will not work anymore (always evaluated as LOW). The only explanations that make sense to me at the moment are that either the Arduino Mega is damaged or that there are side effects, maybe caused by external libraries using certain pins without my knowledge and incorrectly initializing them.

5
  • what happens if you use Serial.println('x');?
    – jsotola
    Commented Aug 27, 2020 at 21:33
  • Do you have a pull up connected between 5 V and the digital output pin? Please check. is it the same with other digital pins too?
    – ArduinoFan
    Commented Aug 28, 2020 at 9:19
  • @goodarduinocode.com Good observation, but it looks like one may be present on the sensor board.
    – StarCat
    Commented Aug 28, 2020 at 14:28
  • 2
    The problem could be in another part of the code. When you run into situations where a seemingly unrelated change completely changes the behavior of the program then you are often times up against some issue causing undefined behavior like a buffer overrun or a memory issue or a bad pointer or something. It can be in a completely unrelated part of the program. But if memory is getting clobbered somewhere then there is no way to predict what the consequences will be. Post a complete and compilable example that illustrates the problem.
    – Delta_G
    Commented Aug 28, 2020 at 14:39
  • Writing a string constant to the serial port (instead of the read value) results in the same behavior as in implementation 2 (no writing to the serial port at all). I added a pull-up since the output voltage was a bit low. However, this did not change the behavior. It seems that the sensor worked fine before and that the problem is software-related. Unfortunately, I still could not find the cause of the problem. I will make sure to update this thread if I should find out what it is. Thank you all for your suggestions!
    – xoric
    Commented Aug 31, 2020 at 16:45

1 Answer 1

3

The 3144 requires a pull-up resistor. It only sinks when a magnet is present. It doesn't source, so the pin is floating if no magnet is present.

You can use the internal pull-up resistor by using pinMode(HALL_PIN, INPUT_PULLUP);

3
  • The Hall sensor came already pre-mounted on a circuit board with a resistor (see picture in my first post). My assumption was that the pull-up was already there. But when we measured the voltage of the output signal, we found that it is only 3.8V (with 4.8V as input voltage). Adding a pull-up has increased the output voltage to the full 4.8V. However, this did not change the behavior of the Arduino so it does not seem to be a hardware problem. Nevertheless your advice is absolutely justified and it is certainly better to add a pull-up. So thank you for that.
    – xoric
    Commented Aug 31, 2020 at 16:37
  • 1
    I think that resistor is for the LED, not a pull-up. Though the net effect is that it will pull-up output pin to 5V minus the forward voltage of the led. The forward voltage of a red led is around 1V so that would give you the voltages you've measured.
    – Gerben
    Commented Sep 1, 2020 at 15:34
  • Thank you for the clarification. My understanding of electrical engineering is still quite limited and I really appreciate your help.
    – xoric
    Commented Sep 1, 2020 at 19:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.