The program I'm trying to build is:
- Type in 1st name, hit enter, type in 2nd name and then hit enter again.
- Register those names from string input to char
naming
instudent
struct. - Print out the names in serial monitor.
- 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!
1 Answer 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!
++i
toi++
if(int i; i<2; i++)
to no avail...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