Variable speed stepper

Hi all, i am working on a project, this is literally my first one so i dont know very much! I dont know how to use libraries yet or anything so go easy.
I want an arduino uno driving an a4988 running a nema 17.
I want a 3 pos switch, A position runs at a constant 8-10 rpm. B position is off, C position is a variable input 0-like maybe 300 rpm using a 1k pot.
I have this so far, with the help of Ai, but the problem im having is, while it works, in the fixed speed it isnt the correct speed. In variable speed, the pot controls it but it almost looks like from 50% and up there is no increase in speed.

// ----- Pin Definitions -----

const int stepPin = 3;       // STEP pin for the driver

const int dirPin = 4;        // DIR pin for direction

const int switchPinA = 5;    // Position A (constant speed)

const int switchPinC = 6;    // Position C (variable speed)

const int analogSpeedPin = A0; // Analog pin for variable speed

 

// ----- Motor Settings -----

const int stepsPerRevolution = 200;

const int fixedSpeedSPM = 800; // steps per minute

const int maxSpeedSPM = 20000;

 

// ----- Derived Constants -----

const int fixedDelayMicros = 60000000L / fixedSpeedSPM; // microseconds between steps

 

// ----- Variables -----

unsigned long lastStepTime = 0;

int stepState = LOW;

 

void setup() {

  pinMode(stepPin, OUTPUT);

  pinMode(dirPin, OUTPUT);

  pinMode(switchPinA, INPUT_PULLUP);

  pinMode(switchPinC, INPUT_PULLUP);

  pinMode(analogSpeedPin, INPUT);

 

  digitalWrite(dirPin, HIGH); // Choose direction (adjust if needed)

  Serial.begin(9600);

}

 

void loop() {

  bool isPositionA = digitalRead(switchPinA) == LOW;

  bool isPositionC = digitalRead(switchPinC) == LOW;

  Serial.println(isPositionA);

  Serial.println(isPositionC);

 

  unsigned long stepDelayMicros;

 

  if (isPositionA) {

    // Constant speed mode

    stepDelayMicros = fixedDelayMicros;

  } else if (isPositionC) {

    // Variable speed mode

    int analogValue = analogRead(analogSpeedPin);

    float speedSPM = map(analogValue, 0, 1023, 0, maxSpeedSPM);

    if (speedSPM < 1) return; // avoid divide by zero

    stepDelayMicros = 60000000L / speedSPM;

    Serial.println(speedSPM);

  } else {

    // Position B (off)

    return;

  }

 

  // Step timing

  unsigned long currentMicros = micros();

  if (currentMicros - lastStepTime >= stepDelayMicros) {

    lastStepTime = currentMicros;

    digitalWrite(stepPin, HIGH);

    delayMicroseconds(2);  // STEP pulse width

    digitalWrite(stepPin, LOW);

  }

}

TIA!!

const int fixedDelayMicros = 60000000L / fixedSpeedSPM;

  • 75,000 will this fit in an integer :thinking:

Unfortunately i dont know how to answer that.

I should say, i understand what you're saying. The equation yields 75000, which is above the interger value of 32767..
As i said this was written with ai and a few adjustments. The problem is i dont know how to fix it!

Almost all 3 pos switches will have an open, no connection position, between the real connection positions. How will your program react to a no-connection situation as you move the switch?

I believe that is satisfied when there is no a or c position, even if not, having the switch in variable position with bo input will be ok

AI can't do simple math, and you expect it to complete your homework? If the homework is not passing, does AI fail the class or do you? Dump AI. Review classroom material. Learn (research and read about) each line of your program until you understand it. You learned how to walk, talk, read, write, and many more things since you were born. Programming is just another one of those things.

I am learning, this is something i need done sooner than later which is why im asking the people who thought would know for help. Also not something i will be doing a ton of. If i was looking for a "read the book" answer, i just wouldn't have asked.

I agree with @xfpd , you should understand "your" work. I would also recommend you learn how to draw a proper annotated schematic, that would make it much easier to explain what you are doing. What you have told us so far is NEMA 17 steppers have a 1.7 x 1.7 inch faceplate. That narrows it down to just a lot of motors.

In programming, uint (unsigned integer) variables can have different bit sizes, commonly 8, 16, 32, or 64 bits, depending on the specific type used (like uint8, uint16, uint32, or uint64). The number of bits determines the range of values that can be stored, with each additional bit doubling the maximum value that can be represented.

This link should help. Integral numeric types | Microsoft Learn

From the above you should realize we cannot answer your question will an integer hold that number, it is dependent on the processor.

This is from: C - Type - What are uint8_t, uint16_t, uint32_t and uint64_t? | BadproG.com

// testValue
unsigned long long testValue     = 0xFFFFFFFFFFFFFFFF; // 18446744073709551615

// 1 byte -> [0-255] or [0x00-0xFF]
uint8_t         number8     = testValue; // 255
unsigned char    numberChar    = testValue; // 255

// 2 bytes -> [0-65535] or [0x0000-0xFFFF]
uint16_t         number16     = testValue; // 65535
unsigned short    numberShort    = testValue; // 65535

// 4 bytes -> [0-4294967295] or [0x00000000-0xFFFFFFFF]
uint32_t         number32     = testValue; // 4294967295
unsigned int     numberInt    = testValue; // 4294967295

 // 8 bytes -> [0-18446744073709551615] or [0x0000000000000000-0xFFFFFFFFFFFFFFFF]
uint64_t             number64         = testValue; // 18446744073709551615
unsigned long long     numberLongLong    = testValue; // 18446744073709551615

A byte consists of 8 bits. A word can vary in size, typically being 16, 32, or 64 bits, depending on the computer architecture.

Add a delay after your serial.begin(9600).

Now add messages showing the values where you want to begin debugging your program.

And

  • This does not endear you to us.

Are you demanding I give you one exact, complete answer?

I just cleared my calendar to give you the answers you really need.

I apologize for not wanting to make this my lifes project, i will absolutely get this solved i just thought some people who do this all the time could probably give me an answer in about 60 seconds.. and they wouldnt have to clear their schedule to help. But apparently this forum is just for people who already know everything, and have no interest in doing anything other than patting themselves on the back. So for the people who gave resonable responses thank you. To the rest, i hope you need help with something, and the people who can help you tell you to figure it out for yourself.

Thank you gilshultz, the stepper is a 1.8°, 1.5A, 2.3ohm stepper. I dont know what other info is required.
It appears that it is using 32 bit, as the calculated interger caps at 32767 when i monitor it. Any interger above that goes back down and then negative. Now i can understand how all this is working and what the generated code was trying to accomplish but it isnt right. I just dont know what a better way to approach it would be.

You are insincere.

... and disingenuous.

They did, so I did, and now I can.

Possible, but your text and your code do not agree... Your text says A = 10RPM, B = STOP, C = 1 to 300RPM, but your code says 800RPM - You supplied conflicting information? Assuming 10RPM and a variable 300RPM...

10RPM...
=   10 REV/MIN * 1 MIN/60 SEC
=   10 REV/60 SEC * 200 STEP/REV
=   33 STEP/SEC (30mSEC/STEP)
==========
300RPM...
=  300 REV/MIN * 1 MIN/60 SEC
=  300 REV/60 SEC * 200 STEP/REV
= 1000 STEP/SEC (1 mSEC/STEP)

The question you should ask is; why did I take a class that I care nothing about, insist others give me their time, attention and work, so I can "check that box" and never look back, or acknowledge the gift. How much effort should one give to someone so ungrateful?

There are so many choices at your fingertips. Why would you surf into a programming electronics forum and announce you are here unwillingly and want nothing more than an answer... in a minute?

...incorrect... Read again.

Yes i was wrong, 16 bit.

Noone said i took a class? I am interested in this as i like to tinker. But i am also a hands on learner not a book study learner. And i have something im trying to accomplish in a short time. So i asked for help. Sorry that was too much trouble for you. Sonce i figured it out in 2 days myself it should have been pretty easy for someone who is so perfect. You also could have literally helped out in less time than it took you to be a douche but i guess that shows where your priorities are. Also i am very appreciative to anyone that helps me

Me, too, and I am a horrible reader, but you need to dance with the devil.

Thank you for noting I am "literally" a shower of assistance. While you are focused on the immediate, I focus on long term. I know you will not thank me later for showing you to the light, because you are not the first who "want it now!" to whom I have proven delayed gratification is far more valuable than instant results.

One day you will see the forest for the trees.

You are welcome.

In my opinion, these are nothing more than excuses not to read books.

By learning only "by hands" you can remember how to do things, but you will never understand why you need to do them this way and not another. This is not knowledge, it is more like training. Once the conditions of the problem changes a little - and you, with your experience of working with your hands - are again at a dead end. You need someone's help again.
In contrast, someone who has an understanding of the basic principles can develop solutions in new situations without outside help.