Fuction Call from menu (Menwiz)

Ciao,
I would like to call a function from the Menwiz menu:

  s1=menu.addMenu(MW_SUBMENU,r,F("SAW"));                       //add a submenu node 1 to the root menu (control the heigh of my Saw)
  s2=menu.addMenu(MW_VAR,s1,F("ABS Height"));                   //add a terminal node in the menu tree (that is "variable"); (move to a certain mm height)
     s2->addVar(MW_AUTO_INT,&sp,0,100,1);                   //int type, fd binded variable, range 0-100, step 1
        s3=menu.addMenu(MW_VAR,s2,F("moveMOTOR"));
        s3->addVar(MW_ACTION,moveMOTOR);

I called the action “moveMOTOR”, but as a beginner I didn’t succeed.
As the name indicate, I want to move a stepper motor of a certain amount of steps (millimeters).
in the menu I put the n° of mm I need, then s3->addVar(MW_ACTION,moveMOTOR) will point to the “moveMOTOR” function which will “convert” mm in steps and execute.
This is what I did (I know it does not what I am expecting, but at least keep my sketch compiling … it’s a success for me!)

void moveMOTOR(){ // I suppose void "moveMOTOR" indicates the function to call
int moveMOTOR = stepsPerRevolution*4; // well, here I wrote something that doesn't give me a compiling error
                                               //but I need to use the variable of the menu and a Xmultiplier
                                               //to have the number of steps needed to move of the mm needed
Serial.println ("ACTION FIRED!"); //this is just to check if the menù is working.
}

Can somebody help ? (the project is an Height actuator for woodworking machines (Saw, Router, Planner… etc.)
P.S.

//         Libaries included
#include <Wire.h>
#include <LiquidCrystal.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>
//#include <Stepper.h> // replaced with AccelStepper.h
#include <AccelStepper.h> //instead of Stepper.h
#include <AFMotor.h> //not needed if not using motor shield

If needed … attached all the sketch

Lcd_menu_002_Stepper_Pulita.ino (9.16 KB)

void moveMOTOR(){ // I suppose void "moveMOTOR" indicates the function to call
int moveMOTOR

A variable with the same name as a function is not a good idea. If the function is named moveMOTOR because it is supposed to move a motor, then, the variable might define an amount to move. Make the name meaningful.

.... so ... int moveMOTOR should be something like "int mmNumber" ? (and maybe declared before the function)
then I have to link to the function the variable defined by the menu.

void forwardstep() {  
  motor1.onestep(FORWARD, SINGLE);
}
void backwardstep() {  
  motor1.onestep(BACKWARD, SINGLE);
}
AccelStepper stepper(forwardstep, backwardstep); // use functions to step

int mmNumber
mmNumber = stepsPerRevolution/4   // I suppose a 4:1 reduction (50steps=1mm)(200 step/rev)

void moveMOTOR(){
stepper.moveTo(mmNumber*???????);    // ?????I don't know what to put here
}

.... sorry, no programming knowledge ...

At the moment your changing the variable 'sp' for your distance, in mm. This is declared as a global variable, so that's fine for this purpose.

First I'd be inclined to change that to something meaningful like motorX, motorZ, or motorY, depending what axis you are moving through.

Then, you change that value in the menu item, lets says it was motorX. You fire the moveMOTOR() function and you want to move through motorX mm.

At the top of your sketch, outside setup() and loop()

int motorX;

Inside setup(), where you set your menu structure up

 s1=menu.addMenu(MW_SUBMENU,r,F("SAW"));                       //add a submenu node 1 to the root menu (control the heigh of my Saw)
  s2=menu.addMenu(MW_VAR,s1,F("ABS Height"));                   //add a terminal node in the menu tree (that is "variable"); (move to a certain mm height)
     s2->addVar(MW_AUTO_INT,&motorX,0,100,1);                   //int type, fd binded variable, range 0-100, step 1
        s3=menu.addMenu(MW_VAR,s2,F("moveMOTOR"));
        s3->addVar(MW_ACTION,moveMOTOR);

Your function

void moveMOTOR()
{
  // use variable motorX however you need
}

I don't know what else you have in your sketch, as you haven't posted it all, but from your subsequent post, it's probably something like

void moveMOTOR()
{
  // use variable motorX however you need
  // assuming 50 steps = 1mm
  stepper.moveTo(motorX * 50) // move motorX mm's
}

This is limited by the info you've given, so is not intended to be running code, just a pointer in the right direction.

Tack,
Thanks a lot, understanding what 'sp' is and how I can change it, is a big understanding step.
I will work on your crystalline informations.
Thamks
P.S.
The whole sketch is on my post 2 as attachment ....
I'll make some modifications based on your help and then I will post the entire code in a different way.
Thanks

The full sketch … certainly there is a lot of work to do still, but … it compiles

// +++++++ Libaries included
#include <Wire.h>
#include <LiquidCrystal.h>
#include <buttons.h>
#include <MENWIZ.h>
#include <EEPROM.h>
//#include <Stepper.h> // replaced with AccelStepper.h
#include <AccelStepper.h> //instead of Stepper.h
#include <AFMotor.h> //not needed if not using motor shield 

// Create global object for menu and lcd
menwiz menu;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

AF_Stepper motor2(200, 2);
const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution for your motor
//AccelStepper motor2(stepsPerRevolution, 11,12);   // initialize the stepper library on pins 0 through 3:


void forwardstep2() {  
  motor2.onestep(FORWARD, SINGLE);
}
void backwardstep2() {  
  motor2.onestep(BACKWARD, SINGLE);
}



boolean wr=0;                         // Instantiate global variables to bind to menu

const int buttonPin = A0;             // 4 button switch circuit input connected to analog pin 0
const int led13Pin = 13;              // the number of the LED output pin
int stepCount = 0;                    // number of steps the motor has taken
int motorX;                           //ABS Height Variable = mm
boolean buttonBlock = 0;
boolean buttonAct = 0;                // flag 1
boolean stopMenu = 0;                 // flag 2
byte buttonPressed = 0;               // which button was pressed
byte lastButtonPressed = 0;           // prev button pressed
int buttonValue = 0;                  // read value from analog port for the 4 navigation pushbuttons
long menuOffTime = 0;                 //used for timer

int list,sp=0;                       // sp variable has 0 as default value (ABS height)

extern byte MW_navbtn;                //needed to run the software key navigation in Menwiz
//AccelStepper stepper1(forwardstep1, backwardstep1);
AccelStepper stepper2(forwardstep2, backwardstep2);


void setup()
{
Serial.begin(9600);                  // Output to serial writing

  //digitalWrite((54), HIGH);            // enable the 20k internal pullup for MEGA board for analog port A0
  digitalWrite((A0), HIGH);         // enable the 20k internal pullup for UNO based board for analog port A0

// Motor Speed 6 Accel
    stepper2.setMaxSpeed(400);
    stepper2.setAcceleration(50);
  //++++++++++++++++++++Menu and LCD  
  char b[84];
  _menu *r,*s1,*s2,*s3;

                                      // initialize the menu object ( 4 x rows x 20 colums LCD)
  menu.begin(&lcd,16,2);              //initialize the menwiz menu object passing the lcd object and the colums and rows params 
  menu.addUsrNav(navMenu,4);
  MW_navbtn=4;                        // force 4 or 6 buttons mode for menu navigation -> MW_navbtn=4; or MW_navbtn=6;

  //create the menu tree
  r=menu.addMenu(MW_ROOT,NULL,F("MAIN MENU"));                      //create a root menu at first (required)

  //---------------  
  s1=menu.addMenu(MW_SUBMENU,r,F("SAW"));                       //add a submenu node 1 to the root menu (control the heigh of my Saw)
  s2=menu.addMenu(MW_VAR,s1,F("ABS Height"));                   //add a terminal node in the menu tree (that is "variable"); (move at a certain mm height)
     s2->addVar(MW_AUTO_INT,&motorX,0,100,1);                   //int type, fd binded variable, rage 0-100, step 1
        s3=menu.addMenu(MW_VAR,s2,F("moveMOTOR"));
        s3->addVar(MW_ACTION,moveMOTOR);
  s2=menu.addMenu(MW_VAR,s1,F("REL Move"));                     //add a terminal node in the menu tree (that is "variable"); (move of a certain mm the height)
     s2->addVar(MW_AUTO_INT,&sp,0,100,1);                   //int type, fd binded variable, rage -100 +100, step 1
  s2=menu.addMenu(MW_VAR,s1,F("Zero"));                         //add a terminal node in the menu tree (that is "variable");  (set the zero)
  s2=menu.addMenu(MW_VAR,s1,F("Setup"));                        //add a terminal node in the menu tree (that is "variable");  (set the parameters)
      s2->addVar(MW_LIST,&list);
      s2->addItem(MW_LIST, F("Option1"));
      s2->addItem(MW_LIST, F("Option2"));
      s2->addItem(MW_LIST, F("Option3"));
  //---------------
  s1=menu.addMenu(MW_SUBMENU,r,F("PLANNER"));                    //add a submenu node 2 to the root menu (control the heigh of my Planner)
  s2=menu.addMenu(MW_VAR,s1,F("ABS Height"));                         //add a terminal node in the menu tree (that is "variable"); (should move at a certain mm height)
     s2->addVar(MW_AUTO_INT,&sp,0,100,1);                   //int type, fd binded variable, rage 0-100, step 1
  s2=menu.addMenu(MW_VAR,s1,F("REL Move"));                         //add a terminal node in the menu tree (that is "variable"); (should move of a certain mm the height)
     s2->addVar(MW_AUTO_INT,&sp,-100,100,1);                   //int type, fd binded variable, rage 0-100, step 1
  s2=menu.addMenu(MW_VAR,s1,F("Zero"));                         //add a terminal node in the menu tree (that is "variable"); (should set the zero)
  s2=menu.addMenu(MW_VAR,s1,F("Setup"));                        //add a terminal node in the menu tree (that is "variable");  (set the parameters)
  
  //---------------
  s1=menu.addMenu(MW_SUBMENU,r,F("SHAPER"));                    //add a submenu node 3 to the root menu
  s2=menu.addMenu(MW_VAR,s1,F("ABS Height"));                         //add a terminal node in the menu tree (that is "variable"); (should move at a certain mm height)
  s2=menu.addMenu(MW_VAR,s1,F("REL Move"));                     //add a terminal node in the menu tree (that is "variable"); (should move of a certain mm the height)
  s2=menu.addMenu(MW_VAR,s1,F("Zero"));                     //add a terminal node in the menu tree (that is "variable"); (should set the zero)
  s2=menu.addMenu(MW_VAR,s1,F("Setup"));                        //add a terminal node in the menu tree (that is "variable");  (set the parameters)
  
  /*
  //++++++ Splash screen +++++++
  
  sprintf(menu.sbuf,"TEST minimum menu\nwith 4 or 6\nanalog push buttons\n",1);
  menu.addSplash((char *) menu.sbuf, 1000);

  //++++++ Userscreen ++++++++++
  // create an user define screen callback to activate after X secs since last button push
  menu.addUsrScreen(msc,3000);
  */
  pinMode(led13Pin, OUTPUT);                // initialize the led as a output control pin
}

void loop()    
{
// NAVIGATION MANAGEMENT & DRAWING ON LCD. NOT BLOCKING has to be the first in the void loop
  menu.draw();
/*
  put your regular code here
   */
  readButtons();
}
/*
void Option1 ()
{
Serial.println("ACTION FIRED");
delay (3000);
}
*/


void moveMOTOR(){
stepper2.moveTo(motorX * 50); // move motorX mm's
Serial.println ("Moving X mm");
}

//  ++++++ functions +++++++

void readButtons()

// ++++ Control 4 buttons ++++
{
  lastButtonPressed = buttonPressed;

  /*
  Analog values representing the pushbutton value are depending on the resitor value used.
   Test the values first with the serial.monitor
   */
  buttonValue = analogRead(buttonPin); //analog value to simulate the pushed buttons
    
  if(buttonValue >= 850)
  {
    buttonPressed = 0;
    noButtonPressed(); // is calling an extra fucntion
  }
  else  if(buttonValue >= 380 & buttonValue <= 450)
  {
    buttonPressed = 4;
    buttonAct = 1; // set the menu flag1
  }
  else if(buttonValue >= 200 & buttonValue <=300)
  {    
    buttonPressed = 3;
    buttonAct = 1; // set the menu flag1
  }
  else if(buttonValue >= 0 & buttonValue <=50)
  {    
    buttonPressed = 2;
    buttonAct = 1; // set the menu flag1
  }
  else if(buttonValue >= 80 & buttonValue <=150)
  {    
    buttonPressed = 1;
    buttonAct = 1; // set the menu flag1
  }
}

int noButtonPressed()
{
  return MW_BTNULL;
}

int navMenu() // called from menu.draw
{
  /*
   As soon as a button is pushed the first time flag 1 is set to HIGH and if the buttonnumber is not 0 then a timer is started.
   The menu action then should only be performed once.
   After 2000 msecs the flag will be set to LOW and a new buttonpush can be processed.
   Menu action is blocked for 400 msec even if the same button is being kept pressed for 2000 msecs by flag2.
   */

  long menublockTime = millis();

  if (buttonAct == 1 && buttonPressed != 0 && stopMenu == 0)  // we have a state were we process a menu navigation step once and block it for 0.4 secs
  {
    digitalWrite(led13Pin,HIGH);  // set timer led ON
    menuOffTime = menublockTime  + 400; //start the timer. You can change this blocking time to your convenience but do not make it lower aa 200 msecs
    stopMenu = 1;

    switch (buttonPressed)
    {
    case 1: // Up
      return MW_BTU;
      break;
    case 2: // Confirm
      return MW_BTC;
      break;
    case 3: // Down
      return MW_BTD;
      break;    
    case 4: // Escape
      return MW_BTE;
      break;
    }
  }

  if (menuOffTime != 0  &&  menublockTime  > menuOffTime)  //  Reset of the timer so a new menu action can be processed
  {
    buttonAct = 0; // resets the flag 1
    buttonPressed = 0;
    menuOffTime = 0;  // resets timer to zero
    stopMenu = 0;
    digitalWrite(led13Pin,LOW);  // set timer led OFF
  }
}