Help understanding why Serial.println does not work inside an if

Hello, Im starting a proyect in wich I connect a coin acceptor to my arduino uno through a sofware serial port (pin 2) to see the inserted coin values in the serial monitor. Here is the code that doesn't work as I want:

#include <SoftwareSerial.h>
SoftwareSerial mon(2,4); // RX, TX, rx recibe
int valor=0;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
mon.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:

if(mon.available()>0)
{
valor+=(mon.read())*10;
Serial.println(valor);

}
else mon.read();

}

The problem I've been having is that when I put a coin, nothing shows on the serial monitor.
So I tried to put the Serial.println(valor); line outside the "if" to see if the value of the "valor" variable was really changing.

#include <SoftwareSerial.h>
SoftwareSerial mon(2,4); // RX, TX, rx recibe
int valor=0;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
mon.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:

if(mon.available()>0)
{
valor+=(mon.read())*10;


}
else mon.read();
Serial.println(valor);
}

In this case, with the code line outside it works with no problem as you can see in the image here.

My question is why it doesn't work. I wanted the value to show just once. And only printing on the serial monitor when I insert the coin, instead of that the monitor shows an endless stream of values.

Thanks

Try to use

if(mon.available())

Instead of

if(mon.available()>0)

What is the purpose of this line:

else mon.read();

If nothing is available in the input buffer, then there is no reason to read it, and you take a chance on a character being received between the test of mon.available() and this mon.read() , which would then read the character and throw it away.

if(mon.available()>0)
{
valor+=(mon.read())*10;
Serial.println(valor);

}
//else mon.read();

It makes no sense to read from software serial if there is nothing available to be read.

What is the coin acceptor sending to the Arduino? Is there code for that device?

david_2018:
What is the purpose of this line:

else mon.read();

If nothing is available in the input buffer, then there is no reason to read it, and you take a chance on a character being received between the test of mon.available() and this mon.read() , which would then read the character and throw it away.

Actually, I deleted that line and the program works as intended, so thanks!!

That line originally was in there because an issue with the coin acceptor, it's not my program, but the author explains it in the code:

void loop()
{
  // Cashola is the variable which stores the amount of money received. Each
  //  cent dropped in increases cashola by one. By making it a static variable,
  //  I ensure that it persists from one loop() iteration to the next without
  //  making it a global variable.
  static unsigned int cashola = 0;
  
  // Check for any input from the coin acceptor. The coin acceptor outputs a
  //  simple binary value representing the value of the coin inserted; in this
  //  case, I've set it equal (on the coin acceptor) to the value of the coin
  //  in cents.
  if (coinInput.available() > 0)
  {
    // Oddly enough, for nickels and dimes, the data coming out of the coin
    //  acceptor has a framing error: the last bit is a little too long. The
    //  SoftwareSerial receive function doesn't seem to wait for the stop bit
    //  (which will always be one), so it starts another read when it sees the
    //  extra long final bit, then reads all ones, which is interpreted as -1.
    //  We want to reject any result which is -1, since that's a nonsense coin
    //  value anyway.
    if (coinInput.peek() != -1) 
    {
      cashola += coinInput.read();
      Serial.println(cashola);
    }
    else coinInput.read();
  }

I didn't have this problem so I deleted that part, but leave the problematic line.

cattledog:

if(mon.available()>0)

{
valor+=(mon.read())*10;
Serial.println(valor);

}
//else mon.read();




It makes no sense to read from software serial if there is nothing available to be read.

What is the coin acceptor sending to the Arduino? Is there code for that device?

The coin acceptor is sending the coin values directly, is sending 01, 05, 10, and 50. According to the datasheet is RS232, but is a 5V signal. And only sends the data when a coin is inserted.

Im not quite sure why it worked tough , but I suppose it has to do with what david_2018 said. If someone can elaborate on this I would really appreciate it.

Again thanks for the help!

Regards

The original code uses .peek() to look at the character in the serial buffer without removing the character from the buffer, then either reads it as a valid coin value, or reads the -1 to remove it from the buffer. That entire segment of code is within the if statement that checks .available()

david_2018:
or reads the -1 to remove it from the buffer.

You can not remove -1 from the buffer.
There never is -1 in the buffer, -1 is returned when there is nothing in the buffer.