Arduino Due - Digital Pins

MicroBahner,

I tested out the MobaTools library today and I was able to get two motor to turn in parallel (at the same time). So looks like exactly what I need! Thanks!

I did have one or two items I wasn't able to figure out, if you might have any comments:

(Background: I am just trying to replace my currently existing motor_move functions shown above. So I call either the clockwise more or counterclockwise move function, and it will move a set amount. This set amount does not change and will be defined only once. Basically, I don't need to keep track of the location of the stepper, as other part of the RPi code manage required tracking.)

  1. I am having difficulty controlling the amount of steps the motor will take in an individual call. I understand the "STEPS_REVOLUTION" variable below is suppose to be the amount of steps for one motor revolution, but the only way I can get the motor to turn more than once is to increase that number. However as I go above 2000, the motor starts to jam and doesn't move. How can I control the total amount of steps the motor takes. I don't see that function? (I 'm trying to set the function to turn the motor about 10 times per call.)

  2. How do I control direction? In your manual (seem image below) it say to add a negative sign to the variable in the "doSteps" function (i.e. make "STEPS_REVOLUTION" negative) , but when I tried that, it just caused the motor to stall.

image

  1. I have noticed that when I don't have anything else running such as a second stepper, or an LED flashing in the main loop, the motor doesn't turn. (For example the code below will turn the motor, but if you comment out the LED flashing, the motor won't turn.) I'm am trying to understand this, mainly because my actual arduino code does not have anything running in the main loop. It only responds to commands over serial via the RPi. Do you think this will be an issue?

Here is some test code I have been using below:

#include <MobaTools.h>

//Stepper DIR and PUL (STEP)
const byte dirPin = 22;
const byte stepPin = 23;

const int STEPS_REVOLUTION = 2000; //Not micro-stepping, step angle 1.8deg/step or 200 steps/rev

MoToStepper myStepper( STEPS_REVOLUTION, STEPDIR );  //Using Stepper Driver

int LED1 = 52;

void setup(){
  pinMode(LED1, OUTPUT);
  
  myStepper.attach(stepPin, dirPin);
  myStepper.setSpeed(200);
  motor_move_clockwise();
}

void loop() {
  
  digitalWrite(LED1, HIGH);    // turn on LED1 
  delay(300);                  
  digitalWrite(LED1, LOW);     // turn off LED1
  delay(300);                  
 
}

void motor_move_clockwise(){
    myStepper.doSteps(STEPS_REVOLUTION); 
   }

The main difference is, that your functions above are blocking. You must always be aware, MoToStepper is NOT blocking. This is important for running the steppers in parallel, but it has a big impact on the structure of your program.

Yes, it ist the amount of steps for one motor revolution, but it is only important for MoToStepper if you want to define the speed as rev/min and not as steps/sec. STEPS_REVOLUTION should always be the real steps per revolution. You should not use it to set speed or steps to take. Don't change this value.

If you want the motor to turn more than once, you must wait until the first movement is finished. Remember that MoToStepper is not blocking. If you call e.g. doSteps again while the motor is still turning, the previous call to doSteps is cancelled and the new one is executed.

I cannot understand that. I tried with your testcode ( see later in this post ) and it worked.

Isn't receiving and interpreting the commands done in loop() ?

Whether you need it or not, MoToStepper always keeps track of the location of the stepper. I would strongly recommend to use that feature :wink:

Here is your testcode with some additional comments and moving the stepper clockwise once and then counterclockwise once. It doesn't make a difference if the code for the LED is commented out or not.

#include <MobaTools.h>

//Stepper DIR and PUL (STEP)
const byte dirPin = 22;
const byte stepPin = 23;

const int STEPS_REVOLUTION = 200; //Not micro-stepping, step angle 1.8deg/step or 200 steps/rev
                                  // This should be the real steps/rev. Without microstepping stay with 200

MoToStepper myStepper( STEPS_REVOLUTION, STEPDIR );  //Using Stepper Driver

int LED1 = 52;

void setup(){
  pinMode(LED1, OUTPUT);
  
  myStepper.attach(stepPin, dirPin);
  //myStepper.setSpeed(200);      // this means 20 rev/min ( STEPS_REVOLUTION is only important
                                  // to compute the correct steprate for setSpeed
  myStepper.setSpeedSteps(500);   // this means 500 steps/sec ( corresponds to your pd=1000 );
  motor_move_clockwise();
  while ( myStepper.moving() );   // wait until all steps are executed ( MoToStepper is NOT blocking! )
  motor_move_counterclockwise();  // if you don't wait, the first movement will be canceled
                                  // and this new movement will be done
}

void loop() {
  
  /* digitalWrite(LED1, HIGH);    // turn on LED1 
  delay(300);                  
  digitalWrite(LED1, LOW);     // turn off LED1
  delay(300);                  
  */
}

 void motor_move_clockwise(){
     myStepper.doSteps(1000); 
 }

 void motor_move_counterclockwise(){
  myStepper.doSteps(-1000); 
 }

The helps clarify a lot! Thanks!

Even when I try to code you just included, if I comment out the two lines below, the stepper doesn't turn:

 while ( myStepper.moving() );   
  motor_move_counterclockwise();

I will keep that in mind for the future!

I'm still working on the serial communication code, but for I2C events are handled in setup().

void setup() {
  
  Serial.begin(9600);
  Wire.begin(0x8);              
  Wire.onReceive(receiveEvent);
  Wire.onRequest(sendData);
}

Very strange ... Did you really change nothing else? It works in my test setup. Does the motor turn back if you don't comment out the two lines?
Please show your test setup - it definitely should work.

You must be aware, that these functions (' receiveEvent' and 'sendData' are called in a TWI ISR-Routine! So they must be as short as possible. Functions that need more time must be handled in loop(), e.g. started by a flag that is set in the ISR routine.

I copied the code in as written. The motor turned clockwise and then counterclockwise just as I would expect. But yeh as soon as I took out the second action (the myStepper.moving() / counterclockwise turn) no commands seem to be executed at all. (I have also tried a separate stepper and driver, with same result) Not sure if it is relevant, but I am using a reproduction board (an Elegoo Mega2560 R3). It was my understanding they are physically the same, but I don't know for sure.

I am using the following stepper and driver to test the code:

https://www.amazon.com/dp/B00PNEQKC0?psc=1&ref=ppx_yo2_dt_b_product_details
https://www.amazon.com/dp/B07HHS14VQ?psc=1&ref=ppx_yo2_dt_b_product_details

Setup
Motor to Driver: Black (A+), Green (A-), Red (B+), Blue (B-),
Driver to Mega: DIR + / PUL + to Mega +5v, DIR- / PUL- to pins as specified in code above.

I'm actually not very familiar with interrupts and this whole side of things. But yes I do see now that Serial is handled in the main loop while I2C is handled in setup(). Interesting.

That should make no difference. I now tested on a Mega and it worked fine - with or without the two lines. I cannot imagine what should be the difference. The only one I see is, that loop() is started without any additional delay in the second case - but that should have no meaning. What if you add a delay() at the end of setup?
Is there anything connected to your board - apart from the stepper ?
I am at a loss...
What happens if you put it all in loop - with or without the counterclockwise moving:

void loop() {  
  motor_move_clockwise();
  while ( myStepper.moving() );   // wait until all steps are executed ( MoToStepper is NOT blocking! )
  delay(300);
  /*motor_move_counterclockwise();  // if you don't wait, the first movement will be canceled
  while ( myStepper.moving() );   // wait until all steps are executed ( MoToStepper is NOT blocking! )
  delay(300);*/
}

Later on everything has to happen in loop().

No, even I2C is not really handled in setup(). The statements in setup() only tell the wire library which functions should be called in the ISR. It all happens while loop() is looping. But as already mentioned, there is too much happening in the ISR. It should must be done in loop() also.