Help Needed With Dual Stepper Motor Code.

Hello, Everyone

I'm completely new to the Arduino platform and without any experience of coding at all. I'm trying to build a dual focus system for my camera rig. I want to focus two lenses at the same time to the same focal length. Due to the different focus ring throw distance on individual lenses, the speed at which each lens needs to focus has to be variable. I hope to build a prototype using two stepper motors to see whether the concept works.

I found a simple sketch (I will post the schematic and sketch below) to drive one stepper motor that uses an Arduino UNO/ L293 IC/ Potentiometer to control speed/ 2 switches + resistors for forward/reverse direction/ 4 LEDS + resistors to indicate motor phase. The stepper is a 5V, 4 phase, 28BYJ-48 motor. It all works well. I would now like to add a second stepper motor to mirror exactly this combination. I have purchased the extra parts necessary and have already wired them up using pins 4 and 5 as switch INPUTs, pins 6, 7, 8 and 9 for the second L293 chip, and A1 for the second potentiometer. I hope this is correct.

I am now struggling with the coding aspect. I naively hoped it was as simple as assigning the corresponding names/numbers to each motor/int/ pinMode lines of code. Then by duplicating the code within the void loop and assigning the respective name and numbers to their anologRead/ digitalRead/ set/ setSpeed commands lines and it would work. When I do this, I get an “expected-unqualified error before 'if'” statement in the duplicated portion of the code. I will only post the original code here as my effort at coding would probably serve more to confuse than contribute..

If anyone is able to help with the coding, it would be greatly appreciated. Thanks in advance to everyone.

Original Code:

#include <Stepper.h>

int forward = 2;
int reverse = 3;

Stepper motor(200, 10,11,12,13);            

void setup() {
  pinMode(forward,INPUT);
  pinMode(reverse,INPUT);
    }

void loop() {
  int Speed = analogRead(A0);
  int RPM = map(Speed, 0, 1023, 0, 100);
  int f = digitalRead(forward);
  int r = digitalRead(reverse);
  if(f == 1 && r == 0 && RPM > 1){
  motor.step(1);
    motor.setSpeed(RPM);
    delay(.01);
  }
  if(r == 1 && f== 0  && RPM > 1){
    motor.step(-1);
    motor.setSpeed(RPM);
        delay(.01);
  }
  delay(5);
    
}]

Schematic.jpg

Read the error message - The compiler tells you the problem is on line 30, character 2. It found a ']' where it does not belong. Look there, and you should see the problem.

Regards,
Ray L.

That code only has 1 motor in it. It also has an unwanted ] at the end.

Post the code for the two motors.

...R

Hi Ray and Robin

Thanks for the speedy replies. I'm not sure whether I explained myself clearly in my opening post. I understand that the sketch that I posted was written to drive only a single motor. This code runs a single stepper motor perfectly. The extra bracket that you both identified is not in the original sketch. Somehow it got into the code when I posted it on this forum.

Basically, I have already configured my Arduino so it physically has two of everything that is in the schematic that I posted earlier. What I am after now is a way to adapt the existing code so that it will run the two stepper motors in the same way that it currently runs a single one. I had a stab writing a sketch myself, but I really know nothing about coding and just tried what I thought to be logical. It didn't work. I was really hoping an experienced coder might be willing to have a go at adapting it. I hope this clarifies things a little better.

Cheers.

P.S. If you think my attempt might give you an idea of what I am trying to do, I will post it. It might amuse you if nothing else.

delay() takes an INTEGER argument! delay(.01) is the same as delay(0), which is clearly pointless.

Cheers, Paul.

neospartacus100:
I had a stab writing a sketch myself, but I really know nothing about coding and just tried what I thought to be logical. It didn't work.

That's exactly what I want you to post. Then we have a starting point from which to help you.

...R

That's exactly what I want you to post.

OP: Even if you are not proud of your attempt, you need to post it, so we can see what you tried, what you thought might work, etc. That way, we have an idea where you are coming from and where you went off the tracks (or the deep end, whichever metaphor works).

Not sure whether my sketch was even on the tracks to start with, but here goes. Thanks for the encouragement anyway.

You will note the #include <StepperAK.h> . This is included as I don't believe the stepper motors I'm using are compatible with the standard <stepper.h> library. If this is removed, additional errors are present. This is the link for the StepperAK library download page.

As you can see, I have basically just duplicated the original code and, where I thought necessary, named and assigned the two motors with their corresponding pin numbers. I tried the same thing with the void setup and void loop. After that, I crossed my fingers and hoped.

As expected, the compiler returned errors:

Steppers2A:41 error: expected unqualified-id before 'if'
Steppers2A:46 error: expected unqualified-id before 'if'

Although only two are highlighted on line 41 and 46 in the void loop, I believe that there are probably more fundamental problems with my sketch. Anyway, hope this helps. Cheers again for your interest my problem. I really do appreciate it.

#include <StepperAK.h>

#include <stepper.h>

Stepper motor1(200 ,6,7,8,9);
Stepper motor2(200 ,10,11,12,13);

int forwardmotor1 = 2;
int reversemotor1 = 3;
int forwardmotor2 = 4;
int reversemotor2 = 5;

void setup() {
  pinMode(forwardmotor1,INPUT);
  pinMode(reversemotor1,INPUT);
  pinMode(forwardmotor2,INPUT);
  pinMode(reversemotor2,INPUT);
}
  
void loop(){
  int Speed = analogRead(A0);
  int RPM = map(Speed, 0,1023,0,100);
  int f = digitalRead(forwardmotor1);
  int r = digitalRead(reversemotor1);
  if(f == 1 && r == 0 > 1){
  motor1.step(1);
    motor1.setSpeed(RPM);
      delay(.01);
  }
  if(r == 1 && f== 0 &&RPM > 1){
    motor1.step(-1);
    motor1.setSpeed(RPM);
       delay(.01);
 }
 delay(5);
}
 int Speed = analogRead(A1);
 int RPM = map(Speed, 0,1023,0,100);
 int f = digitalRead(forwardmotor2);
 int r = digitalRead(reversemotor2);
 if(f == 1 && r == 0 > 1){
   motor2. step(1);
    motor2. setSpeed(RPM);
    delay(.01);
 }
  if(r == 1 && f == 0 &&RPM > 1){
    motor2.step(-1);
    motor2.setSpeed(RPM);
       delay(.01);
       }

What is this (on line 41)?

if(f == 1 && r == 0 > 1){

That is not valid syntax.

Regards,
Ray L.

Hi Ray

I don't have the answer to that question. If you say it's an invalid code, I have to believe that is the case. Your knowledge is greater than mine on the subject. This is code that I found on blog site that works in it's original form to run the single stepper motor without issues (see my earlier original code post.) My version is an attempt to adapt it for two motors. I have not changed any of the written instructions as such, just added names and pin numbers to the motors. The strange thing is that the identical string of code is also on line 30 and yet no error is highlighted there. Any ideas?

The stepper is a 5V, 4 phase, 28BYJ-48 motor.

Isn't that a 5-wire unipolar motor? But you mention a L293D, which is a dual-Hbridge
(which are normally used for high impedance bipolar motors)

You can drive two unipolar motors from one ULN2803, which would seem a better
use of hardware than two L293Ds.

One other observation - the 28BYJ-48's have a lot of backlash in their gear systems
which isn't what you want really for high accuracy. You may be able to code round this
though.

A good way to structure your code is to pass the motor objects around by
reference to the routines that control them - thus you only write the code once.

Following is the code from Reply #8 with my commentary added.
I make no claim that my comments are exhaustive and I have not tested the code.

#include <StepperAK.h> 		// <<<<< don't think this is necessary

#include <stepper.h>

Stepper motor1(200 ,6,7,8,9);
Stepper motor2(200 ,10,11,12,13);

int forwardmotor1 = 2;
int reversemotor1 = 3;
int forwardmotor2 = 4;
int reversemotor2 = 5;

void setup() {
  pinMode(forwardmotor1,INPUT);
  pinMode(reversemotor1,INPUT);
  pinMode(forwardmotor2,INPUT);
  pinMode(reversemotor2,INPUT);
}
  
void loop(){
  int Speed = analogRead(A0);
  int RPM = map(Speed, 0,1023,0,100);
  int f = digitalRead(forwardmotor1);
  int r = digitalRead(reversemotor1);
  if(f == 1 && r == 0 > 1){
  motor1.step(1);
    motor1.setSpeed(RPM);		// <<<<<< I suspect you should set the speed before the step
      delay(.01);				// <<<<< I doubt if this is necessary or useful
  }
  if(r == 1 && f== 0 &&RPM > 1){
    motor1.step(-1);
    motor1.setSpeed(RPM);
       delay(.01);
 }
 delay(5);
//}							// <<<<<< this needs to move to the very bottom
 int Speed = analogRead(A1);  // <<<<< this can go right after (or before) the other analogRead()
 int RPM = map(Speed, 0,1023,0,100);  // <<< you need separate variable names for this motor - eg RPM2
 int f = digitalRead(forwardmotor2);  //     etc
 int r = digitalRead(reversemotor2);  //     etc
 if(f == 1 && r == 0 > 1){
   motor2. step(1);
    motor2. setSpeed(RPM);
    delay(.01);
 }
  if(r == 1 && f == 0 &&RPM > 1){
    motor2.step(-1);
    motor2.setSpeed(RPM);
       delay(.01);
       }
}							//  <<<< at the bottom, here

...R

Hi Mark

Thanks for the information regarding an alternative IC. That might be something I will consider in the future. Yes, the 5V, 4 phase, 28BYJ-48 is the 5 wire version. I am not using the com fifth (red) wire in this configuration. I just purchased two of the cheapest steppers in order to test the concept. I was trying to follow the original components listed with the sketch as closely as possible. Although, I will admit that the original setup was driving a different motor to the one I'm using. If I can get the code to do what I want and it operates in a reasonable way, I will invest in a better combination of components. Any recommendations on suitable steppers to use in a follow focus system would be welcome. I imagine low torque and reasonable speed would be the best combination.

I vaguely understand what you are saying regarding the code. You have spotted inefficiency in the structure. Could you elaborate on your,

A good way to structure your code is to pass the motor objects around by
reference to the routines that control them - thus you only write the code once.

maybe by annotating some comments in the code.

Cheers

Hi Robin.

Brilliant! That is the kind of information I was hoping for. I will try your suggestion tonight.

Thank you very much.

neospartacus100:
Hi Ray

I don't have the answer to that question. If you say it's an invalid code, I have to believe that is the case. Your knowledge is greater than mine on the subject. This is code that I found on blog site that works in it's original form to run the single stepper motor without issues (see my earlier original code post.) My version is an attempt to adapt it for two motors. I have not changed any of the written instructions as such, just added names and pin numbers to the motors. The strange thing is that the identical string of code is also on line 30 and yet no error is highlighted there. Any ideas?

Let me revise just slightly. It is legal syntax, but the intent is anything but clear, making it a really bad way to write it. If I am correctly recalling c operator precedence, that line will be parsed as though it were written like this:

if ( ( f == 1 ) && ( ( r == ( 0 > 1 ) ) ) {

which is equivalent to:

if ( ( f == 1 ) && ( r == 0 ) ) {

I doubt this is really the intent, but I have no clue what the intent actually is...

In any case, this is the line the compiler is complaining about, so there is something wrong here. It is poor practice to write such an expression without parentheses, to make the intended order of evaluation clear, as the compiler may evaluate the terms in a different order than the author intended.

What is the ENTIRE error message you get?

Regards,
Ray L.

Success! Very very pleased. I implemented almost everything that Robin advised. The only exceptions being that I kept the #include < stepperAK.h> in place of #include <stepper.h> standard library, and kept the original position on the int2 Speed2 analogRead(A1). It seems to be working as I had hoped. The next phase is to obviously engineer the dual focus system itself.. This is more within my area of experience. I am pretty certain that I will have more questions going forward. As has been pointed out, the code and hardware are not being utilised to maximum efficiency.

To Ray, Paul, Mark and especially Robin, I owe a big thank you. I would have struggled for a long time before finding the solution without your efforts. I already feel like I have a achieved a good start and that your help has given my project real momentum now.

I will post the revised code below for anyone who wishes to use it. If you notice any poor syntax, please feel free to comment. All advice on coding is welcome. I will try to post an updated schematic when I have finalised the wiring configuration. I'm not sure if there is a particular section on this forum where it would be best viewed. Is there a repository for members' projects?

Thanks again to all.

Cheers

Anthony

#include <StepperAK.h>

Stepper motor1(200 ,6,7,8,9);
Stepper motor2(200 ,10,11,12,13);

int forwardmotor1 = 2;
int reversemotor1 = 3;
int forwardmotor2 = 4;
int reversemotor2 = 5;

void setup() {
  pinMode(forwardmotor1,INPUT);
  pinMode(reversemotor1,INPUT);
  pinMode(forwardmotor2,INPUT);
  pinMode(reversemotor2,INPUT);
}
  
void loop(){
  int Speed = analogRead(A0);
  int RPM = map(Speed, 0,1023,0,100);
  int f = digitalRead(forwardmotor1);
  int r = digitalRead(reversemotor1);
  if(f == 1 && r == 0 > 1){
   motor1.setSpeed(RPM);
    motor1.step(1);
    delay(.01);
  }
  if(r == 1 && f== 0 &&RPM > 1){
   motor1.setSpeed(RPM);
    motor1.step(-1);
    delay(.01);
 }
 delay(5);
 int Speed2 = analogRead(A1);
 int RPM2 = map(Speed, 0,1023,0,100);
 int f2 = digitalRead(forwardmotor2);
 int r2 = digitalRead(reversemotor2);
 if(f2 == 1 && r2 == 0 > 1){
   motor2. setSpeed(RPM2);
   motor2. step(1);
    delay(.01);
 }
  if(r2 == 1 && f2 == 0 &&RPM2 > 1){
    motor2.setSpeed(RPM2);
    motor2.step(-1);
    delay(.01);
       }
}

Just out of curiosity what's different about the StepperAK library and where does one get it?

...R

Hi Robin

I was doing a little research and I came across a youtube video that led me to this page. The video tutorial is about fourteen minutes long. It mainly describes the fundamentals of stepper motors and the principals by which they work, but if you jump to 12:36 in the video time line, you will see the explanation the guy gives for using this particular library. Apparently, it is because the standard library is unable to reverse the direction of the 28BYJ-48 stepper motor. Not sure if that is the case or not. He sounds knowledgeable on the subject. The library download link is there too. Hope it's useful to you.

Hi

Just a quick follow up to my earlier posts. The code is now functioning something close to what I require, but for some reason both stepper motors are now taking their speed control from only the potentiometer connected analog pin(A0). I cannot vary the speed of each motor individually. Does anyone notice anything in the code (or missing from it) that may be causing this, or do you think it is more likely to be a hardware issue?

Cheers

#include <StepperAK.h>

Stepper motor1(200 ,6,7,8,9);
Stepper motor2(200 ,10,11,12,13);

int forwardmotor1 = 2;
int reversemotor1 = 3;
int forwardmotor2 = 4;
int reversemotor2 = 5;

void setup() {
  pinMode(forwardmotor1,INPUT);
  pinMode(reversemotor1,INPUT);
  pinMode(forwardmotor2,INPUT);
  pinMode(reversemotor2,INPUT);
}
  
void loop(){
  int Speed = analogRead(A0);
  int RPM = map(Speed, 0,1023,0,100);
  int f = digitalRead(forwardmotor1);
  int r = digitalRead(reversemotor1);
  if(f == 1 && r == 0 > 1){
   motor1.setSpeed(RPM);
    motor1.step(1);
    delay(.01);
  }
  if(r == 1 && f== 0 &&RPM > 1){
   motor1.setSpeed(RPM);
    motor1.step(-1);
    delay(.01);
 }
 delay(5);
 int Speed2 = analogRead(A1);
 int RPM2 = map(Speed, 0,1023,0,100);
 int f2 = digitalRead(forwardmotor2);
 int r2 = digitalRead(reversemotor2);
 if(f2 == 1 && r2 == 0 > 1){
   motor2. setSpeed(RPM2);
   motor2. step(1);
    delay(.01);
 }
  if(r2 == 1 && f2 == 0 &&RPM2 > 1){
    motor2.setSpeed(RPM2);
    motor2.step(-1);
    delay(.01);
       }
}