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.
Anything seems possible when you don't know what you're talking about.
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...
...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.
- https://forum.dronebotworkshop.com/user-robot-projects/inqling-a-test-mule/paged/3/#post-30623 - I found the ULN2003 (at least mine) drove is at ridiculously low torques. I could easily stop it with my fingers. It and the stepper ran very hot... especially at zero speed. At full speed, they actually ran cooler.
- 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
Thanks. I will try your suggestion. I will repost the Arduino (ino) file as well and get back to you.
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.
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?
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.
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
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.
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
[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.
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.
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.
- 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.
- 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.
- 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.
- 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.
- It "opens the shutter" 0.88 degrees.
- It reads your photocell reading.
- Waits 1 second.
- ONLY, if the sensor reading is below 20,
- It opens the shutter 0.88 degrees more.
- Then, closes it by 72 degrees.
- Wait 10 seconds
- Waits 100 seconds
- 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