Serial IO and math

Ok, so these kinds of programs are usually done in introductory courses to programming, and most people are quite familiar with them. What I wanted to see, just out of curiosity, is to whether such a simple program can be written for an Arduino. I'm still a noob, but I do these kinds of things to help me understand how software/hardware works.

So the premise is that I want to enter a number through the Serial monitor and get it printed out on it. Basically, I want to use the Serial monitor as a console or command prompt.

I wrote this little program:

void setup(){
  
  Serial.begin(9600);
    
}

void loop(){
  Serial.print("Enter a number: ");
  
  if(Serial.available() > 0){
    int num = Serial.parseInt();
    
    Serial.print("The number is: ");
    Serial.println(num);
  }
}

But instead the text "Enter a number: " was printed indefinitely. But if I put the whole code into void setup, it didn't work, the text was printed but not the input.

So how do I go about this? It seems as a simple thing to do, but I couldn't find anything about it online.

You need a line to make the code wait until something is received. I think this will work

while (Serial.available() == 0) {
}

...R

Here is a crude modification to your program.
Two things - it prints when the number is 0 AT RANDOM! It must detect some noise, Would like to know if you get same results.
Second - the IDE sucks - why I cannot cut and paste stuff from the COM dialog? I guess nobody cares as long as it is quoted properly.

void setup(){
  
  Serial.begin(9600);
    
}

void loop(){
  Serial.print("Enter a number: ");
  while (Serial.available() == 0) {
}
  if(Serial.available() > 0){
    int num = Serial.parseInt();
    
    Serial.print("The number is: ");
    Serial.println(num);
  }
  
  delay(5000);
}

Moderator edit: quote tags replaced with code tags. The sin-bin beckons.

It works. But I moved it to void setup so it doesn't repeat itself after I entered the number.

Now, what I want to try to do next is to enter two numbers, but the second one only when the first one has been entered. To do this I repeated the code once again, added a new integer name and it worked again. And finally I added the two numbers and printed out the sum. I'm glad it all worked. Thank you guys :smiley:

void setup(){
  
  Serial.begin(9600);
    
  int num1, num2;
    
  Serial.println("Enter the first number");
  while (Serial.available() == 0) {
  }
  if(Serial.available() > 0){
    num1 = Serial.parseInt();
    
    Serial.print("The first number is ");
    Serial.println(num1);
    Serial.println("");
  }
  
  Serial.println("Enter the second number");
  while (Serial.available() == 0) {
  }
  if(Serial.available() > 0){
    num2 = Serial.parseInt();
    
    Serial.print("The second number is ");
    Serial.println(num2);
    Serial.println("");
  }
  
  int sum = num1 + num2;
  
  Serial.print("The sum of ");
  Serial.print(num1);
  Serial.print(" and ");
  Serial.print(num2);
  Serial.print(" is ");
  Serial.print(sum);
  
}

void loop(){

}

delodephius:
It works. But I moved it to void setup so it doesn't repeat itself after I entered the number.

Now, what I want to try to do next is to enter two numbers, but the second one only when the first one has been entered. To do this I repeated the code once again, added a new integer name and it worked again. And finally I added the two numbers and printed out the sum. I'm glad it all worked. Thank you guys :smiley:

void setup(){

Serial.begin(9600);
   
  int num1, num2;
   
  Serial.println("Enter the first number");
  while (Serial.available() == 0) {
  }
  if(Serial.available() > 0){
    num1 = Serial.parseInt();
   
    Serial.print("The first number is ");
    Serial.println(num1);
    Serial.println("");
  }
 
  Serial.println("Enter the second number");
  while (Serial.available() == 0) {
  }
  if(Serial.available() > 0){
    num2 = Serial.parseInt();
   
    Serial.print("The second number is ");
    Serial.println(num2);
    Serial.println("");
  }
 
  int sum = num1 + num2;
 
  Serial.print("The sum of ");
  Serial.print(num1);
  Serial.print(" and ");
  Serial.print(num2);
  Serial.print(" is ");
  Serial.print(sum);
 
}

void loop(){

}

Well if it does what you want, that's OK.
However, the "rule" is to use Setup for stuff you want to do only once - initialize.
Challenge yourself and do your code in loop.
As I said it was just crude czech code to make it work, so take a look at the " while " control .
Cheers
Vaclav

Yes, I am aware of the "rule", bratku. But in the loop the whole process starts again once I entered both numbers and it prints out the sum. All I know is to add a delay function with a ridiculously high number so that it doesn't re-start in this lifetime. Unless, of course, you or someone else knows how to terminate the loop once its all done. I'm assuming it'll require some sort of for or do/while loops to achieve that, but I'm not yet sure how. I still haven't grasped that part of programming very well.

delodephius:
It works.

Except when the number is entered slowly.

Now, what I want to try to do next is to enter two numbers, but the second one only when the first one has been entered.

Using the current technique (wait for data to be available followed by parseInt) trying to collect a second number will be unreliable until the problem above is resolved.

Vaclav:
However, the "rule" is to use Setup for stuff you want to do only once - initialize.

@delodephius specifically stated he wants to collect one (or two) numbers once. By your own "rule" his code belongs in setup.

Well do you have an idea then, coz I sure don't know what else to do.

To make something happen only once in the loop function. Modify as needed to run as many times as needed.

void loop(){

static boolean weDidThisAlready = false;  // Could have also been global
if ( ! weDidThisAlready){
     weDidThisAlready = true;

     // Now go do your one time thing inside this block.
     }

}

Well I wouldn't have thought of that. Thank you. :wink:

delodephius:
Well do you have an idea then, coz I sure don't know what else to do.

parseInt has a litany of problems; it does not even deserve to have "parse" in the method name.

Give this a try...

int getInt( const __FlashStringHelper * prompt )
{
  char ch;
  bool negative;
  int rv;

startover:
  Serial.print( prompt );
  negative = false;
  rv = 0;
  do
  {
    while ( ! Serial.available() );
    ch = Serial.read();
  }
  while ( (ch != '-') && (ch != '+') && ((ch < '0') || (ch > '9')) );
  
  if ( ch == '-' ) negative = true;
  
  if ( (ch =='-') || (ch == '+') )
  {
    Serial.print( ch );
    while ( ! Serial.available() );
    ch = Serial.read();
    if ( (ch < '0') || (ch > '9') ) 
    {
      Serial.println( F( "  Illegal input.  Try again." ) );
      goto startover;
    }
  }
  
  do
  {
    Serial.print( ch );
    rv = (10*rv) + (ch-'0');
    while ( ! Serial.available() );
    ch = Serial.read();
  }
  while ( (ch >= '0') && (ch <= '9') );

  Serial.println();
  
  if ( negative ) rv = -rv;
  
  return( rv );
}

void setup(){
  
  Serial.begin(9600);
  
}

void loop(){

    
  int num1, num2;
  num1 = getInt( F( "Enter the first number:  " ) );
  num2 = getInt( F( "Enter the second number: " ) );

  int sum = num1 + num2;
  
  Serial.print("The sum of ");
  Serial.print(num1);
  Serial.print(" and ");
  Serial.print(num2);
  Serial.print(" is ");
  Serial.print(sum);
  Serial.println();
  Serial.println();
  Serial.println();
}

You will have to set line ending to something other than "No line ending".

But instead the text "Enter a number: " was printed indefinitely.

You obviously didn't even bother to find out what loop() is actually for.

I haven't tried this code so I will assume it works.

I find it hard to think of anything likely to be more confusing for a beginner than including the initialization of a variable within loop(), expecting it not to re-initialize on each iteration of loop yet it is possible to change its value within loop().

For beginners it would be much more obvious if the flag variable was initialized within setup().
(For everyone actually - programs should be designed to be read occasionally)

...R

Delta_G:

void loop(){

static boolean weDidThisAlready = false;  // Could have also been global
if ( ! weDidThisAlready){
     weDidThisAlready = true;

// Now go do your one time thing inside this block.
     }

}

Second - the IDE sucks - why I cannot cut and paste stuff from the COM dialog? I guess nobody cares as long as it is quoted properly.

You have obviously never used a proper editor and rely on menus, icons and right click options :slight_smile:

Highlight the text you want to copy using the mouse and the left button then use Ctrl/C on the keyboard to copy the selected text to the clipboard ready to paste wherever you want (Ctrl/V by the way)