multi digit inputs and masked inputs while using Hyper Terminal

I’m very frustrated. I’m very new to arduino and having lots of trouble. I took a class in C++ about 5 years ago but have probably forgotten more than I remember. I’ve looked at several examples and tutorials yet I can’t seem to find simple answers to my simple questions. My project is 90% software and most examples online involve wiring up a bunch of buttons and LEDs. What I would like is someone who could basically walk me through some stuff to get me started. Yes, hand holding. I’ve been struggling with trying to decipher “helpful hints” and search the web for a couple weeks and am about ready to just quit. Can someone please help?

The basic questions: I wish to use an uno to accept and store data to be retrieved or updated later. For instance upon initializing the program typing “I” would display an ID number which can be saved or modified. Typing “M” would display a Model number which can also be saved or modified. Here is my code so far…

int long ID = 10000000;
int long ModelNumber = 0;
String readString;

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

if (Serial.available() > 0) {

int incomingByte = Serial.read();

switch(incomingByte){

case ‘I’:

Serial.print (“ID number is      “);
Serial.print (ID);
while(Serial.available() == 0)
{
// Causes the program to wait for the next input
}
//Following while statement and if statement make
//that input into a string

while (Serial.available())
{
delay(2);
char c = Serial.read();
readString += c;
}
if (readString.length()>0)
{
char carray[readString.length() + 1];
readString.toCharArray(carray,sizeof(carray));
long f = atol(carray);
ID = f;
readString = “”;
readString[8];
}
Serial.print (“    “);
Serial.println (ID);
Serial.print (“ID number is now   “);
Serial.println (ID);
break;

case ‘M’: 

Serial.print (“Input model number.       “);
while(Serial.available() == 0)
{
// Causes the program to wait for the next input
}
//Following while statement and if statement make
//that input into a string

while (Serial.available())
{
delay(2);
char c = Serial.read();
readString += c;
}
if (readString.length()>0)
{
char carray[readString.length() + 1];
readString.toCharArray(carray,sizeof(carray));
long f = atol(carray);
ModelNumber = f;
readString = “”;
readString[8];
}
Serial.println (ModelNumber);
Serial.print (“Model number is now   “);
Serial.println (ModelNumber);
break;

default:
Serial.println (“Invalid entry. Enter I or M to set ID or Model numbers.”);
}
}
}

A few problems…first of all I wish to access this program through HyperTerminal which recognizes each key stroke. So the program asks to input a model number and if I wish to put in “54321” as soon as I hit the 5 it updates the model number and any entry after that result in the default error message.
Second, I would like to mask the inputs so that inputs must be numeric and of a specific number of digits or they won’t be accepted.
Of course I have other issues that are bugging me but if I could get some help with those two to begin with, I would feel a lot better about the entire project.

int long ID = 10000000;

You need to start with the Reference page. An int on the Arduino can not hold that value.

String readString;

Do NOT go there. C-style strings, NULL terminated arrays of chars, are easy to use, and do not suffer the issues of Strings. Remember, you have much less memory on the Arduino than on a PC.

while (Serial.available())
{
delay(2);
char c = Serial.read();

We know that there is data to read. So, lets sit around for a while doing nothing before we actually read the data. Why would we do that?

readString[8];

OK. Why? What do you think this is doing?

A few problems…first of all I wish to access this program through HyperTerminal which recognizes each key stroke. So the program asks to input a model number and if I wish to put in “54321” as soon as I hit the 5 it updates the model number and any entry after that result in the default error message.

So, what is the problem? Really, I think you would be better of writing an application on the PC that gets the data you want, does the validation, etc. and just sends valid data to the Arduino.

“int long ID = 100000000” allows the initial response upon first typing “I” to display an 8 digit number, namely “10000000”. You are right that “int” will not handle that size of a number and that’s why I use “int long”.

“delay (2)” doesn’t seem to make any noticeable difference when using Hyper Terminal to run the program, however when removed if I run the program viewing it through the serial monitor, no more than 1 digit of the new number I enter will be recognized.

As to why I can’t just have my PC programed to do all this… Hypothetically, there are 5000 widgets which are serviced by multiple service men. The widgets run on 1970s technology and I wish to upgrade them by installing a preprogramed Uno in each one. I would like to do this without affecting the menus that the service men use to program the widgets and not have to upgrade each service man’s PC.
Another issue that’s making me scratch my head is that I don’t want to have to have to enter a new ID number each time I select “I”. I’m having no luck trying to get if statements to function within my case. Any help would be appreciated.

Im-just-Rusty:
You are right that “int” will not handle that size of a number and that’s why I use “int long”.

Just use "long", it is less confusing.

Im-just-Rusty:
“delay (2)” doesn’t seem to make any noticeable difference when using Hyper Terminal to run the program, however when removed if I run the program viewing it through the serial monitor, no more than 1 digit of the new number I enter will be recognized.

The location of the delay() is why you see a difference, not its presence. Paul's point is there is no reason to wait right after checking Serial.available. You already have characters there. Instead of deleting it, move it to the end of the while() loop and you probably won't see a behavior change.

As for do you actually need the delay, the is probably a non-obvious reason why you see a difference. Hyperterminal sends characters as you type them. You're slow at typing, at least to the Arduino you are. Serial Monitor sends them one right after another, which is much faster than you.

You should really be detecting when you get a new line character or some other delimiter and not basing the receiving on time which will almost always vary.

Im-just-Rusty:
Another issue that’s making me scratch my head is that I don’t want to have to have to enter a new ID number each time I select “I”. I’m having no luck trying to get if statements to function within my case. Any help would be appreciated.

You need to investigate state machines.

“delay (2)” doesn’t seem to make any noticeable difference when using Hyper Terminal to run the program, however when removed if I run the program viewing it through the serial monitor, no more than 1 digit of the new number I enter will be recognized.

The issue is that you are treating a packet as "all the data that arrives while I'm diddling around" as opposed to having recognizable start- and end-of-packet markers, and reading (and storing) all the data until the end of packet marker (whatever that is) arrives, whenever that is.

A few problems…first of all I wish to access this program through HyperTerminal which recognizes each key stroke. So the program asks to input a model number and if I wish to put in “54321” as soon as I hit the 5 it updates the model number and any entry after that result in the default error message.

The code with the delay works with the serial monitor because the string is sent when the enter key is depressed. Try the below code with hyperterminal. The arduino will capture the characters sent until it receives a "," that is used to mark the end of the string, at which time the captured string will be sent back to hyperterminal.

//zoomkat 3-5-12 simple delimited ',' string parce 
//from serial port input (via serial monitor)
//and print result out serial port
// CR/LF could also be a delimiter

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial delimit test 1.0"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like wer,qwe rty,123 456,hyre kjhg,
  //or like hello world,who are you?,bye!,
  
  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      //do stuff
      Serial.println(readString); //prints string to serial port out
      readString=""; //clears variable for new input      
     }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Thanks everyone. This gives me some stuff to think about and play with this weekend. :slight_smile: