Help setting up Hall Effect Sensor A3144

I am interested in hall effect sensors to read the presence of a magnet. I have purchased a set of 10 A3144's and I am having a hard time getting them to read a value.

I found documentation here http://iteadstudio.com/store/images/produce/Sensor/Hall_Effect_Sensor/A3144EU_IC-ON-LINE.CN.pdf, but I must admit that I am not the most knowledgable user here.

This seems like it should be a simple setup. Pin one = 5v Pin two = Ground Pin 3 = Digital Pin2 on arduino

I have a pretty powerful magnet, and no matter what I do, or what angle I approach the sensor, digital read is always returning 0, even with the magnet out of range.

Is there anything obvious that I am missing? Does anyone out there have any experience with this type of component?

int sensorPin = 2;
int counter = 0;

void setup() 
{
  // setup serial - diagnostics - port
  Serial.begin(9600);
  pinMode(sensorPin, INPUT);
}

void loop() 
{
  counter++;
  int sensorValue = digitalRead(sensorPin);
  Serial.print(counter);
  Serial.print(" ");
  Serial.println(sensorValue);
  delay(1000);
}

Open-Collector 25 mA Output ... Compatible with Digital Logic

You need pull-up resistor, external between input and +5V or you could activate internal, look here : http://arduino.cc/en/Reference/DigitalWrite

This sensors are magnet pole sensitive. After implementing the pull up resistor as the other post stated, try it using the different sides of your magnet.

pgmartin: This sensors are magnet pole sensitive. After implementing the pull up resistor as the other post stated, try it using the different sides of your magnet.

That is not correct, at least for that device. Switching on and off happens at a certain gauss value (+/- hystrisis value), it is not sensitive to the magnetic polarity of the field. The OP just needs to provide a pull-up to the proper voltage for the device to operate.

From the datasheet:

The output of these devices (pin 3) switches low when the magnetic field at the Hall sensor exceeds the operate point threshold (BOP). At this point, the output voltage is VOUT(SAT). When the magnetic field is reduced to below the release point threshold (BRP), the device output goes high. The difference in the magnetic operate and release points is called the hysteresis (Bhys) of the device. This built-in hysteresis allows clean switching of the output even in the presence of external mechanical vibration and electrical noise.

Lefty

Poor datasheet - its really unclear if its sensitive to B or |B|

Perfect!

Thanks for the help Magician, and all.

That worked perfectly. Was it the "Open Collector" that gave you that answer? I am a bit noobish here. That was much simpler than I thought it was going to be.

It turns out that the sensor is sensitive to polarity. One side will read a north value, and one will read a south value, not that I know which side is which =)

A side question about the programming. I have the code below, and if you read it you might be able to see what I am trying to do. Basically, I want to do "something" when the magnet is detected and when it leaves, non-repeating. Right now it is just printing a message, and it is trivial. I am just trying to learn more about this type of development. I am a programmer by trade, but this type of programming is completely new to me.

It would be very easy to tie up the processor waiting for the event to occur, but that would mean that nothing else could happen while we were waiting for the events. What I have works perfectly for now, but I was wondering if anyone had a more "elegant" way of doing this. Basically my if statements in the loop method.

If I lost you with my explanation, let me know that too, it has been a long day =)

int sensorPin = 2; int counter = 0; boolean sensorState = false;

void setup() { // setup serial - diagnostics - port Serial.begin(9600); pinMode(sensorPin, INPUT); digitalWrite(sensorPin, HIGH); }

void loop() { if(magnetPresent(sensorPin) && !sensorState) { sensorState = true; printMessage("Magnet Present"); } else if(!magnetPresent(sensorPin) && sensorState) { sensorState = false; printMessage("Magnet Gone"); } }

void printMessage(String message){ counter++;

Serial.print(counter); Serial.print(" "); Serial.println(message); // delay(1000); }

boolean magnetPresent(int pin){ return digitalRead(pin) == LOW; }

It would be very easy to tie up the processor waiting for the event to occur, but that would mean that nothing else could happen while we were waiting for the events.

That isn't quite correct, "if/else" statement doesn't hold program from running, and code "reasonable" when main "loop" isn't too big and there is no "delay" inside. Of course, there is always way to improve something, try to experiment with http://arduino.cc/en/Reference/AttachInterrupt for starting, "falling" interrupt would save couple instruction in current code, and increase "responsiveness" for fast varying magnetic fields.

Magician:

Open-Collector 25 mA Output ... Compatible with Digital Logic

You need pull-up resistor, external between input and +5V or you could activate internal, look here : http://arduino.cc/en/Reference/DigitalWrite

Thank you thank you thank you.

You made my month, even though it stupid that I didn't try to set the resistor into 5v....

Hay
I’m also working on a similar project, a bit different. i used 7 LEDs to light up according to the magnetic field strength. but my code seems not working. actually the code itself is something i came up with going through so many examples online. but, still couldn’t get it right and struggling so hard. help me.

here’s my code

const int numReadings = 40;

int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average

int hallinputPin = A0;
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int LED5 = 6;
int LED6 = 7;
int LED7 = 8;

void setup() {
// initialize serial communication with computer:
Serial.begin(9600);

pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(A0, INPUT);

// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}

void loop(){

// subtract the last reading:
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = analogRead(hallinputPin);
// add the reading to the total:
total = total + readings[readIndex];

// advance to the next position in the array:
readIndex = readIndex + 1;
}

// if we’re at the end of the array…
if (readIndex >= numReadings){
// …wrap around to the beginning:
readIndex = 0;
}

// calculate the average:
average = total / numReadings;

if (average >= 4){
average = 5; // max LEDs 7.
}
if (average <= 1){
average = 1; // 1 the min.
}

if (average <= 1) {

digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500); // half a second for stability
}

if (average >= 1.01 && average <= 1.50) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500);
}

if (average >= 1.51 && average <= 2) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500);

if (average >= 2.01 && average <= 2.50) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, LOW);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500);
}

if (average >= 2.51 && average <= 3) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500);
}

if (average >= 3.1 && average <= 3.50) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, HIGH);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500);
}

if (average >= 3.51 && average <= 3.999) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, HIGH);
digitalWrite(LED6, HIGH);
digitalWrite(LED7, LOW);

delay(500);
}

if (average >= 4 ) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, HIGH);
digitalWrite(LED6, HIGH);
digitalWrite(LED7, HIGH);

delay(500);
}
}


And also i came up with another code just in case. I acually dont know what instructions to give. this is my first project and i’m stuck with this for weeks.

int hallPin =A0;
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int LED5 = 6;
int LED6 = 7;
int LED7 = 8;

void setup() {

pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(A0, INPUT);

}

void loop() {

int val =analogRead(hallPin);

if (val <= 8) {
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500); // half a second for stability
}

if (val >= 9 && val <= 16) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500);
}

if (val >= 17 && val <= 32) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500);
}

if (val >= 33 && val <= 64) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, LOW);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500);
}

if (val >= 65 && val <= 128) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, LOW);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500);
}

if (val >= 129 && val <= 256) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, HIGH);
digitalWrite(LED6, LOW);
digitalWrite(LED7, LOW);

delay(500);
}

if (val >= 257 && val <= 512) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, HIGH);
digitalWrite(LED6, HIGH);
digitalWrite(LED7, LOW);

delay(500);
}

if (val >= 513 ) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, HIGH);
digitalWrite(LED6, HIGH);
digitalWrite(LED7, HIGH);

delay(500);
}

}

I'm not sure I'm clear on what it is you are expecting to see on pin "A0". Appears that you expect "A0" to do a Analog to Digital (ADC) conversion of a signal from the output of the A3144, and give a varying value depending on magnetic field strength. Is this basically correct?

If you are using an A3144, an I assuming what I stated above is the case, then you are expecting a result from the A3144 that it does not provide.

The A3144 is essentially a switch. In the presence of a proper polarity magnetic field, the A3144 provides a low / ground on it's output pin. Basically the A3144 switches a ground path.

If my assumption is incorrect then please provide a better description of your circuit and goal of this project.

I recently completed a project using the A3144 and have a fully functional counting device.

Let me know.

Edit: post deleted found the answer right after posting.