Moving 28byj-48 via serial as poor man limits switches

Hello!

I want to start off by saying i'm a total noob in way over my head.

I'm controlling (learning how) a clock I designed with 9x 28byj-48 - ULN2003 1x NEMA 17 with an Arduino MEGA.

I will someday use limit switches for each motor. I'm trying to simplify anything I can to continue testing the mechanical parts associated with the motors.

Long story short I would like to position each motor individually via serial to the correct starting position - Then start the program

Below is a program I found to control 1 motor. How hard will it be to modify this to control my 9 motors? I could not find an example with 2 motors otherwise I'd be able to hack it together. I also can't get negative values to work.

Feel free to recommend different styles or programs then what I have mentioned.

//define pin numbers
#define IN1  8
#define IN2  9
#define IN3  10
#define IN4  11

int ang = 0;
//for the delay
int mils = 1;

void setup() {

  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  Serial.begin(9600);


}

void loop() {
  // Read input from serial Monitor if available
  if (Serial.available()) {
    ang = Serial.parseInt();
    Serial.println("Read " + String(ang) + " degrees");
    rotate(ang);
  }

}

void rotate(int angle)
{
  int numberOfRounds = (int) angle * 1.42222; // angle*512/360
  for (int i = 0; i < numberOfRounds; i++) {

    //1000
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    delay(mils);

    //1100
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0100
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0110
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0011
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, HIGH);
    delay(mils);

    //0010
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0001
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
    delay(mils);

    //1001
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
    delay(mils);


  }
  // Switch off all phases
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
}

Thank you in advanced,

-Grant

When you Serial.print(numberOfRounds); What do you get?

Thanks for your quick response Paul. Sorry I'm very green with this.

Were do I put Serial.print(numberOfRounds); and what do I do?

In the program or serial? Total noob sorry

Why? Why not "warm up" with easy example matters? This business is not at all "plug and paly".

Start by making the Serial.read work well.
Then just make the stepper move "here and there" according to a stepper test code.

If You cut out the NEMA 17 I can approve the combination of stepper and driver assuming the power supply is the right one regarding voltage.

Good approach taking one step at the time.

Make one stepper move first. Then it will not be difficult to expand into more.

Thanks for the advice Railroader. I've gone through the starter kit examples. I have 9x motors wired and running forward and backwards. I have not messed with the NEMA 17 yet. Its a giant birds nest of wires!

I'm needing help bridging the knowledge between examples and real life uses.

The code I provided works for 1 motor. (But you are correct I cant get it to go backwards, so its not fully working for 1)

If its not difficult to expand could you please explain how?

Thanks you,

-Grant

Not a problem. The question is in what direction You want to go.
I suggest running only one stepper and adding the limit switch.

Running 9 steppers You would likely need to use a library like Accelstepper. Multiplying Your code for 9 steppers might give a slow response. That question later.

You could surely crank up the baudrate in serial to 115200. Do it in Serial.begin an in serial monitor.
Read the code You use and try to figure out how each line works, what it does.

Good. Most likely that stepper needs a driver controlling the current to the stepper and that's not done in the more than stone age technology ULN2003.

So my goal is to get the program

//define pin numbers
#define IN1  8
#define IN2  9
#define IN3  10
#define IN4  11

int ang = 0;
//for the delay
int mils = 1;

void setup() {

  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  Serial.begin(9600);


}

void loop() {
  // Read input from serial Monitor if available
  if (Serial.available()) {
    ang = Serial.parseInt();
    Serial.println("Read " + String(ang) + " degrees");
    rotate(ang);
  }

}

void rotate(int angle)
{
  int numberOfRounds = (int) angle * 1.42222; // angle*512/360
  for (int i = 0; i < numberOfRounds; i++) {

    //1000
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    delay(mils);

    //1100
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0100
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0110
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0011
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, HIGH);
    delay(mils);

    //0010
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0001
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
    delay(mils);

    //1001
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
    delay(mils);


  }
  // Switch off all phases
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
}

To work with many steppers. Right now I can only type in 1 positive angle and the stepper moves that amount. In a perfect world I would like to be able to do this with all 9 steppers. in serial type "Motor 9 - 15" or something like that to be able to control each motor in the + and- direction.

I use accelstepper to move the motors in the program.

Between the two lines I quoted. That way you know what you are working with.

https://forum.arduino.cc/t/creating-the-bmw-kinetic-sculpture/670206/178

Wow thanks!

Paul,

Once I have added the code and I type in a negative (-100) number I see

Read -100 degrees
-142Read 0 degrees
0

Any suggestions?

Thanks,

-Grant

Well, when you coded =(int) angle * 1.42222;
You create a NEW angle variable. Don't put the (int) in front of angle and you will use the one being provided when the function is called.

Paul,

I removed the (int) from before the angle. I'm still not getting any movement from negitive numbers.

I typed -20
Read -200 degrees
-28Read 0 degrees
0

//define pin numbers
#define IN1  8
#define IN2  9
#define IN3  10
#define IN4  11

int ang = 0;
//for the delay
int mils = 1;

void setup() {

  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  Serial.begin(9600);


}

void loop() {
  // Read input from serial Monitor if available
  if (Serial.available()) {
    ang = Serial.parseInt();
    Serial.println("Read " + String(ang) + " degrees");
    rotate(ang);
  }

}

void rotate(int angle)
{
  int numberOfRounds = (int) angle * 1.42222; // angle*512/360
  Serial.print(numberOfRounds);
  for (int i = 0; i < numberOfRounds; i++) {

    //1000
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    delay(mils);

    //1100
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0100
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0110
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0011
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, HIGH);
    delay(mils);

    //0010
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    delay(mils);

    //0001
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
    delay(mils);

    //1001
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, LOW);
    digitalWrite(IN4, HIGH);
    delay(mils);


  }
  // Switch off all phases
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
}

Any ideas?

Thanks,

-Grant

Which motor is that?
Common 28BYJ-48 motors have (about) 2048 steps per revolution.
The only one I know off with about 512 steps is the one from Adafruit (516.096/rev), so the value should be 1.4336
Or did you use more gear reduction.

Did you see in the link I gave you that I have used TPIC6B595 power shift registers instead of ULN2003 boards. One per two motors. Then you can even use a common Nano.

Adding input shift registers for limit switches to the chain could be another option.
Leo..

You still have the (int) in front of angle.
You only ever need to tell the compiler that angle is an int one time when you first define it. That applies to ALL variables. The compiler is smart enough to know what the variable is.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.