Receiving information from serial port and use them to move a pallet stacker

Morning everybody.

I'm working on a project right now. I have to control motors to raise and lower a pallet stacker. :slight_smile:

I have many sensors that giving differents kind of informations and one of them is the distance from the lifting table to the ground.
Then I have a height(we will call it H) where the lifting table has to stop. So I have 3 cases:
1- The lifting table is under H. The pallet goes up till it reach H and then stop at H
2- The lifting table is over H. The pallet goes down and stop at H
3- The lifting table is at H. It stay at H

My problem here is that H is not define by me but by a user. 8)
The user should be able to enter H in the serial port and then the system do what he have to do according to what is above.
I don't know in advance what the user will put in the serial interface(we we call it input) :confused: but H should be between 5< H< 125.

So I should be able to tell my user according to the input:

Input is not a number -> Error system try again thanks
Input is a number but not in the right range -> Enter a valide number
Input is in the right range and a number -> Control motor program

I have a code but as you can guess it don't work. I'm putting it there don't hesitate to help me out.
Thanks in advance

Serial.println("------------------------------------------------------------------");
Serial.println("Enter the height please.");
Serial.println("The value should be between 15 and 125cm\n");
delay(2000);
while(Serial.available())
{
   inChar = (char)Serial.read();
   haut += String(inChar);     
}
delay(10);
Serial.println(haut);

//  hauteur = haut.toFloat();

if(isDigit(haut))
{
   if(hauteur<15 || hauteur >125)
   {
      Serial.print("Invalide number!");
      Serial.println("Please enter a number between 15 and 125 cm");
   }
   else
   { 
      Control motor code;
   }
}
else
{
   Serial.print("System error!");
   Serial.println("Enter a valide number please!Thanks");
}
if(isDigit(haut))

The isDigit() function does NOT take a String. You need to test each character BEFORE adding it to the String instance.

//  hauteur = haut.toFloat();

Well, you can't expect commented out code to do anything.

   if(hauteur<15 || hauteur >125)

I do not like to see floats compared to ints.

   if(hauteur < 15.0 || hauteur > 125.0)

makes it clear that you are comparing like things.
(And the spaces make it easier to read.)

I have a code but as you can guess it don't work.

Rubbish. The code DOES work, if it compiles (which I doubt). If it compiles, it does exactly what it is supposed to do. That may not be the same as what you want, but that just means that your expectations are wrong.

You need to describe exactly what the code does, and how that differs from your clearly incorrect expectations. If it compiles at all, that is.

If it doesn't, you need to fix the compilation issues. If you need help with that, "it doesn't work" is nowhere near enough information.

PaulS thank you for your answer.
I'm a newbie and I never really use Arduino before so sorry if wasn't clar enough.

Here what I wanted to do

When I receive an input from the serial port I have to check if it's a number(2 or 3 digit for example 85) or not.

  • If it not a number then the user receive a message on the serial port screen and have to put another input
  • if it is a number then
  • If the input is in a certain range I execute the pallet motor control code (That code is already made and is working)
  • If the input is not is the range I send the user a message on the serial port screen and have to put another input

I found a function that help me determine if my input as a String is a numeric or not. Now the issue I'm facing two other issue.
1- When the input is not a number or is a number that is not in the right range I can't put enter another input. Is like I stay in the loop and I don't know how to solve this
2- When I enter a number of 3 digit (for example 458) the program consider input digit by digit and for example at the second time input= 45 for the system and it start working

here is my code hope that you can help

boolean rep = true;

boolean isNumeric(String str) {
   unsigned int stringLength = str.length();

   if (stringLength == 0) {
       return false;
   }

   boolean seenDecimal = false;

   for(unsigned int i = 0; i < stringLength; ++i) {
       if (isDigit(str.charAt(i))) {
           continue;
       }

       if (str.charAt(i) == '.') {
           if (seenDecimal) {
               return false;
           }
           seenDecimal = true;
           continue;
       }
       return false;
   }
   return true;
}


void interface(){
 Serial.println("------------------------------------------------------------------");
 Serial.println("Enter H");
 Serial.println("It should be between 15 and 125cm\n");
 delay(2000);
 if(Serial.available())
 {
   inChar = (char)Serial.read();
   haut += String(inChar);
   
   if(isNumeric(haut))
   {
     Serial.print("Hauteur H:");
     Serial.println(haut);
     controle();
   
   }
   else
   {
     Serial.print("Erreur systeme!");
     Serial.println("Start again");
     rep = true;
   }     
 }
 
}

void controle(){
 hauteur = haut.toFloat(); 
 if(hauteur<15 || hauteur >125)
 {
   Serial.print("Invalid number!");
   Serial.println("Start again");
   rep = true;
 }
 else
 {
   lev1();
   delay(10);
   lev2();
   if(distanceG > hauteur || distanceD > hauteur)
   {
     digitalWrite(13, HIGH);
     speedLeft = 0;
     speedRight = 60;
     Serial.println("Hello");
   }
   else if(distanceG < hauteur || distanceD < hauteur)
   {
     digitalWrite(13, HIGH);
     speedLeft = 0;
     speedRight = -30;
   }
   else
   {
     digitalWrite(13, LOW);
     speedLeft = 0;
     speedRight = 0;
     Serial.println("BUG OK!");
   }   
   affichage();
   delay(2000); 
   rep = false;
 }
}

void loop()
{
  // test();
     
   if (rep == true){
      interface();
   }
   
}

Every time you read a character, you determine whether the String (which you do NOT need) contains a numeric value. If it does, you use the value. With that approach, you will never be able to enter a multi-digit number.

Suppose you see a string of characters, like "56:231:9:32". Can you see the 4 numbers in the string? Pretty easy, right?

Suppose that the string of characters was "56231932". Can you see the 4 numbers in the string? No. You have no idea where any number starts or ends.

The data you send to the Arduino must have a delimiter (like the :slight_smile: to indicate where a number ends, in the data stream.

The Serial Monitor app can append a carriage return, a line feed, or both, to the number it sends. THAT is how you can recognize that you need to call isNumeric() (and controle(), if the string contains a number.

And, there is NO reason to use Strings.

Find Robin2's Serial Input Basics - Updated thread and have a good read.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R