In short, the driver has 6 inputs
ENA +/- (enable)
DIR +/- (direction)
PUL +/- (pulse)
which I would like to control with the outputs of the Arduino NANO (precision clone):
ENA-, DIR-, PUL- directly to the GND of the arduino
ENA+, DIR+, PUL+ directly to the digital outputs of the arduino.
And now a question:
As I read, the digital inputs/outputs of the Arduino are set as inputs by default during power-up, restart,... And if I understand correctly, the driver inputs would take it as if they were at HIGH level at this point.
Sure, I can immediately override settings of the the PINs within setup() (I know that it's possible to use writeDigital LOW before setting the PIN as output, etc), but my concern is the moment before setup() is even called. I need the PINS to be there during arduino start, restart,... for the driver at LOW level.
Is the correct solution to connect the arduino pins directly to the corresponding "+" inputs of the driver, but also connect each of these arduino pins to GND via a pull_down resistor (some 10k)?
Normally the pins are set to input, output or input pullup inside setup(). But I guess you can do that in the code before the setup() function's definition. So as soon as the code starts executing the pins will be configured even before setup() is called.
So, instead of this:
void setup() {
pinMode(8, OUTPUT);
digitalWrite(8, HIGH);
}
Do this:
pinMode(8, OUTPUT);
digitalWrite(8, HIGH);
And this will guarantee that even during arduino start and arduino restart the ENA+ input of the driver will be always on the LOW level even with this connection? (example for ENA+/- inputs)
You don't need any pull-down resistors. The stepper driver has optocoupler inputs, so the arduino only controls one LED per driver input. is absolutely problem-free, even during the startup / power on of the arduino.
Yes, but for all practical purposes the pins will be set to the programmed values as soon as the code starts executing. The time difference is just too small to have any effect...
Why not? Here's some partial code of what I'm using to drive my stepper motor:
The library header that I made:
"A4988_DRV8825_lib.h"
// A4988_DRV8825_lib.h
class A4988_DRV8825
{
public:
A4988_DRV8825(byte stepPin, byte directionPin)
{
pinMode(StepPin, OUTPUT); //Note: pinMode set in constructor
pinMode(directionPin, OUTPUT); //Note: pinMode set in constructor
//Default to CW
digitalWrite(directionPin, HIGH); //Note direction pin set to HIGH in constructor
//Default to stop
digitalWrite(stepPin, LOW); //Note direction pin set to HIGH in constructor
}
void SetSpeed(float rpm)
{
//Code that sets up the required delay between steps to run the motor
}
void Run()
{
//Code that runs the motor
}
}
The actual arduino .ino code
#include "A4988_DRV8825_lib.h"
#define DIR_PIN 7
#define STEP_PIN 13
// Initialize the A4988_DRV8825 object with the above pins:
A4988_DRV8825 objDriver(STEP_PIN, DIR_PIN); //Note that the pinMode for DIR & STEP pins are being done in the constructor and not in setup()
void setup()
{
}
void loop()
{
objDriver.SetSpeed(45.0f);
objDriver.Run();
}
This code is tested and working perfectly at the moment. As you can see the pinMode() and digitalWrite() for the STEP and DIR pins are being done in the constructor A4988_DRV8825::A4988_DRV8825() which is being invoked when objDriver is instantiated outside of setup().
If you want I will be happy to share the full code for scrutiny. Rest assured setup() is just the arduino framework function for organising code that will be run only once. Any code outside of setup() such as variable initialisation or pinMode or writes, etc still has to be executed in the order in which its written till execution reaches loop().
The bootloader and other framwork initialization is done before user code. Dunno what happens behind the scene with ESP82 and other big controllers. Not a full Windows boot, but the FreeRTOS version. And nothing at all will happen while somebody is pressing the Reset button.
There is no argument against pull up/down resistors on critical control lines. If it seems to work without such resistors the first user will proof the opposite
Right. And any code written before setup(), after setup() and before loop() will be executed in that order. Once loop() is invoked control will not reach any code that is written after loop().
How comes that you assume any order of execution, based on the code position inside a module? Where is a place in the C/C++ syntax that allows for statements outside functions?
You can have global variables, with declaration and initialisation (i.e. defined not just declared). Statements that are executable directly (not function defintion) will be executed as encountered. Functions are callable and will be executed when called. So setup() is indeed the first function to be called by the arduino runtime itself but any code declared and implemented before it that is directly executable will be executed. To the computer its just a set of instructions that it starts executing from the start of the code. The arduino framework or runtime will execute statements before setup() if they are initialising statments, construction statments or even a function call. If setup indeed is first then we would not be able to initialize any variable in this manner but if you see the code I posted it works perfectly well.