I have a program where the user should input several different setup values that will be stored in EEPROM, via a keypad and LCD. The entered data will be used as integers or float values and should not be zero.
If the enter key is pressed with no value being input, the associated variable defaults to zero which I don't want because it is often not suitable for later calculations.
In Microsoft Excel, we can very easily check for an empty input cell by the formula;
=IF(cell_name="", do something, do something else), or by using ISBLANK()
The point being that the double quotes "" indicate an empty cell or "null" and that value is not the same as 0.
Is there anything (simple) we can do similar to this in Arduino code / C/C++ to ensure that the user has input a valid value?
If not, I guess will need to write numerous lines of code to achieve this, but I am searching for an easier way.
If the enter key is pressed with no value being input, the associated variable defaults to zero which I don't want because it is often not suitable for later calculations.
someVariable = Serial.read();
if (someVariable == 0)
{
//no value entered. code here to deal with it
}
Please post your code or a working subset of it that shows the problem. What data types are you prompting the user for ?
arduino_new:
You can count how many digit the user has entered since last accepted or rejected input.
If the count == 0 then the user did not enter anything.
if (someVariable == 0)
{
//no value entered. code here to deal with it
}
Please post your code or a working subset of it that shows the problem. What data types are you prompting the user for ?
Sorry if I misled in the opening post. I suggested that zero was not allowed, in which case your suggested code would work. I know because I had already tried it but had to give up with it because for some settings, zero is a valid data input and it won't allow me to enter a zero value when I need to.
There is nothing really relevant to post in the way of code, it is a conceptual problem which is;
User presses a key,
Current setting is displayed together with a data entry box for new setting.
User (should) enter a value of some type
User presses enter
Input data is recorded
The problem is, if the user does not input anything, just presses enter then the variable defaults to zero which is not always desirable.
I have attached a photo of the input screen to help illustrate the situation.
If the keystrokes are first read into a Cstring that gets its terminating '\0' character when the user presses enter then you can use strlen() to check the length of it and atoi() or atof() to convert it to an interger or float as required.
Thanks for your responses guys, I really appreciate all your input.
UKHeliBob, I mentioned in my first post that the settings are a mix of integers of floats
Robin2, I am sure that will work but it is far too complex for what I need. All I wanted to do was check if the user had input anything before presser the enter key.
I finally went with the very simple concept that arduino_new came up with in reply #1
I have copied the important parts of the code below, other extraneous stuff has been deleted for clarity;
The important part is the integer "countKey" which checks if any keystrokes have been made with the numeric keys 0-9.
Then, when the # key is pressed to enter the new value, the value of countKey is checked. If it is zero, then the pre-existing value curVal is witten to EEPROM, otherwise the newly input value will be used.
In addition, using EEPROM.put() only writes to the EEPROM address if the value has actually changed - saves wear and tear on the memory.
Very simple in the end. Just used one integer, 3 lines of code and an if statement. Initially, my mind was thinking far too much complexity was needed until I got the nudge from arduino_new.
void putnewVal(int addr) { // Input New Setting *****
int countKey = 0; // Will be used to count keystrokes in case 0 to case 9
newVal = 0;
while (menSelect > 90 && menSelect < 100) {
key = kpd.getKey();
switch (key) {
//case NO_KEY:
// break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
countKey ++; // Increment the key counter for each digit pressed
newVal = newVal * 10 + (key - '0');
lcd.print(key);
break;
(Other stuff deleted from here)
case '#': // The ENTER key
if (countKey == 0) { // If no key presses were counted before pressing enter...
newVal = curVal; // ...use the current value as the new input value
}
EEPROM.put(addr, newVal); // Update the selected EEPROM address with new value
menSelect = 9;
break;
}
}
} // END PUTNEWVAL #################################
UKHeliBob, I mentioned in my first post that the settings are a mix of integers of floats
So what ?
If the user enters an invalid number then reject it or don't change the default. What if the user enters a single 0 ? Its length will be 1 so will it be regarded as valid ? What if the user enters 00000 or 9999999999 and so on ?
You must be checking somewhere that the number entered is valid and its length is not good enough to do that
archiebald:
Robin2, I am sure that will work but it is far too complex for what I need. All I wanted to do was check if the user had input anything before presser the enter key.
Interesting. To my mind it would be far simpler than what you are trying to do. But each to his own
If the user enters an invalid number then reject it or don't change the default. What if the user enters a single 0 ? Its length will be 1 so will it be regarded as valid ? What if the user enters 00000 or 9999999999 and so on ?
You must be checking somewhere that the number entered is valid and its length is not good enough to do that
In my particular case, if the user types in something, then realizes his error, he can use the D key to delete his entry and start again. Doing so will will also reset the length counter.
Also, in certain conditions, zero IS an acceptable input, that is why I couldn't simply reject the zero value that gets put into a memory location by default. I was simply looking for some input vs no input, that's the reason why I just asked for concepts rather focus on detailed code.
000000 and 9999999999 could be valid inputs for some of the cases in my particular usage. They wouldn't be very sensible, but they might be valid depending on the user's requirements.
In my particular case, validating the value range is not very helpful- the input settings have a wide range;
Gear ratio in the user's system (could be almost anything),
No of motor pulses per revolution (to suit user's stepper motor setup),
Direction system will move (0 = CW, 1 = CCW),
No of divisions to split up a circle into (zero not acceptable, but max value is almost infinite),
Degrees that the user wants to move (zero is utilized as infinite for constant movement so it is acceptable in this case, max value is almost no limit)
Number of revolutions to move (almost infinite possibilities depending on the user)
In my particular case, validating the value range is not very helpful- the input settings have a wide range;
Gear ratio in the user's system (could be almost anything),
No of motor pulses per revolution (to suit user's stepper motor setup),
Direction system will move (0 = CW, 1 = CCW),
No of divisions to split up a circle into (zero not acceptable, but max value is almost infinite),
Degrees that the user wants to move (zero is utilized as infinite for constant movement so it is acceptable in this case, max value is almost no limit)
Number of revolutions to move (almost infinite possibilities depending on the user)
I think that you have made your own case for validating the value entered by the user. Take "No of divisions to split up a circle into (zero not acceptable, but max value is almost infinite)," What happens if the user enters zero in that case ? The length will be 1 so you would regard it as valid. Would the code crash with a value of zero ? Do you perhaps divide by the value returned ?
I think that your approach is flawed, and that if you are going to use a general purpose input routine, which is a good idea, then you should pass max and min value parameters to it and return either the value entered, if within range, stay in the function until a valid value is entered or return an impossible value such as -1 and act on it as invalid.
UKHeliBob:
I think that you have made your own case for validating the value entered by the user. Take "No of divisions to split up a circle into (zero not acceptable, but max value is almost infinite)," What happens if the user enters zero in that case ? The length will be 1 so you would regard it as valid. Would the code crash with a value of zero ? Do you perhaps divide by the value returned ?
I think that your approach is flawed, and that if you are going to use a general purpose input routine, which is a good idea, then you should pass max and min value parameters to it and return either the value entered, if within range, stay in the function until a valid value is entered or return an impossible value such as -1 and act on it as invalid.
In a couple of cases I am in fact using 0 to indicate infinite movement and I have other code that checks for that very thing. In this case a stepper motor will rotate continuously, i.e. it will travel an infinite number of degrees and will only stop with user intervention.
My sole purpose here was that I didn't want zero being input as an unintended action of the user pressing enter without having made a conscious decision to enter zero.