Serial.available()

I want to know does Serial.available cannot be in the setup() function or what? because every time I put the function call that has Serial.available in it, it cannot be compile. But when I moved to the loop() it runs perfectly.

Nope, that function works perfectly fine in any function. There's nothing special about setup other than the fact that it is only called once. You can put any line in there that will work in any other function. You've made a mistake when you wrote it in the setup function. What that mistake was is anyone's guess at this point because you chose not to show the code or the error it produced.

My guess is that there's more than just one line of code that you're moving between setup() and loop() and maybe in the move you're leaving something behind. Perhaps you have an if(Serial.available()...){...} and in the if block you have a variable which has scope in loop() not in setup().

But that's a guess: As Delta_G said, with no code or error posted, who knows?

Below is the code. I want the user input just once. So that is why I put it in the setup(). Unfortunately it didnt work. Can you help me?

const int analogPin = A0;
const int sensorPhoto = 53;
const int sampleSize = 100;

// for user response
const byte numChars = 32;
char userResponse[numChars];
const char endMarker = '\n';
static byte bytesRecvd = 0;
boolean ackResponse = true;
char dataNumber;
float grams = 0.0;

// for raw ranges
int xVoltage;


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

  // Ask user input
  Serial.println("Place egg on the scale and type its weight in grams, then press enter.");
 getUserResponse();
  acknowledgeResponse();
}

void loop()
{

}

void getUserResponse()
{
  if (Serial.available() > 0) {
    dataNumber = Serial.read();

    if (dataNumber != endMarker) {
      userResponse[bytesRecvd] = dataNumber;
      bytesRecvd++;
      if (bytesRecvd >= numChars) {
        bytesRecvd = numChars - 1;
      }
    }
    else {
      userResponse[bytesRecvd] = '\0'; // terminate the string
      bytesRecvd = 0;
      ackResponse = false;
    }
  }

}

void acknowledgeResponse()
{
  if (ackResponse == true)
  {
    return;
  }
  grams = 0.0;
  grams = atof(userResponse);
  Serial.print("Weight (grams) : ");
  Serial.println(grams);
  ackResponse = false;
}

You already have a thread on your egg measurements project... keep everything in one place

When you run the arduino - for your code to kinda work - you would need to send very quickly something on the Serial line and you would only get 1 char... getUserResponse() does not really get anything meaningful , probably not what you expect

You will need a loop in setup that loops till a weight has been entered.

I did not quite follow your other thread. I think the purpose of this is to have a reference weight.

So in loop() you can keep a flag. As long as it's false, the user needs to enter a reference weight. Once that's done, set the flag to true and start doing the normal weighing of the eggs.

how do i keep the flag? can u show me?

here is an example (untested juste typed it in) on how to build an unsigned integer from the user input by possibly keeping a default value from the setup() to be executed only once

Also example on how to have a similar input from the loop with a flag to only ask once. After the data has been asked once in the loop, then it is just printing hello every second.

You need to set the console at 115200 bauds, and make sure to send the CR+LF or LF after the user input in the console.

The function to read the user input expects an unsigned long int as parameter, and I’m passing the argument by reference. The functions only deals with digits and ‘\n’ so if you enter 12[color=red]abc[/color]345, it will read this as a value of 12345 and just ignore the [color=red]abc[/color]

// Make sure Console settings are set to send '\n' 

unsigned long initialWeight;
unsigned long otherWeight;

// if user just enters '\n' then we don't change the value
void getUserInput(unsigned long& w)
{
  boolean waitingForNumber = true;

  while (true) {
    if (Serial.available()) {
      char c = Serial.read(); // we don't need to deal with the -1 if error
      if (c == '\n') break; // user validated input
      if ((c >= '0') && (c <= '9')) { // ignore all other data
        if (waitingForNumber) {
          waitingForNumber = false;
          w = (c - '0');          // replace default value
        } else {
          w = 10 * w + (c - '0'); // build the int
        }
      }
    }
  }
}

void setup() {
  Serial.begin(115200);
  initialWeight = 222; // default value

  Serial.print(F("Enter initial weight in grams (default="));
  Serial.print(initialWeight);
  Serial.println(F(")"));

  getUserInput(initialWeight);

  Serial.print(F("The user entered: "));
  Serial.println(initialWeight);
}

void loop() {
  static boolean alreadyAsked = false;
  if (!alreadyAsked) {
    alreadyAsked = true;
    otherWeight = 666; // default value

    Serial.print(F("Enter Other weight in grams (default="));
    Serial.print(otherWeight);
    Serial.println(F(")"));

    getUserInput(otherWeight);

    Serial.print(F("The user entered: "));
    Serial.println(otherWeight);
  } else {
    // here you can do other stuff
    delay(1000);
    Serial.println(F("hello"));
  }
}

Serial.print(F("Enter initial weight in grams (default="));

What does F means?

Version 1.0 of the Arduino IDE introduced the F() syntax for storing strings in flash memory rather than RAM. e.g.

http://playground.arduino.cc/Learning/Memory

.

I think that because you are trying to enter calibration data in setup() it is OK to use the blocking function of Serial.parseFloat() to pick up the input. The user needs to confirm the entered value, and if they do not, the program asks for the calibration value again. I have added a utility function to clear an CR or LF entries which can create problems when the calibration value is re-entered.

const int analogPin = A0;
const int sensorPhoto = 53;
const int sampleSize = 100;
float grams = 0.0;

// for raw ranges
int xVoltage;

void setup()
{
  Serial.begin(9600);
  // get user input for calibration
  getUserResponse();
}

void loop()
{}

void getUserResponse()
{
  Serial.println("Place egg on the scale and type its weight in grams, then press enter.");
  clearInput();//clear any CR/LF
  while (Serial.available() <= 0) {}//wait for serial input of calibration value
  grams = Serial.parseFloat();
  clearInput();//clear any CR/LF
  acknowledgeResponse();
}

void acknowledgeResponse()
{
  Serial.print("Weight (grams) : ");
  Serial.println(grams);
  acceptCalibration();
}

void acceptCalibration()
{
  Serial.println("Is this the correct weight? Enter Y or N");
  clearInput();
  while (Serial.available() <= 0){} //wait for serial input of acceptance
  if (Serial.read() == 'Y')
    Serial.println("Calibration Weight Accepted");
  else
  {
    clearInput();
    getUserResponse();
  }
}

//utility function to discard NL/CR
void clearInput()
{
  while (Serial.available())
  {
    Serial.read();//throw away any terminating character
    delay(5);//see if there's another
  }
}

@cattledog the challenge with your code is that the user cannot press only return to accept the default value - hence the code I posted above.

Also the canned functions have a timeout so can return 0 if the user is slow - which could be an acceptable value (not for an egg weight but in generalà and you don't really know if the input timed out or if the user forgot to send the data by pressing return

Also the canned functions have a timeout so can return 0 if the user is slow - which could be an acceptable value (not for an egg weight but in generalà and you don’t really know if the input timed out or if the user forgot to send the data by pressing return

The routine I provided waits for serial input before any entry with

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

If the user doesn’t enter anything, the program does not time out and proceed, it halts. I thought this was a good thing if the OP is trying to force a calibration.

the user cannot press only return to accept the default value

In the OP’s code, I don’t see any default value from setup. grams is initialized to zero. From your’s and strerretje’s comments it appears there is another thread on these eggs which I have not seen. I may have missed a critical requirement.

Good point about waiting indeed, so no timeout. yes this is the problem with two threads (I hate that!) this was mentionned somewhere else and OP ask was how to differentiate timeout, from a valid 0 entry from just a return