Slow method ruins my Program

Good evening and merry christmas to everyone!

I m having some problem with my code, its works as it should but its too slow. ( guess I need other boards with more calculating power cuz all i do for days is thinking about efficiency and not about my projects... :frowning: )

I hope that some genius can figure out how to make it more efficient!

Its not long but especially the last method takes a lot of time to calculate but I dont know any other way to implement it :confused:

Heres the code:

#include <SoftwareSerial.h>
#include <AccelStepper.h>

SoftwareSerial btAdapter (12, 13); //RX TX
AccelStepper stepper(AccelStepper::DRIVER, 9, 8);



String counterString, minuteString;
int minute = 0, counter = 12;
int minuteCounter = 0;
int currentMin = 0;

String HC05_Response = "";

int enableStepper = 10;
int schalter = 2;
int i;
long steps = 5493.4256 * counter;
long millisecs;
boolean _on = false;
boolean _restart = false;
boolean _los = false;
boolean _finish = true;
boolean justOnce = true;
boolean bt_Connected = false;


const long p1 = 5493.4256;
const long p2 = 5493.4256 * 2;
const long p3 =5493.4256 * 3;
const long p4 = 5493.4256 * 4;
const long p5 = 5493.4256 * 5;
const long p6 = 5493.4256 * 6;
const long p7 = 5493.4256 * 7;
const long p8 = 5493.4256* 8;
const long p9 = 5493.4256 * 9;
const long p10 = 5493.4256 * 10;
const long p11 = 5493.4256 * 11;
const long p12 = 5493.4256 * 12;

void setup() {
  pinMode(enableStepper, OUTPUT);
  pinMode(schalter, INPUT_PULLUP);
  btAdapter.begin(9600);



  stepper.setMaxSpeed(1700);
  stepper.setAcceleration(2500);
  stepper.moveTo(-steps);

}

void loop() {
  checkBT();

  if (digitalRead(schalter)) {
    _on = true;

  } else if (atTop(-stepper.currentPosition())) {
    _on = false;
    stepper.setCurrentPosition(0);
    stepper.moveTo(-steps);
    delay(50);
  }

  if (_on == false || stepper.distanceToGo() == 0)digitalWrite(enableStepper, HIGH);
  else digitalWrite(enableStepper, LOW);

  if (!bt_Connected) {

    if (_on == true) {

      stepper.run();
    }


  } else {



    if ( minuteCounter == currentMin + minute && justOnce == false && _finish == true || _los == true) {
      _restart = true;

    }


    if (_restart == true && _on == true ) {
     _finish=false;
      //stepper.moveTo(-steps);
      stepper.run();
      if (stepper.distanceToGo() == 0) {
        _restart = false;
        _los = false;
        _finish = true;
        currentMin = minuteCounter;
        stepper.setCurrentPosition(0);
        delay(50);
      }
    }
  }
}

void checkBT() {
  if (_on == true) {
    millisecs = millis();
    if (millisecs >= 60000 * (minuteCounter + 1)) {
      minuteCounter += 1;
    }
  }

  if (btAdapter.available() > 0) {
    bt_Connected = true;

    char c = btAdapter.read();
    HC05_Response += c;
    if (HC05_Response.length() == 1 && HC05_Response.charAt(0) == 'a') {
      HC05_Response = "";
    }
    if (HC05_Response.length() == 11 && HC05_Response.charAt(0) == 'S'
        && HC05_Response.charAt(10) == 'E') {

      _los = true;

      minuteString = HC05_Response.substring(2, 5);
      counterString = HC05_Response.substring(6, 9);

      minute = minuteString.toInt() - 100;
      counter = counterString.toInt() - 100;
      if (minute == 0)justOnce = true;
      else justOnce = false;
      steps = 5493.4256 * counter;
      if (stepper.distanceToGo() == 0) {
        stepper.setCurrentPosition(0);
        stepper.moveTo(-steps);
      }

      HC05_Response = "";
    }

  }
}

bool atTop(long pos) {

  bool b = false;
  if (pos == 0 || pos == p1 || pos == p2 || pos == p3 || pos == p4 || pos == p5 || pos == p6 || pos == p7
      || pos == p8 || pos == p9 || pos == p10 || pos == p11 || pos == p12)b = true;
  return b;

}

thanks a lot as allways!

Greetings from Germany,

RWTH_MASCHI

const long p1 = 5493.4256;Please be sensible

  • in that long "if" string, try putting the "||" conditions most likely to be true, first.
    Fröhliche Weihnachten :slight_smile:

What do u mean @AWOL? it has to be such a big number and it gets rounded anyway.. or am I wrong?

and in the "if" string.. everything is equally likely- its there to stop the motor if its at the "top" and not when the switch is turned off...

i dont rly know what to do :confused:

it has to be such a big number and it gets rounded anyway.

Yes, you're wrong; it gets truncated

RWTH_MASCHI:
I m having some problem with my code, its works as it should but its too slow.

In what way is it too slow? What exactly does it do and what do you want it to do that is different.

I notice that you have some delay()s which can't be helping.

Also you should just need to call stepper.run() once - perhaps as the last thing in loop(). It should not be inside any other conditional clauses.

And, as others have said, trying to put floating point values into integer variables is silly.

...R

its too slow because it begins to slow the stepper down when its running, because of calculations etc.

the program works this way:

  1. if BTDevice is not connected: if the switch (schalter in my program) get activated: the stepper does exactly 12 revolutions. if switch gets deactivated after e.g. 4 revolutions, it continues to run until it hits the spot it began on ( in my case at the "top" -> method atTop) so it did 5 full rotations and gets reset so when activated it does 12 rounds again if not stopped in the meanwhile.

  2. if BTDevice is connected: You can send a timer and a counter. counter tells the program how many revs it should do. (from 1 to 12) and the timer is for repeating the revolutions after eg 2 min.
    if BT is connected the first case will be deactivated.

the delays only get called when the stepper is not running, and they are necessary because if its not delayed its gonna bug around ( took my freaking long to get that i need a delay) so those dont slow my program..

run is also only called once per loop. it depends on if the BT is connected or not

there a lot of boolean stuff going on what might seem weird. but its all necessary in my Opinion. maybe there is a smarter way to do it but i cant figure it out.

maybe theres also a smarter way to write the atTop method without the long if string... cuz thats kinda hard for the program to "calculate".

@AWOL i dont seem to get what u mean, maybe u can explain me what i can do better :slight_smile:

the number is following: 400 steps per Rev( halfstepping)*13.97smth (planetary)

RWTH_MASCHI:
its too slow because it begins to slow the stepper down when its running, because of calculations etc.

Is it slow in every situation or only when you are getting Bluetooth data?

How slow do you mean? How many steps per second?

How fast do you want it to go?

...R

maybe theres also a smarter way to write the atTop method

Maybe there is, but that is not slowing you down significantly. Even if it had to test all 13 conditions in that statement it would still take less than 100 microseconds to do the whole thing. If atTop is true, you then delay for 50 milliseconds which is a lot longer than atTop takes.
You should try to get rid of the delays.

Pete

FYI: I measured how long atTop executes when it has to evaluate all 13 conditions in the 'if' statement. I overestimated it a bit. It takes less than 390 nanoseconds.
I think that is plenty fast for what you are doing and is certainly not ruining your program.

Pete

    if (HC05_Response.length() == 11 && HC05_Response.charAt(0) == 'S'

&& HC05_Response.charAt(10) == 'E') {

What happens if it gets 11 characters but the first one isn't 'S'? Then it never ends. It's always stuck, with the HC05_Response String growing uncontrollably large. Always include a trap to ensure that things don't grow like this. If it gets to 12 and the aboe statement hasn't triggered, you could delete the whole thing and start over, except you may have just missed one character and you're never going to be back in sync with an 'S' in the first position.

The big-S string is slowing you down a bit and chewing up memory but that should not be significant for this program.

The cosntant 5493.4256 appears in a LOT of places in your program. Give it a name and then use that everywhere in your program.

I am not sure yet, i have to test how the fluids behave ( the motor drives a pump made from a syringe to pump booze into shotglases :slight_smile: ) but speed we ll be around 1500-2000 steps per sec and with halfstepping. its not too fast.

and as i said the delay doesnt interfere with the program. it ll just get called if the motor is turned off

ill try to put the long number into a variable as said. thanks for that idea.

i also put it down from quarter stepping to half stepping, so speed is half as high and it has to do less calculations per second what helped also

RWTH_MASCHI:
but speed we ll be around 1500-2000 steps per sec and with halfstepping. its not too fast.

That is very confusing.

Are you saying that it is working at 2000 steps per second?
Are you saying that that is the appropriate speed?

...R

Is this project related to this thread -speeding up my code - Programming Questions - Arduino Forum

If so Better keep the discussion in one place to prevent repetition of question and answers.