Hall effect sensor A3144 tachometer inaccurate readings

Hello

I've built a simple pickup coil winding machine for making custom pickups for musical instruments. I've got a geared DC motor (200RPM) speed controlled by PWM from an ATMEGA328 on a PCB. I'm having trouble with the turn counter though.

I've got an A3144 hall effect sensor in close proximity to the rotating disc, which has a small neo magnet. I believe I have this magnet set in the correct orientation, and get readings using attachInterrupt when it passes by the sensor.

I've got a 10k resistor between 5V and the output of the sensor, and a 100nf ceramic cap between ground and 5V.

The amount of turns is read out on an LCD screen. My intention with the code was that every time the sensor detected a transition from HIGH to LOW, a counter is incremented. However, when I start the motor from 0 with PWM, before it even starts rotating, the sensor is counting . If I change speed on the motor when it is turning it adds dozens or hundreds of counts, not matching the actual amount of rotations.

I read in other posts about interrupts that it doesn't play well with delay() so I removed the one instance of delay in the code, which was a button debouncing tip from an instructables tutorial. This didn't have any effect. From reading other posts about the A3144 I added a decoupling cap but that didn't seem to do much - in fact the counts started jumping up into the hundreds where before they had crawled along.

Here's my code. It's entirely possible I've made some dumb mistake with my use of attachInterrupt - please let me know how idiotic I am if so! My fear is that the motor is emitting EM interference, which doesn't sit well with the design of my winder if I've to move it.

Any suggestions welcome :slight_smile:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

//int hallEffect = 2; //(A3144)
int TIP120pin =3; //(PWM)
int onOffTransistor = 4;
int startStop = 9;
int testLed = 13;//3mm test LED


volatile unsigned int revs = 0;
int speedPot = A0;

LiquidCrystal_I2C lcd(0x38,16,2);  // set the LCD address to 0x20 for a 16 chars and 2 line display

boolean currentState = LOW;//stroage for current button state
boolean lastState = LOW;//storage for last button state
boolean ledState = LOW;
boolean transState = HIGH;
///////////////////////////////////////////////////////////////////
//SETUP//
///////////////////////////////////////////////////////////////////
void setup() {

  lcd.init();                      // initialize the lcd 
  lcd.setBacklight(LOW);
  lcd.print("test");
  pinMode(TIP120pin, OUTPUT);
  pinMode(testLed, OUTPUT);
  pinMode(startStop, INPUT_PULLUP);
  pinMode(onOffTransistor, OUTPUT);
  attachInterrupt(0, rpm_fun, FALLING);//hall effect sensor on digital pin 2
  //  Serial.begin(9600);

}
///////////////////////////////////////////////////////////////////
//MAIN LOOP//
///////////////////////////////////////////////////////////////////
void loop() {
  currentState = digitalRead(startStop);
  if (currentState == HIGH && lastState == LOW){//if button has just been pressed
    // Serial.println("pressed");
  //  delay(1);//crude form of button debouncing

    //toggle the state of the LED
    if (ledState == HIGH){
      digitalWrite(testLed, LOW);
      ledState = LOW;
    } 
    else {
      digitalWrite(testLed, HIGH);
      ledState = HIGH;
    }
    if (transState == HIGH){
      digitalWrite(onOffTransistor, LOW);
      transState = LOW;
    } 
    else {
      digitalWrite(onOffTransistor, HIGH);
      transState = HIGH;
    }
  }


  int speedMotor = analogRead(speedPot);
  speedMotor = map(speedMotor, 0, 1023, 0, 255);
  analogWrite(TIP120pin, speedMotor);
  //  int revs = digitalRead(hallEffect);
  // Serial.println(speedMotor);
  //  Serial.print("Turns = ");
  //  Serial.println(revs);
  lcd.print("Turns = ");
  lcd.print(revs);

  lcd.clear();
  lastState = currentState;
}

void rpm_fun(){
  revs++; 
}

Sounds a lot like this guy's problem (another PWM noise post). Using an optoisolator to drive your motor driver (Mosfet?) and separating the power supplies might help you.

thanks for your reply. Sounds similar alright...also doesn't sound like a particularly easy thing to fix judging by the different attempts at isolation he used.

I've got a 12V source for the motor, which is driven by a TIP120 via PWM. Voltage regulation by LM805. If I put an optoisolator between the PWM pin and the 1k resistor - I have a 6n137 optoisolator.

I just came across this passionate plea to electronics hobbyists not to use TIP120 in favour of a modern MOSFET. Is the TIP120 the likely culprit?

cheers

You've probably got my reply on the other thread by now.

I suggest you get a 'scope on the signal so you really know what is going on. You may find you actually have a problem that you can solve once you know what is going on.

Watch how the signal is affected (or may be not) as you move your Arduino and wiring closer to the various sources of EMF.