Random Movement in CustomEventsImpl.h problem with String and PSTR

I make a plotter with Repetier.
The plotter shall make just radomly dots in an area.

my idea:
void Custom_500MS()
 {
  //in random mode Plotter checks Buffer if the buffer is smaller than 5, then start new commands for dot
  if (Plotter::RandomMode>0 and PrintLine::linesCount < 5 ){
    PlotRandomMode();
  }
}

//function
void PlotRandomMode() {
  //plotterstart
  if (Plotter::RandomMode ==1){
    GCode::executeFString(PSTR("M5"));
    GCode::executeFString(PSTR("G28"));
    GCode::executeFString(PSTR("G90")); //absolut
    Plotter::RandomMode = 2;
  }
  //punkt suchen
    float x=random(100000);float y=random(100000); //x,y plot area by 1000
    x=x/1000; y=y/1000;
    PlotMuster(x,y);
}

// plotter just pendown and penup
void PlotMuster(float x, float y) {
    String temp="G1 X" + String(x,3) + " Y" + String(y,3);
    GCode::executeFString(PSTR(temp)); //<-- here is my problem
    GCode::executeFString(PSTR("M3"));
    //stift absetzen also nur punkt machen - just a dot
    delay(100);//100 millisekunden stift untenlassen
    GCode::executeFString(PSTR("M5"));
}

sorry for my poor programming knowledge:
PSTR gives back the pointer
what do I have to do, to bring the String variable temp into the PSTR function??
Thanks for help!

Comments

  • First don't use string. We do not use any dynamic memory allocation in firmware. Better use char array and sprintf instead.

    PSTR ensures the string is stored in flash data section on compilation. You can not use that with dynamic variables!
    Please simply call the proper move command directly:

    Printer::moveToReal(targetX, targetY, IGNORE_COORDINATE, IGNORE_COORDINATE, feedrate);

    that way you also do not need to do any string manipulations at all.
  • arghh ... you are right - why complicated !
    thanks for the tip ...
  • Somehow the Printer::moveToReal has influence on the buffe (is my impression)..
    If I comment the moveToReal command out, then the G28 work as usual.
    (G28 goes to the endstop , moves back a little bit, goes a second time to the end stop, and back again and then the same for Y).
    If I use the moveToReal command, the G28 makes the first move to the endstops and goes back without end. On the display is the value of the moveToReal command. So the G28 works not as usual.
    My impression is that the buffer is corrupt.
    Is it possible that the moveToReal command interfere with the buf of GCode::executeFString?

    I tried to use Commands::waitUntilEndOfAllMoves(); before Printer::moveToReal, but this did not change the situation.
    Thanks for help!



  • executeFString executes a complete action and only then returns. Since G28 includes many waitUntilEndOfAllMoves these moves should finish before returning.

    Maybe add after
    Plotter::RandomMode = 2;
    a
    Com::printFLN(PSTR("now homed"));

    to see if it was finished at all.

    One problem is that you call such a long operation in 500ms timer. It might get called several times with bad result. Make a protection to return if mode is 100 and set mode 100 until the 3 commands around homing are finished so reentered cases are ignored instead of adding commands between.
  • Make a protection to return if mode is 100 and set mode 100 until the 3 commands around homing are finished so reentered cases are ignored instead of adding commands between.
    I do only understand half of your comment.
    I got your point, that I start the commands before they are finished.
    that is the disadavantage of Custom_500MS, because I call the function every 500ms independent how far it is done.
    Can I find out that a command is just acting?

    I solved it by adding it to the commandloop (and not the 500ms event!) in command.cpp
    the only disadvantage is that now the custom_500ms is not reacting anymore ...
    Do you have an idea??

    ..
    void Commands::commandLoop() {
        while(true) {
    //+++Randomfunktion
      if (Plotter::RandomMode>0 and PrintLine::linesCount < 5 ){
        Plotter::PlotRandomMode();}
        
    #ifdef DEBUG_PRINT
    ...

  • I meant write it like this:
    void PlotRandomMode() {
    if(Plotter::RandomMode == 100) return;
      //plotterstart
      if (Plotter::RandomMode ==1){
    Plotter::RandomMode = 100;
        GCode::executeFString(PSTR("M5"));
        GCode::executeFString(PSTR("G28"));
        GCode::executeFString(PSTR("G90")); //absolut
        Plotter::RandomMode = 2;
      }
      //punkt suchen
        float x=random(100000);float y=random(100000); //x,y plot area by 1000
        x=x/1000; y=y/1000;
        PlotMuster(x,y);
    }

    that should be the best solution here.
  • Now I understand ... the "return" was my lack of understanding.
    It is working perfect now!
    Thanks again...
    (Willich ist zu weit, sonst wüde ich dich zur Vernisage gern nach Nürnberg einladen ...)
Sign In or Register to comment.