Notifications
Clear all

Arduino based function to control stepper motors

43 Posts
6 Users
3 Likes
2,758 Views
 Kirk
(@kirk)
Member
Joined: 3 years ago
Posts: 23
Topic starter  

My question relates to using functions to control stepper motors. I wrote a program which is attached that uses a a function to have a stepper motor open a shutter for a light beam to pass through. The program includes a sensor (photoresistor) that detects light intensity and quantifies it to a number and assigns it to a variable (sensorMin). The variable is then tested using a Switch statement. If light intensity is low; I have programmed Case 1 to report the value and a message ("obstruction in light path") and activate a function to have the stepper motor close the shutter. Case 2 just reports a value of the measured light intensity.

The issue or problem is that the same stepper motor is receiving a clockwise motion instruction to open the shutter from one part of the code and a counterclockwise instruction to close the shutter from another part of the code. The open shutter command is in one function (Stepper1A) and the close shutter command is in another function (Stepper1B).They are separated in the code by a delay command (1000).

 After running the program once, neither function worked and I am suspecting a damaged driver (ULN2003) or motor (NEMA 11, CX28BYJ48-5V).  I declared all my constants in each function separately.

I hope that makes sense. I have credited the Forum for the basic stepper instructions. Let me know if there are questions. 

 


   
Quote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2528
 

@kirk

Please repost the sketch as an Arduino sketch instead of a Word document, thanks.

 

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 
Posted by: @will

@kirk

Please repost the sketch as an Arduino sketch instead of a Word document, thanks. 

Although I agree with @will about using the supplied code button...

image

...I had more problems with the K&R formatting.  But that is a pet-peeve I'll get over someday... NOT!  😆 

 

I brought your code from MS Word into a real editor to look it over...

The main problem is you are defining the stepper object (line 174 & 212) within the Stepper1A() method and gets run on the stack every time.  This should be created once at the top and only accessed within your loops.  

There may/may not be other problems, but give that a try and see where it leads.  Please report back  your success... or give details about new "bad" symptons.

VBR,

Inq

P.S.  If you find these steppers wanting... I just had an opportunity to mess with these: (ULN2003) or motor (NEMA 11, CX28BYJ48-5V) in a couple of projects.

  • About to throw them out as useless, I was willing to hack on them.  In the second project. I found a hack to make them into standard 4 wire  steppers:   https://www.instructables.com/28BYJ-48-5V-Stepper-Motor-and-A4988-Driver/ and use a $1.50 A4988 motor driver common to 3D printers.  I was able to reduce the current down to the point that they didn't burn me when touched.  Even at that low current, I could not stop them with my fingers.  The torque was tremendous!

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
 Kirk
(@kirk)
Member
Joined: 3 years ago
Posts: 23
Topic starter  

@inq 

Thanks. I  will try your suggestion. I will repost the Arduino (ino) file as well and get back to you.


   
ReplyQuote
 Kirk
(@kirk)
Member
Joined: 3 years ago
Posts: 23
Topic starter  

@inq 

Hi thanks for your advice. I reposted my sketch as a reply to Will's first comment and formatted it.

I have ordered another driver and stepper motor through Mouser and expect them August 2nd.  Then I'll plug everything in using the coding changes that you recommended and see what happens. You had good suggestions for a different motor or driver. I was wondering about that myself and may look into that next month.  I'll post an update next week/month.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@kirk

Posted by: @kirk

@inq 

Hi thanks for your advice. I reposted my sketch as a reply to Will's first comment and formatted it.

I have ordered another driver and stepper motor through Mouser and expect them August 2nd.  Then I'll plug everything in using the coding changes that you recommended and see what happens. You had good suggestions for a different motor or driver. I was wondering about that myself and may look into that next month.  I'll post an update next week/month.

I can't see your reposted sketch?


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2528
 
Posted by: @kirk

@inq 

Hi thanks for your advice. I reposted my sketch as a reply to Will's first comment and formatted it.

Where did you post it ?

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
 Kirk
(@kirk)
Member
Joined: 3 years ago
Posts: 23
Topic starter  

@will 

Motor Test_M3_72522

 

[code]

 

 

 

 

// Motor Test_M3_72522

//compiled: 7/24/22 Tests:7/24/22 with M3+ ->ok,7/25 M3- --> board failure

 

 

// stepper code credits:

// DroneBot Workshop 2018

// https://dronebotworkshop.com

 

// LIBRARIES

#include "Arduino.h"

#include <Stepper.h>

 

 

// CONSTANTS

 

// Constants for switch and sensor

 

const int Switch = 12; //The input pin where the

//switch is connected

const int analogPin = A0;

int analogValue = 0;

int photocellReading;

 

int sensorValue;

int sensorMin = 1260;

int sensor1 = 0;

 

 

// constants for stepper motor ULN2003 driver //Constants placed inside the functions

 

// Number of steps per internal motor revolution

//const float STEPS_PER_REV = 32;

// Amount of gear reduction

//const float GEAR_RED = 64;

// Number of steps per geared output rotation

//const float STEPS_PER_OUT_REV = STEPS_PER_REV * GEAR_RED;

 

int val = 0;

int k=0;

 

 

void setup() {

 

// Setup code for Serial programing

Serial.begin (9600);

 

 

// Setup Code for Switch and Sensor

 

pinMode(Switch, INPUT); //and SWITCH is an input (digital pin 12).

pinMode (analogPin, INPUT); // A0 is used for analog input (Serial Monitor used)

 

 

 

 

//Function call and setup (4 functions)

 

//Stepper motor model 28BYJ-48, NEMA 11, ULN2003 controller

 

//Stepper1A() // M3 Shutter open

// Stepper1B() //M3 Shutter close

 

 

 

}

 

 

void loop() {

 

while (digitalRead(Switch) == LOW) {

//DO NOTHING

//Serial.print ("Switch= ");

//Serial.println( Switch);

 

}

// else start the program

 

Stepper1A();

Serial.print("k= ");

Serial.println (k);

 

// Acquire analog reading from A0 and check alarm status

analogValue = analogRead(analogPin);

// Instruction to invert reading

photocellReading = 1023 - analogValue;

Serial.print ("photocellReading ");

Serial.println (photocellReading); //Low light level ~ 0

sensorMin= photocellReading;

delay (1000);

 

Serial.print ("sensorMin= ");

Serial.println (sensorMin, DEC);

 

if (sensorMin < 20) { //smoke or obstruction of sensor

sensor1 = 1;}

 

else sensor1 = 2;

 

switch (sensor1) {

case 1:

Serial.print( "sensorMin= ");

Serial.println (sensorMin);

Serial.print ("sensor1= ");

Serial.println(sensor1);

Serial.print("Obstruction in Light Path");

Stepper1B();

 

Serial.print ("End of Case 1 ");

delay (10000);

break;

 

 

 

case 2:

//For other motor options and test of sensor

Serial.print("sensorMin ");

Serial.println (sensorMin);

Serial.print ("sensor1 ");

Serial.println (sensor1);

Serial.print ("Case 2 ");

delay(1000);

break;

}

Serial.print ("End Program ");

Serial.print ( "k = ");

// Timing loop

for (int k=0; k<100;k++) {

Serial.println (k);

delay (1000);

}

 

}

 

 

 

// STEPPER FUNCTION M3 SHUTTER // divide M3 cw and M3 ccw___7/09__

/*

Stepper motor M3 Shutter

Uses 28BYJ-48 Unipolar stepper with ULN2003 Darlington driver

Uses Arduino Stepper Library

*/

 

 

void Stepper1A () { //Open Shutter

// Define Variables

//review and consider break statement

 

// Number of Steps Required

int StepsRequired;

 

 

//Create Instance of Stepper Class

//Specify Pins Used for Motor Coils

//The Pins Used are 8,9,10,11

// Connected to the ULN2003 Motor Driver In1, In2, In3, In4

// Pins entered in sequence 1-3-2-4 for proper step sequencing

 

// constants for stepper motors

// Number of steps per internal motor revolution

const float STEPS_PER_REV = 32;

// Amount of gear reduction

const float GEAR_RED = 64;

// Number of steps per geared output rotation

const float STEPS_PER_OUT_REV = STEPS_PER_REV * GEAR_RED;

 

 

Stepper steppermotor(STEPS_PER_REV, 8, 10, 9, 11);

 

 

//Slow- 4 step CW sequence to observe lights on Driver Board. edit 6/30/20 slow CW and CCW, 2000 ms delays.

steppermotor.setSpeed(50);

StepsRequired = 5;

steppermotor.step(StepsRequired);

delay(2000);

 

 

// Rotate CW 1/4 turn slowly

StepsRequired = STEPS_PER_OUT_REV / 5;

steppermotor.setSpeed(50);

steppermotor.step(StepsRequired);

delay (2000);

}

 

void Stepper1B () { //Close Shutter

// Number of Steps Required

int StepsRequired;

 

 

//Create Instance of Stepper Class

//Specify Pins Used for Motor Coils

//The Pins Used are 8,9,10,11

// Connected to the ULN2003 Motor Driver In1, In2, In3, In4

// Pins entered in sequence 1-3-2-4 for proper step sequencing

 

// constants for stepper motors

// Number of steps per internal motor revolution

const float STEPS_PER_REV = 32;

// Amount of gear reduction

const float GEAR_RED = 64;

// Number of steps per geared output rotation

const float STEPS_PER_OUT_REV = STEPS_PER_REV * GEAR_RED;

 

 

 

Stepper steppermotor(STEPS_PER_REV, 8, 10, 9, 11);

 

steppermotor.setSpeed(50);

StepsRequired = 5;

steppermotor.step(StepsRequired);

delay(2000);

 

 

//RotateCCW 1/4 turn slowly, NOTE NEGATIVE SIGN BELOW separate function


   
ReplyQuote
 Kirk
(@kirk)
Member
Joined: 3 years ago
Posts: 23
Topic starter  

   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2528
 

@kirk 

Both attempts appear to be incomplete and/or broken.

Also you have not extracted the stepper definition and initialization to the setup() section as you were advised to do by inq.

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 
Posted by: @will

@kirk 

Both attempts appear to be incomplete and/or broken.

Also you have not extracted the stepper definition and initialization to the setup() section as you were advised to do by inq.

I consider it a flattery when anyone actually responds to my posts.  🤣  And maybe I'm senile, but I don't remember advising anyone to do anything... but I sure find it comical after happy hour!

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2528
 
Posted by: @inq

[snipt]

I brought your code from MS Word into a real editor to look it over...

The main problem is you are defining the stepper object (line 174 & 212) within the Stepper1A() method and gets run on the stack every time.  This should be created once at the top and only accessed within your loops.  

There may/may not be other problems, but give that a try and see where it leads.  Please report back  your success... or give details about new "bad" symptons.

VBR,

Inq

[snipt]

The bold section is what I was referring to ...

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
 Kirk
(@kirk)
Member
Joined: 3 years ago
Posts: 23
Topic starter  

   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2528
 

@kirk 

Attached is an updated and properly formatted version of the sketch you included. Have removed several hectares of blank space so that the program flow can be seen more easily without having to continually drag the text up and down.

It isn't clear from either the comments nor the code what you're trying to do, so I'll just go over a few parts at a time.

1) in setup() you appear to be setting up the stepper motor. However, before you even set set a speed value for it, you declare an int called StepsRequired (for what ?) and move the stepper those 5 steps. Why are you repositioning the stepper by 5 steps before you even complete initializing it.

2) in Stepper1A you again declare StepsRequired and assign it a value of 5 and ten move the stepper 5 steps. After a delay of 20 ms, you reset StepsRequired to be STEPS_PER_OUT_REV / 5, then delay another 20 ms and return. What were you intending this module to do for you ?

3) in Stepper1B you repeat the assignment of 5 to StepsRequired and then move 5 steps but the time with no delay. You then reassign StepsRequired = -STEPS_PER_OUT_REV / 5 and then move the stepper backwards with a final delay of 200 ms again. What were you intending this module to do for you.

 

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
Inq
 Inq
(@inq)
Member
Joined: 2 years ago
Posts: 1900
 
Posted by: @will

Attached is an updated and properly formatted version of the sketch you included. Have removed several hectares of blank space so that the program flow can be seen more easily without having to continually drag the text up and down.

Thanks @will.  At least your version is readable.

@kirk - I happen to have the same driver/stepper your using and I wired them up and loaded your Sketch.  I'm going to re-iterate @will observations for completeness.    

  1. In the setup() method, you need to setSpeed() before you command it to move using step().  I can't think of a purpose doing it the way you had it.  Nothing happens.
  2. Still in the setup() moving 5 steps is less than a degree or rotation.  5/2048*360 = 0.88 degrees.  Are you sure this is what you intended?  I bumped it up to 100 so I could actually see it move.
  3. Stepper1A gets called first in the loop().  Again you "open shutter" less than 1 degree.  Maybe that is what you intend???  The second assignment to StepsRequired does nothing, it's not used.
  4. I don't understand why you reassign values so much...  Get analogValue, flip it for photocellReading, reassign to sensorMin, set some flag sensor1, then switch on it.  Maybe you have far bigger plans for it, but it makes your code very hard to read for no apparent reason.

After really digging into it, I imagine your stepper/driver are fine.  You just haven't commanded it to hardly do anything.  I'll put in English what your code is doing... in the loop.

  1. It "opens the shutter" 0.88 degrees.
  2. It reads your photocell reading.
  3. Waits 1 second.
  4. ONLY, if the sensor reading is below 20, 
    1. It opens the shutter 0.88 degrees more.
    2. Then, closes it by 72 degrees.
    3. Wait 10 seconds
  5. Waits 100 seconds 
  6. Repeats the loop.'

IOW, if the sensor is above 20, you'll never see it move.  Is this what you intend?

 

 

 

3 lines of code = InqPortal = Complete IoT, App, Web Server w/ GUI Admin Client, WiFi Manager, Drag & Drop File Manager, OTA, Performance Metrics, Web Socket Comms, Easy App API, All running on ESP8266...
Even usable on ESP-01S - Quickest Start Guide


   
ReplyQuote
Page 1 / 3