Hall Sensor on Linear Actuator

Hello everyone. I have been searching and researching and have not found any viable answers to my questions. I have one of these actuators (http://www.timotion.com/product/1481269298/74) hooked up to a motor shield (Pololu Dual VNH5019 Motor Driver Shield for Arduino) on a Arduino Mega. The MA2 is configured with dual hall effects but I only need the one. Using an interrupt I am counting the rotations to keep track of the stroke distance. The problem I am having is when I send the counter data to the serial monitor for review I get multiples and multiples showing up. I have attached a screen capture of the serial monitor for review. Can anyone tell me why this is and will it have any bearing on accuracy? In the example code I am retracting and extending to the internal limit switches. Thanks in advance for any insight.

#include "DualVNH5019MotorShield.h"
DualVNH5019MotorShield md;

// Motorshield Speed Variable
const int motorspeed = 400;               //400 is max speed
const int delayMotor = 200;               //settle inertia before changing directions

volatile unsigned long act_hallcounter;   // volatile variables, may be changed
volatile byte act_hallstate = LOW;        // volatile variables, may be changed
const int act_hallpin = 19;              //Signal wire in Pin 19 on Mega for interrupt

boolean act_retracting = false;
boolean act_extending = false;

void setup() {
  pinMode(act_hallpin, INPUT);
  digitalWrite(act_hallpin, HIGH);        // enable internal pullup (if hall needs it)
  md.init();                                       // initialize VNH5019
  attachInterrupt(digitalPinToInterrupt(act_hallpin), act_read_hall, RISING);
  Serial.begin(9600);
  Serial2.begin(9600);     
  Serial.println("Actuator Control Test");
}

void loop() {
  if (Serial2.available()>0) 
  {
    char data = Serial2.read();
    switch (data)
    {      
      case 'E':  // Extend Actuator
      Serial.println ("Extend Actuator");     
      act_extend();
      break;

      case 'R':  // Retract Actuator
      Serial.println ("Retract Actuator");
      act_retract();
      break;

      case 'C':  // Calibrate
      Serial.println ("Calibrate Actuator");
      act_calibrate();
      break; 
    }
  }
}

void act_retract()
{
    act_retracting = true;
    md.setM2Speed(-motorspeed);
    delay(1);    
    while(md.getM2CurrentMilliamps() > 0)
      {
        md.setM2Speed(-motorspeed);
        Serial.println(act_hallcounter);
      }
    md.setM2Brake(400);
    act_retracting = false;   
}

void act_extend()
{
    act_extending = true;
    act_hallcounter = 0;
    md.setM2Speed(motorspeed);
    delay(1);    
    while(md.getM2CurrentMilliamps() > 0)
      {
        md.setM2Speed(motorspeed);
        Serial.println(act_hallcounter);
      }
    md.setM2Brake(400);
    act_extending = false; 
}

void act_calibrate()      //Retract actuator to home position to reset counter
{      
    md.setM2Speed(-motorspeed);
    delay(1);    
    while(md.getM2CurrentMilliamps() > 0)
    {
      md.setM2Speed(-motorspeed);
    } 
    md.setM2Brake(400);
    delay(delayMotor);    
    act_hallcounter = 0;
}

void act_read_hall() //ISR for counting hall effect
{
  act_hallstate = digitalRead(act_hallpin);   // read input signal level
  if (act_extending == true)  { act_hallcounter ++; }
  if (act_retracting == true)  { act_hallcounter --; }
}

    while(md.getM2CurrentMilliamps() > 0)

{
        md.setM2Speed(-motorspeed);
        Serial.println(act_hallcounter);
      }

Do you realize how fast that loop runs? Really fast. If it wasn't being slowed down by the Serial.println() then it could be running maybe a hundred thousand times per second.

MorganS thanks for replying. I do realize how fast that loop runs but what I am asking is why are there multiples of the same number being printed to the serial monitor. i am not printing the current used by the actuator I am printing the number of times the rising of the hall effect sensor is recorded. Shouldn't that be once per rev with a single hall sensor? That loop is used to let me know when I have reached the internal limit switches and reset the counter to zero. I know every actuator is different but can't I calculate how many revs is needed to extend the shaft a certain distance by knowing the lead screw pitch? This particular actuator has a stroke of 100mm and from min to max travel I get 370. That would mean the lead screw has a approximate pitch of .27mm. That is a pretty fine thread. I must be missing something or the code is wrong. I will call the manufacturer and get the details on the encoder design and pitch details.

what I am asking is why are there multiples of the same number being printed

Because the number is the same.

The loop quoted in reply #1 repeatedly prints the value of act_hallcounter as fast as it possibly can.

You would do better to use BOTH HE sensors, they are probably set up in quadrature encoder form, can you post a wiring diagram for the actuator? I didn't see anything about the HE sensors on the datasheet.

Outside, US tech engineer sent me the attached image. I also attached the datasheet. Sorry I forgot you looked at it. I am able to accurately control its stroke. I just wanted to know why the multiple numbers appear. I don’t want to open it up as it voids the IP69K rating. Thanks for replying.

wiring.jpg

DataSheet_MA2-C_EN.pdf (561 KB)

jremington. I am completely new to the encoding of linear actuators. So thanks for understanding my additional questions. Are you saying because the while loop is way faster than the counter is incrementing that it prints the same value multiple times from the act_hallcounter? Isn't the hall sensor used to count the rotations of the drive nut? Here is an article from Timotion. https://www.timotion.com/fr/news-content/1481266229/277. What is the best way just to count rotations? Thanks for educating me.

One way to avoid printing the same value of a number over and over again is to print the number only when it has changed.

Furthermore, act_hall_counter is a four byte global variable being modified by an interrupt, and that can happen while you are printing and cause incorrect data to be printed.

Therefore, you need to turn interrupts off, make a copy of the number, then turn them back on again.

Try, for example, something like this (untested):

unsigned long counter_copy; //possibly global
unsigned long last_counter_copy=0; //last value
...
   noInterrupts();
   counter_copy=act_hall_counter; //copy with interrupts off
   interrupts();
   if (counter_copy != last_counter_copy) {
     Serial.println(counter_copy);
     last_counter_copy=counter_copy; //remember new value
     }