0

The program I'm trying to build is:

  1. Type in 1st name, hit enter, type in 2nd name and then hit enter again.
  2. Register those names from string input to char naming in student struct.
  3. Print out the names in serial monitor.
  4. Use those names in the main program.

The problem is I got randomize results whenever I typed in the names.

My target output:

Program Starts
Insert 2 students name:
First student: Adam //When input -> Adam
Second student: Eve //When input -> Eve
First student: John //When input -> John
Second student: Amy //When input -> Amy
//the sequences should repeat

...but what happened is the sequences of the names randomized. For example:

Program Starts
Insert 2 students name:
First student: Adam
First student: Eve
Second student: John
First student: Amy
//the sequences will keep randomizing

Can anyone point out what I've missed out?

The program:

typedef struct
 {
 char naming[20]; 
 }student;
 student record[]{
 {""},
 {""},
 };
 String readString;
 String str=""; 
 // the setup routine runs once when you press reset:
 void setup() {
 Serial.begin(9600); // initialize serial communication at 9600 bits per second
 while (!Serial); // wait for Serial Monitor to open
 SerialUSB.println("Program Starts \n Insert 2 students name:"); // Title of sketch 
 }
 void loop() {
 namedata();
 mainprg();
 }
 void namedata() 
 {
 for(uint8_t i = 0; i < sizeof(record)/sizeof(student); i++){
 while (Serial.available()) {
 char c = Serial.read();
 readString += c;
 readString.trim();
 }
 if (readString.length() >0) {
 str = readString;
 str.toCharArray(record[i].naming,20);
 if(i==0){
 Serial.print("First student: ");
 }else if(i==1){ 
 Serial.print("Second student: ");
 }
 Serial.println(record[i].naming); 
 }
 readString="";
 } 
 }
 void mainprg()
 {
 //main program using student`s name
 }

Additional infos:

1.Why use struct? Because I've more data to process/store for one "student" in my main program. 2.Currently using Arduino Yun Mini, Arduino 1.8.7

Thanks in advance!

asked Jan 28, 2019 at 5:02
8
  • change ++i to i++ Commented Jan 28, 2019 at 6:07
  • @Juraj Nope still the same, though I also tried if(int i; i<2; i++) to no avail... Commented Jan 28, 2019 at 6:24
  • your algorithm for reading the names is based on misunderstanding how Serial input works Commented Jan 28, 2019 at 7:30
  • @Juraj I would appreciate it if you can point me to any info on the topic Commented Jan 28, 2019 at 7:46
  • 3
    The problem, that Juraj mentioned, is that you seem to think, that all the data from one name input will arrive as a big chunk, so that the while loop will only exit, when a full name has been read. That is not the case. There might be pauses between arbitrary bytes in the stream, for example introduced from the OS of the PC. The while loop will often exit, before a full name is read. You can use the something like the readline function here: majenko.co.uk/blog/reading-serial-arduino Commented Jan 28, 2019 at 14:45

1 Answer 1

1

Even though this is not elegant by any means, for now this is what I've came out with:

typedef struct
{
 char naming[20];
} student;
student record[] {
 {""},
 {""},
};
int a = 0;
char buf[20];
// the setup routine runs once when you press reset:
void setup() {
 Serial.begin(9600); // initialize serial communication at 9600 bits per second
 while (!Serial); // wait for Serial Monitor to open
 Serial.println("Program Starts \n Insert 2 students name:"); // Title of sketch
}
void loop() {
 if (readline(Serial.read(), buf, 20) > 0) {
 if (a == 0) {
 Serial.print("First student: ");
 strncpy(record[a].naming, buf, 20);
 Serial.println(record[a].naming);
 a = 1;
 }
 else if ( a == 1) {
 Serial.print("Second student: ");
 strncpy(record[a].naming, buf, 20);
 Serial.println(record[a].naming);
 }
 }
}
int readline(int readch, char *buffer, int len) {
 static int pos = 0;
 int rpos;
 if (readch > 0) {
 switch (readch) {
 case '\r': // Ignore CR
 break;
 case '\n': // Return on new-line
 rpos = pos;
 pos = 0; // Reset position index ready for next time
 return rpos;
 default:
 if (pos < len - 1) {
 buffer[pos++] = readch;
 buffer[pos] = 0;
 }
 }
 }
 return 0;
}

Basically by using int a, the program decides the sequences of the name. Although it will not repeat the sequence after the 2nd input (ie 1st>2nd>1st>2nd), at least the sequence is not randomize anymore.

Btw thanks for the tips @chrisl!

answered Jan 31, 2019 at 1:03

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.