Using an arduino(A) to count the steps from a motor driven by an arduino(B)

Good afternoon everyone.

I think formatting is OK but apologize in advance if it is not.

GOAL:
What I am trying to do is run a NEMA34 1600pul/rev stepper motor with an Arduino Uno (let’s call it Arduino B), while counting the steps taken using a primary Arduino Mega (Arduino A) .

RATIONALE:
The reason (i think) I need to use two Arduinos is because I will be running the motor at ~300-400rpm while collecting data from a load cell, storing data to an SD, and checking a few safety switches.

PROBLEM:
When I run upload the following code to both Arduinos, I want the motor to turn 2 revolutions (3200 steps) and stop for 3 seconds, and repeat. What actually happens is the motor spins for ~20-30 revolutions, and the step count that I am reading on Arduino A is not accurate.

SETUP:
Arduino A has:
pulsePin coming from the motor/Arduino B as an input to PIN 3
arduinoPin going from Arduino A PIN 8 as an OUTPUT to Arduino B PIN 2

Arduino B has:
pulPin going to the motor/Arduino A as in output from PIN 3
dirPin going to the motor as an output from PIN 4

CODE:

ARDUINO A:

// MAIN ARDUINO, ARDUINO MEGA

int arduinoPin = 8; // pin connected to secondary arduinos interrupt pin 2
int pulPinIn = 3; // Pulse pin from the stepper, as an input to count the steps
int stepCount = 0; // step counter
void setup() {
pinMode(arduinoPin,OUTPUT); // pin to stop the motor on the secondary arduino
pinMode(pulPinIn,INPUT); // pul pin going into the stepper motor
Serial.begin(9600);
}

void loop() {
//potVal = analogRead(potVal);
stepCount += digitalRead(pulPinIn);
if(stepCount == 3200){ // 3200 steps should be 2 complete revolutions
  digitalWrite(arduinoPin,HIGH); // change the state of the interrupt
  delay(3000); 
  digitalWrite(arduinoPin,LOW); // change the state of the interrupt
  stepCount = 0;
}
Serial.println(stepCount); // print the step count to determine accuracy

}

ARDUINO B:

// SECOND ARDUINO, ARDUINO UNO

int arduinoPin = 2; // pin connected to arduinoPin on the first arduino. interrupt pin 
bool dir = 0;
int dirPin = 4; // direction pin to the stepper driver
int pulPin = 3; // pulse pin to the stepper driver
int motorSpeed = 100; // motor speed (lower is faster)
int motorRun = LOW; // initial condition to get the motor to run
void setup() {
  pinMode(arduinoPin,INPUT); // interrupt pin, pin 8 on MAIN ARDUINO
  pinMode(pulPin, OUTPUT); // to stepper motor driver
  pinMode(dirPin, OUTPUT); // to stepper motor driver
  attachInterrupt(digitalPinToInterrupt(arduinoPin),motorStop,CHANGE);
}

void loop() {
 
  digitalWrite(dirPin, dir); // set direction
  while(motorRun == LOW){
    digitalWrite(pulPin, HIGH);
    delayMicroseconds(motorSpeed);
    digitalWrite(pulPin, LOW);
    delayMicroseconds(motorSpeed); // rising edge to spin the motor
    
  }

}
void motorStop(){
  motorRun = !motorRun; // stop/run the motor until a change from the MAIN ARDUINO pin is seen 
}

QUESTION: Is there anything I can do to my current setup to generate an accurate reading of the step count?

The reason (i think) I need to use two Arduinos

Unless you have evidence that one can't accomplish the task, you are creating an awful lot of work for yourself.

There is certainly no reason to use a blocking delay, like this:

    digitalWrite(pulPin, HIGH);
    delayMicroseconds(motorSpeed);
    digitalWrite(pulPin, LOW);
    delayMicroseconds(motorSpeed); // rising edge to spin the motor

Try one of the nonblocking stepper libraries, like AccelStepper. I suspect you will find that there is PLENTY of time to do other things, while the motor runs.

jremington:
Unless you have evidence that one can’t accomplish the task, you are creating an awful lot of work for yourself.

There is certainly no reason to use a blocking delay, like this:

    digitalWrite(pulPin, HIGH);

delayMicroseconds(motorSpeed);
   digitalWrite(pulPin, LOW);
   delayMicroseconds(motorSpeed); // rising edge to spin the motor



Try one of the nonblocking stepper libraries, like AccelStepper. I suspect you will find that there is PLENTY of time to do other things, while the motor runs.

Using AccelStepper.h yielded the same results.

Same Arduino A code

Updated Arduino B code:

// SECOND ARDUINO, ARDUINO UNO
#include<AccelStepper.h>

int arduinoPin = 2; // pin connected to arduinoPin on the first arduino. interrupt pin 
bool dir = 0;
int dirPin = 4; // direction pin to the stepper driver
int pulPin = 3; // pulse pin to the stepper driver
int motorRun = LOW;
AccelStepper stepper(AccelStepper::DRIVER,pulPin,dirPin);


void setup() {
  pinMode(arduinoPin,INPUT); // interrupt pin, pin 8 on MAIN ARDUINO
  attachInterrupt(digitalPinToInterrupt(arduinoPin),motorStop,CHANGE);
  stepper.setCurrentPosition(0);
  stepper.setMaxSpeed(8000);
  stepper.setSpeed(8000);
  stepper.setAcceleration(8000);
  stepper.setAcceleration(8000);
}

void loop() {
 
  digitalWrite(dirPin, dir); // set direction
  while(motorRun == LOW){
  stepper.move(3600);
  stepper.run();
  }

}
void motorStop(){
  motorRun = !motorRun; // stop/run the motor until a change from the MAIN ARDUINO pin is seen 
}

Using AccelStepper.h yielded the same results.

You are using AccelStepper in blocking mode. Two successive calls to stepper.move() are BLOCKING, because it has to wait for the first to finish before it can start the second.

Read the AccelStepper documentation more carefully to learn how to use it in non-blocking mode. Basically, it means using stepper.move() to start the motion, then use a loop to keep the motor in motion with stepper.run(), while doing other things.

Study these two multitasking tutorials for more:
http://www.gammon.com.au/blink
How to do several things at once.

Note: motorRun must be declared "volatile" if shared between main and an interrupt routine.