Serial read twice doesn't work

I'm needing two parameters for a stepper motor control, mode and number of steps.

I have read the serial.read introduiction and example 5 would solve my problem, but as a newbie I'm keen to understand why the attached does not work

I tried with both serial.reads in the main program, but thought a function would do it - NO!

int no_of_steps;
int modeType;

void setup() {
  Serial.begin(9600);  // open the serial connection at 9600bps
  Serial.print("Set mode 1,2,4,8 or 16)");
  Serial.println();
}

void loop() {
  //  0pt2 Serial.print("Set mode 1,2,4,8 or 16)");
  // Serial.println();
  while (Serial.available() > 0) {
    modeType = Serial.parseInt();  //Read user input and trigger appropriate function
    Serial.println(modeType);

    // failed code!
    // Serial.print("Set no of steps");
    // Serial.println();
    // while (Serial.available()) {
    //   no_of_steps = Serial.parseInt();  //Read user input and trigger appropriate function
    // }

    no_of_steps = SecondInput();

    Serial.println(no_of_steps);  // Serial.print("modeType is ");
    Serial.println(modeType);
    Serial.println("Whats up doc?");
  }
}

int SecondInput() {
  Serial.println("Set no of steps");
  while (Serial.available() > 0) {
    no_of_steps = Serial.parseInt();  //Read user input and trigger appropriate function
  }
  return no_of_steps;
}

the monitor output:

Set mode 1,2,4,8 or 16)
2
Set no of steps
/* Here it bypasses and prints an empty value for no_of_steps and the mode */
0
2

Whats up doc?

Can you explain why it fails
TIA

Serial.parseint() and related functions are extremely limited in their applications.

You would be much better off using a more robust method of serial input, as discussed in the Serial Input Basics tutorial.

In addition to what @jremington wrote you about parseInt() and correct way to manage serial readings, the main problem I see is that you do two consecutive readings but you are not sure that all the data is really present (if it has had time to enter the serial buffer). After the first "while (Serial.available() > 0) {" you read the first value then you jump to "SecondInput()" function, where its "Serial.available()"call could return zero, failing to get the second value, and probably go out of sync.

If you need two related values you need to make sure you read them together. As parseInt() is a blocking function, you need to check Serial.available() first, wating for the input, then read the first value, then repeat for the second one.
Something like:

  Serial.print("Type a number: ");
  while(!Serial.available()) { }
  int v1 = Serial.parseInt();
  Serial.println(v1);
  Serial.print("Second number: ");
  while(!Serial.available()) { }
  int v2 = Serial.parseInt();
  Serial.println(v2);

  Serial.print("v1=");Serial.println(v1);
  Serial.print("v2=");Serial.println(v2);

It should work if you put both numbers in the same line:
2 27
The first 'parseInt()' will read the first number and stop at the space. The remaining characters will allow the second parseInt() to run. It will skip leading spaces and get the next number.

tks Profile - johnwasser - Arduino Forum and Profile - docdoc - Arduino Forum.
I also found out:

Compilation error: text section exceeds available space in board

thanks for tips - good feedback for me.

It seems you're trying/running a code too big for the board, and obviously it isn't the one we're talking about...

Yes, it's the same kind of solution I'd suggest (except I don't like using parseInt but it's because how my mind works...:wink: ), but I just kept the original logic with an "user prompt" for each input.

I hyave a new problem...

int modeType, tstType;

void setup() {
  Serial.begin(9600);
  tstType = 5;
  modeType = 5;

  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
  modeType = checkMotorMode(modeType);
  //  returns int:modeType
  Serial.print("checkMode is ");
  Serial.println(modeType);
  if (modeType == 0) {
    Serial.println(F("Invalid mode! "));
  } else {
    //  enable the motor
    Serial.println("start motor");
  }
}

//***************************************************************************
//chekcMotorMode
//***************************************************************************
// mod 21 Mar 2023_1722 - removed/added/removed debug prints...
int checkMotorMode(int modeType) {

  // mode (stepper) values (1,2,4,8,16)
  int modeValues[] = { 1, 2, 4, 8, 16 };
  int mtrMode;

  for (int i = 0; i < 5; i++) {
    mtrMode = modeValues[i];
    // Serial.print(mtrMode);
    if (modeType == modeValues[i]) {
      // Serial.print("chkMtr1Mode is ");
      // Serial.println(modeType);
      //  valid modeType;
      return mtrMode;
      break;
      // } else if (modeType < modeValues[i]) {
    } else if (modeType < mtrMode) {
      // Serial.print("chkMtr2Mode is ");
      // Serial.println(modeType);
      // Serial.print("chkmode3Type changed to ");
      // Serial.println(modeValues[i]);  
      //  correct the value, select mtrMode
      return mtrMode;
      break;
    } else if (i == 4) {
      // end of valid values - failed
      // Serial.print("chkmode4Type is ");
      // Serial.println(0);
      return 0;
    }
  }
}

I run this exerpt from the main code and it works.
checkMode is 8
start motor
However in my fuill program, it only works with all the Serial.print statements operational.

I cannot work it out - can you offer advice?
I haven't included the main program but could of course.
with debugging:
<WA42, 5, 55>

Motor is WA42
modeType is 5
No of steps are 55
Enabling Motor WA42
chkMtr2Mode is 5
chkmode3Type changed to 8
checkMode is 8
Step Mode is Eighth... 55

Please post your full program. Also provide a complete schematic / wiring diagram.

From a software perspective, one possible reason why Serial print (or any other) statements influence the behaviour are memory issues (writing outside bounds of arrays, incorrect use of String (capital S) objects). Either omitting them or adding them can result in crashes in that case because the memory layout of variables will change.

Aqnother reason is that Serial prints can onfuence the timing of your program.

///////////////////////////////////////////////////////////
// Stepper Motor skecth for use with the EasyDriver v4.2 //
//  JM mod to add for 16th mode 15 Mar 2023_1651
///////////////////////////////////////////////////////////

// Dan Thompson 2010
//
// Use this code at your own risk.
//
// For all the product details visit http://www.schmalzhaus.com/EasyDriver/
// For the full tutorial visit http://danthompsonsblog.blogspot.com/

//  added Date function see https://www.softwaretestinghelp.com/date-and-time-in-cpp/
// #include <iostream>
// #include <ctime>
// using namespace std;

#include <Wire.h>
// #include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// JM mod 02 Mar 2023 taken from sketch OLEDfeathering.ino
#define WIRE Wire

////// ED_v4jm  Step Mode Chart ////////////////
//   WA42    0.9deg 400 for 1 rev             //
//                                            //
//   MS1 MS2 MS3  Resolution(2 phase)  Steps  //
//   L   L        Full step            400    //
//   H   L        Half step            800    //
//   L   H        Quarter step         1600   //
//   H   H        Eighth step          3200   //
//   H   L   L    16th step            6400   //
//                                            //
////////////////////////////////////////////////
// #include <DrDuino_Explorer.h>

int DIR = 3;   // PIN  3 = DIR
int STEP = 2;  // PIN  2 = STEP
int MS1 = 4;   // PIN 13 = MS
int MS2 = 5;   // PIN  9 = MS2
int MS3 = 6;
int SLEEP = 12;  // PIN 12 = SLP
int LED = 10;    // enable when MS3 in operation

// ArdFrm Example 5 - Receive with start< and end> markers combined with parsing
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];  // temporary array for use when parsing

// variables to hold the parsed data
char mtrType[numChars] = { "" };
int integerFromPC = 0;
float floatFromPC = 0.0;
boolean newData = false;

String prompt = "Set motor, mode (1,2,4,8,16) & required steps eg <2T15, 16, 3> ";
int user_input;
int no_of_steps = 0;
int reqSteps;
int i = 0;
int modeType;
String motorType, motor;
boolean mtrValid = false;  //is the mType a valid value (T or F)

// JM mod 02 Mar 2023 taken from sketch OLEDfeathering.ino
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &WIRE);


//***************************************************************************
//void setup
//***************************************************************************
void setup() {
  Serial.begin(9600);      // open the serial connection at 9600bps
  pinMode(DIR, OUTPUT);    // set pin 3 to output
  pinMode(STEP, OUTPUT);   // set pin 2 to output
  pinMode(MS1, OUTPUT);    // set pin 13 to output
  pinMode(MS2, OUTPUT);    // set pin 9 to output
  pinMode(MS3, OUTPUT);    // set pin 6 to output
  pinMode(SLEEP, OUTPUT);  // set pin 12 to output
  pinMode(LED, OUTPUT);    // set pin 13 to output

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Address 0x3C for 128x32
  display.display();
  delay(1000);

  display.clearDisplay();
  MitchSplashScreen();


  // read taken from ArdForum afSerislRead.ino
  // Serial.println("Set motor, mode (1,2,4,8,16) & required steps eg <2T15, 16, 3> ");
  Serial.println(prompt);

  Serial.println();
  // recvWithStartEndMarkers();
}


//***************************************************************************
//void loop
//***************************************************************************
void loop() {
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempChars, receivedChars);
    // this temporary copy is necessary to protect the original data
    //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    // showParsedData();


    Serial.print(F("Motor is "));
    Serial.println(mtrType);
    Serial.print("modeType is ");
    Serial.println(modeType);
    Serial.print("No of steps are ");
    Serial.println(reqSteps);
    // no_of_steps = modeType * 200;        // dt's original method
    // no_of_steps = 400 * 16;
    // int modeType = 1;
    // no_of_steps = 5;


    // select Motor type for options 1-6
    motorType = String(mtrType);
    selectMotor(motorType);
    //  returns motorType: string, updates mtrValid
    if (mtrValid == false) {
      Serial.print(F("Invalid motor: "));
      Serial.println(motorType);
    } else {
      //  motor type OK
      Serial.print(F("Enabling Motor "));
      Serial.println(motorType);
      motor = "motor " + motor + ", mode " + modeType + ", steps " + reqSteps + "...";
      // Serial.println(motor);
      // send message to display
      int mlen = motor.length() + 1;
      // Serial.println(mlen);
      char Msg[mlen];
      motor.toCharArray(Msg, mlen);
      DisplayMessage2User(Msg, 1);

      // check if mode is one of Full to 1/16th;
      //  if near < number, select Next ie 6 > 8, else fail ie > 16!
      // motor mode OK, check motor type
      modeType = checkMotorMode(modeType);
      //  returns int:modeType
      Serial.print("checkMode is ");
      Serial.println(modeType);
      if (modeType == 0) {
        Serial.println(F("Invalid mode! "));
      } else {
        //  enable the motor
        digitalWrite(DIR, LOW);                           // Set the direction change LOW to HIGH to go in opposite direction
        digitalWrite(MS1, MS1_MODE(modeType, reqSteps));  // Set state of MS1 based on the returned value from the MS1_MODE() switch statement.
        digitalWrite(MS2, MS2_MODE(modeType));            // Set state of MS2 based on the returned value from the MS2_MODE() switch statement.
        if (modeType == 16) {
          digitalWrite(MS3, LOW);
          digitalWrite(LED, HIGH);
        }
        digitalWrite(SLEEP, HIGH);  // Set the Sleep mode to AWAKE.

        // int i = 0;  // Set the counter variable.
        // JM mod 15 Mar 2023_1541

        for (i = 0; i < reqSteps; i++) {  //Loop the forward stepping enough times for motion to be visible
                                          // while (0 < i < no_of_steps) {
          // Iterate for 200, then 400, then 800, then 1600 steps.
          // while (i < (400*16))
          // Iterate for 400 steps at a full step WA42 0.9 deg = 400
          // Serial.print("Step ");
          // Serial.println(i);

          // Then reset to 200 and start again.
          digitalWrite(STEP, LOW);   // This LOW to HIGH change is what creates the..
          digitalWrite(STEP, HIGH);  // .."Rising Edge" so the easydriver knows to when to step.
          delayMicroseconds(2000);   // This delay time determines the speed of the stepper motor.
                                     // Delay shortens from 1600 to 800 to 400 to 200 then resets

          // i++;
        }
        // modeType = modeType * 2;  // Multiply the current modeType value by 2 and make the result the new value for modeType.
        //                           // This will make the modeType variable count 1,2,4,8, 16 each time we pass though the while loop.

        // delay(500);

        // digitalWrite(SLEEP, LOW);  // switch off the power to stepper
        // digitalWrite(LED, LOW);    // turn off MS3 LED
        // Serial.print("SLEEPING..");
        // delay(1000);
        // Serial.print("z");
        // delay(1000);
        // Serial.print("z");
        // delay(1000);
        // Serial.print("z");
        // delay(1000);
        // Serial.println("");
      }
    }
    digitalWrite(SLEEP, HIGH);
    digitalWrite(LED, LOW);      // turn off MS3 LED
    Serial.println("AWAKE!!!");  // Switch on the power to stepper
    delay(1000);

    // re-initialise
    newData = false;
  }

  delay(10000);
  // read taken from ArdForum afSerislRead.ino
  Serial.println("Set motor, mode (1,2,4,8,16) & steps eg <WA42, 16, 3> ");
  Serial.println();
}


//***************************************************************************
// recvWithStartEndMarkers
//***************************************************************************
void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      } else {
        receivedChars[ndx] = '\0';  // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

//***************************************************************************
//parseData - note char & 2 ints (can be char, int or float)
//***************************************************************************
int parseData() {  // split the data into its parts

  char* strtokIndx;  // this is used by strtok() as an index

  //  motor type
  strtokIndx = strtok(tempChars, ",");  // get the first part - the string
  // Serial.println(strtokIndx);
  strcpy(mtrType, strtokIndx);  // copy it to messageFromPC

  //  mode
  strtokIndx = strtok(NULL, ",");  // get the second part - the integer
  // Serial.println(strtokIndx);
  modeType = atoi(strtokIndx);  // convert this part to an integer

  // reqSteps
  strtokIndx = strtok(NULL, ",");  // this continues where the previous call left off
  // Serial.println(strtokIndx);
  reqSteps = atoi(strtokIndx);  // convert this part to an integer

  // strtokIndx = strtok(NULL, ",");
  // floatFromPC = atof(strtokIndx);  // convert this part to a float

  return mtrType, modeType, reqSteps;
}

//***************************************************************************
//showParsedData
//***************************************************************************
void showParsedData() {
  Serial.print("Motor ");
  Serial.println(mtrType);
  Serial.print("modeType ");
  Serial.println(modeType);
  Serial.print("no_of_steps ");
  Serial.println(reqSteps);
  // Serial.print("Float ");
  // Serial.println(floatFromPC);
}

//***************************************************************************
//MS1_MODE(int MS1_StepMode, int no_of_steps)
//***************************************************************************
int MS1_MODE(int MS1_StepMode, int no_of_steps) {  // A function that returns a High or Low state number for MS1 pin
  switch (MS1_StepMode) {                          // Switch statement for changing the MS1 pin state
                                                   // Different input states allowed are 1,2,4 or 8
    case 1:
      MS1_StepMode = 0;
      Serial.print("Step Mode is Full... ");
      Serial.println(no_of_steps);
      break;
    case 2:
      MS1_StepMode = 1;
      Serial.print("Step Mode is Half...  ");
      Serial.println(no_of_steps);

      break;
    case 4:
      MS1_StepMode = 0;
      Serial.print("Step Mode is Quarter...  ");
      Serial.println(no_of_steps);

      break;
    case 8:
      MS1_StepMode = 1;
      Serial.print("Step Mode is Eighth...  ");
      Serial.println(no_of_steps);

      break;
    case 16:
      MS1_StepMode = 1;
      Serial.print("Step Mode is 16th...  ");
      Serial.println(no_of_steps);

      break;
  }
  return MS1_StepMode;
}


//***************************************************************************
// MS2_MODE(int MS2_StepMode)
//***************************************************************************
int MS2_MODE(int MS2_StepMode) {  // A function that returns a High or Low state number for MS2 pin
  switch (MS2_StepMode) {         // Switch statement for changing the MS2 pin state
                                  // Different input states allowed are 1,2,4 or 8
    case 1:
      MS2_StepMode = 0;
      break;
    case 2:
      MS2_StepMode = 0;
      break;
    case 4:
      MS2_StepMode = 1;
      break;
    case 8:
      MS2_StepMode = 1;
      break;
    case 16:
      MS2_StepMode = 0;
      break;
  }
  return MS2_StepMode;
}

//***************************************************************************
//DisplayMessage2User
//***************************************************************************
void DisplayMessage2User(char advice[], int fontsize) {
  // Serial.println(F("Entered 2User"));
  display.clearDisplay();
  display.setCursor(0, 0);
  display.setTextSize(fontsize);
  display.println((advice));
  display.display();
}

//***************************************************************************
//MitchSplashScreen
//***************************************************************************
void MitchSplashScreen() {
  // Serial.println(F("Entered MitchSplashScreen"));
  display.clearDisplay();
  display.setTextSize(2);       // Normal 1:1 pixel scale
  display.setTextColor(WHITE);  // Draw white text
  display.setCursor(10, 0);     // Start at top-left corner
  display.cp437(true);          // Use full 256 char 'Code Page 437' font

  display.println(F("Mitch"));
  display.setTextSize(1);
  display.setCursor(10, 15);  // Start at top-left corner

  // get current date & time
  // see NTP over ethernet solutions
  display.println(F("20 Mar 2023"));
  display.setCursor(35, 23);  // Start at top-left corner
  // display.println(( FwVersion));
  display.display();
  delay(100);
}

//***************************************************************************
//select Motor type
//***************************************************************************
String selectMotor(String motorType) {
  // select from the available Motor types
  //  updated 15 Mar 2023_1244, uses mtrValid global
  if (motorType == NULL) {
    Serial.println(F("Enter type: 2T35, 2T15 or WA42"));
    while (Serial.available() == 0) {}  //wait for data available
    motorType = Serial.readString();    //read until timeout
    motorType.trim();                   // remove any \r \n whitespace at the end of the String
  }
  char steppers[] = "2T35, 2T15, or WA42";
  char* pch;
  // convert motorType to a char Mtr
  int slen = motorType.length() + 1;
  char Mtr[slen];
  // delay(1000);
  motorType.toCharArray(Mtr, slen);
  // Serial.print(F("slen is "));
  // Serial.println(slen);
  // Serial.println(Mtr);

  pch = strstr(steppers, Mtr);
  if (pch != NULL) {
    // Serial.print(F("Selected motor type is "));
    // Serial.println(Mtr);
    mtrValid = true;
    // get steps/revolution
    no_of_steps = setAttributes(motorType);
    motor = "Using " + motorType + ", steps " + no_of_steps + "...";
  } else {
    // Serial.println(F("Invalid motor type"));
    mtrValid = false;
    motor = "Invalid motor type " + motorType + "...";
    // Serial.println(motor);
  }
  //***************************************************************************
  // send message to display
  int mlen = motor.length() + 1;
  // Serial.println(mlen);
  char Msg[mlen];
  motor.toCharArray(Msg, mlen);
  DisplayMessage2User(Msg, 1);

  // return motorType;
}

//***************************************************************************
// set motor attributes
//***************************************************************************
int setAttributes(const String motorType) {
  if (motorType == "2T35") {
    // step = 3.75 deg
    int no_of_steps = 360 / 3.75;
    return no_of_steps;

  } else if (motorType == "2T15") {
    //   step = 18 deg
    int no_of_steps = 360 / 18;
    return no_of_steps;

  } else if (motorType == "WA42") {
    //  step = 0.9 deg
    int no_of_steps = 360 / 0.9;
    return no_of_steps;
  }
  // debug
  Serial.println(no_of_steps);
  Serial.println();
}

// //***************************************************************************
// //Reset Easy Driver pins to default states
// //***************************************************************************
// void resetBEDPins() {
//   digitalWrite(stp, LOW);
//   digitalWrite(dir, LOW);
//   digitalWrite(MS1, LOW);
//   digitalWrite(MS2, LOW);
//   digitalWrite(MS3, LOW);
//   digitalWrite(EN, HIGH);
//   digitalWrite(LDd, LOW);
// }

//***************************************************************************
//chekcMotorMode
//***************************************************************************
// mod 21 Mar 2023_1722 - removed debug prints...
int checkMotorMode(int modeType) {

  // mode (stepper) values (1,2,4,8,16)
  int modeValues[] = { 1, 2, 4, 8, 16 };
  int mtrMode;

  for (int i = 0; i < 5; i++) {
    mtrMode = modeValues[i];
    // Serial.print(mtrMode);
    if (modeType == modeValues[i]) {
      Serial.print("chkMtr1Mode is ");
      Serial.println(modeType);
      //  valid modeType;
      // modeType = mtrMode;
      return mtrMode;
      break;
    // } else if (modeType < modeValues[i]) {
    } else if (modeType < mtrMode) {
      Serial.print("chkMtr2Mode is ");
      Serial.println(modeType);
      Serial.print("chkmode3Type changed to ");
      Serial.println(modeValues[i]);  //  correct the value, select mtrMode
      // modeType = mtrMode;
      return mtrMode;
      break;
    } else if (i == 4) {
      // end of valid values - failed
      // Serial.print("chkmode4Type is ");
      // Serial.println(0);
      // modeType = 0;
      return 0;
    }
  }
  
}

I'm using a DrDuino Explorer with a BigEasyDriver board and Wantai 428YBHM809 motor

Very quick glance over it.

That will not do what you think it does. You can not return three values in one int.

If you set the warning level to all in file → preferences, you will get the following warnings.

C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023221-11172-35gts9.p8ciy\sketch_mar21a\sketch_mar21a.ino: In function 'int parseData()':
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023221-11172-35gts9.p8ciy\sketch_mar21a\sketch_mar21a.ino:297:19: warning: left operand of comma operator has no effect [-Wunused-value]
   return mtrType, modeType, reqSteps;
                   ^~~~~~~~
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023221-11172-35gts9.p8ciy\sketch_mar21a\sketch_mar21a.ino:297:29: warning: right operand of comma operator has no effect [-Wunused-value]
   return mtrType, modeType, reqSteps;
                             ^~~~~~~~
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023221-11172-35gts9.p8ciy\sketch_mar21a\sketch_mar21a.ino: In function 'String selectMotor(String)':
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023221-11172-35gts9.p8ciy\sketch_mar21a\sketch_mar21a.ino:473:1: warning: no return statement in function returning non-void [-Wreturn-type]
 }
 ^
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023221-11172-35gts9.p8ciy\sketch_mar21a\sketch_mar21a.ino: In function 'int setAttributes(String)':
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023221-11172-35gts9.p8ciy\sketch_mar21a\sketch_mar21a.ino:501:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023221-11172-35gts9.p8ciy\sketch_mar21a\sketch_mar21a.ino: In function 'int checkMotorMode(int)':
C:\Users\sterretje\AppData\Local\Temp\.arduinoIDE-unsaved2023221-11172-35gts9.p8ciy\sketch_mar21a\sketch_mar21a.ino:560:1: warning: control reaches end of non-void function [-Wreturn-type]

@sterretje
Agreed, although one could cobble up a return value that's an amalgam of flag bits. Pretty advanced programming for our usual needs on this forum, and beyond the needs of this case, but it is another tool in the toolbox.

But if you look at how the function is called, the return value is ignored so much easier to declare it of type void. :slight_smile:

@sterretje and colleagues

thanks for the advice - code working much better. I am enjoying this a lot despite a rather bizarre sketch I'm learning heaps
tks

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.