Jomelo / LCDMenuLib

Create a tree menu. Use it with different lcd types / console output / ssh console.
http://forum.arduino.cc/index.php?topic=73816.0
MIT License
143 stars 48 forks source link

AccelStepper library #38

Closed ghost closed 3 years ago

ghost commented 7 years ago

I am using AccelStepper library and have a function in LCDML_FUNC_DISP that calls for run stepper motor but it runs very slowly and i see it it Serial Monitor updating date 1 second a second Does void LCDML_DISP_loop updates 1 second at a time?

Jomelo commented 7 years ago

The updatetime is set in the main tab to 1000UL millisecounds. The display function is not for steppers, you can call the stepper update function from the main loop. I have an example for steppers, pleased open it.

Jomelo commented 7 years ago

https://github.com/Jomelo/LCDMenuLib/tree/master/examples/AVR/LCDML_DISP/LCDML_stepper_serialmonitor

I set the first backend function to 0 ms and change the return value to check the other backend function. When the return value is set to default, only the first function is called, because the call condetion is true.

ghost commented 7 years ago

Hello, thank you for your attention, i dont get it, the backend tab is where the stepper run? can i have the functions do run there? i am trying to set them with a LCD menu

// LCDMenuLib_add(id, group, prev_layer_element, new_element_num, lang_char_array, callback_function) LCDML_DISP_init(_LCDML_DISP_cnt); LCDML_DISP_add (0 , _LCDML_G1 , LCDML_root , 1 , "Manual" , LCDML_FUNC); LCDML_DISP_add (1 , _LCDML_G1 , LCDML_root_1 , 1 , "Manual" , LCDML_FUNC); LCDML_DISP_add (2 , _LCDML_G1 , LCDML_root_1 , 2 , "ON" , LCDML_FUNC_MANUAL_ON); LCDML_DISP_add (3 , _LCDML_G1 , LCDML_root_1 , 3 , "OFF" , LCDML_FUNC_MANUAL_OFF); LCDML_DISP_add (4 , _LCDML_G1 , LCDML_root_1 , 4 , "Back" , LCDML_FUNC_back); LCDML_DISP_createMenu(_LCDML_DISP_cnt);

` // void LCDML_DISP_setup(LCDML_FUNC_MANUAL_ON) // { stepper1.setEnablePin(enableDriver); g_button_value = 0;

// lcd setup content lcd.setCursor(0, 0); lcd.print(F("MANUAL ON")); lcd.setCursor(0, 1); lcd.print(F("INDEX SPD:")); lcd.setCursor(0, 3); lcd.print(F("TIME:")); lcd.setCursor(6, 3); lcd.print(F("0.00")); lcd.setCursor(16, 3); lcd.print(F("m.s")); lcd.setCursor(11, 1); lcd.print(g_button_value); //lcd.blink();

checkstate = false;

//LCDML_DISP_triggerMenu(1);

}

void LCDML_DISP_loop(LCDML_FUNC_MANUAL_ON) {
//check loop Serial.println("check loop");

if (LCDML_BUTTON_checkAny()) // check if any button is pressed (enter, up, down, left, right) { if (LCDML_BUTTON_checkLeft() || LCDML_BUTTON_checkUp()) { LCDML_BUTTON_resetLeft(); // reset LCDML_BUTTON_resetUp(); // reset
--g_button_value; g_button_value_interval_check(); menu_manual_on_lcd_update();

}    

if (LCDML_BUTTON_checkRight() || LCDML_BUTTON_checkDown()) 
{
  LCDML_BUTTON_resetRight(); // reset
  LCDML_BUTTON_resetDown(); // reset 
  ++g_button_value;
  g_button_value_interval_check();
  menu_manual_on_lcd_update();

}

}

if ( LCDML_BUTTON_checkEnter() ){ delay(250); Serial.println("LCDML_BUTTON_checkEnter");

checkstate = true;
while ( checkstate == true ){
  runStepper1();

  Serial.println("");
  Serial.print("ENCODER:"); Serial.print(g_button_value);
  Serial.print("\t");
  Serial.print("SPEED:"); Serial.print(stepper1.speed());
  Serial.print("\t");
  Serial.print("POSITION:"); Serial.print(stepper1.currentPosition());

  if ( digitalRead(35) == 0 ){        
   checkstate = false; 
   stepper1.stop();
   Serial.println("");
   Serial.println("STOP");
   LCDML_DISP_funcend();
  }
}

} `

this what i have tks

Jomelo commented 7 years ago

Can you open the example which i have linked above? Try to remove all delay functions from your code. Any delay destroys your stepper movement.

ghost commented 7 years ago

Hi, thank you, i am changing the stepper motors functions to the BACKEND and stick with the LCD Yes i will delete the delays. One problem that i had and i had to use "if ( digitalRead(35) == 0" because the encoder button did not respond to LCDML_BUTTON_checkEnter like before. Did i miss something? can you explain the encoder KEYWORDS?

Jomelo commented 7 years ago

Have you enable the pullup resistor? Have you an extern pullup ? I cannot explain all at the moment i have no pc here (only handy) :-)

ghost commented 7 years ago

yes INPUT_PULLUP, but the encoder does not get accurate readings, it skips steps (its the problem of not using interrupts) Do you think is better to have the stepper run functions in the main loop? in main ino file?

here! void loop() { // this function must called here, do not delete it LCDML_run(_LCDML_priority); stepper1CurrentSpeed = stepper1SpeedArray[abs(g_button_value)]; stepper1.setMaxSpeed(stepper1CurrentSpeed); stepper1.run(); }

Jomelo commented 7 years ago

Try to set the loop time for this backend function to 5UL ms. The old value is 20UL. (0UL dont work) The encoder need a small loop time. If you get realy fast rotations, you have to work with interrupts.

ghost commented 7 years ago

i did not had the opportunity to teste, but in another project if the stepper motor was running and if i turned the nob to set a new speed or update serial or the lcd, the stepper motor stall for one step like it had to stop running for doing another thing; does your menu library does the same? in fact, it must do it, this is a microcontroller, not a microprocessor, i am right?

sgryb commented 7 years ago

Hi @paulosilver , you may find a code for CONTROL WITH ENCODER section for Encoder based on pin change interrupt (using RoraryEncoder library) in this branch (so far - the last message) https://github.com/Jomelo/LCDMenuLib/issues/14#issuecomment-337031257 There are no delays used there. Hope, it would help...

Jomelo commented 7 years ago

The problem is that delays occur during the update of the display depending on the display type (interface standard). The library tries to update the display only if something changes.

Each stepper motor needs a fix interwall ("hard real-time"). Any interruption of the interval will result in a non-clean movement.

Option 1: Alternatively, you can customize your program so that the menu is only updated when the stepper reaches an end point or the direction of rotation has changed.

Option 2: You can use a larger microcontroller with more resources and install a real-time operation system (for example free-rtos). The real-time operation system have a scheduler witch allows to release hard real-time for some tasks. http://www.freertos.org/implementation/a00005.html https://exploreembedded.com/wiki/Setting_Up_FreeRTOS_on_Arduino

ghost commented 6 years ago

hello again, option 1, question: loop inside menu lcd function, if it does not update the LCD does not miss any steeps? or there is any cycle there?

Jomelo commented 6 years ago

It is possible but not the fine way :-)