Вывод случайных чисел/последовательности
Программа, которую я пытаюсь создать:
- Введите первое имя, нажмите «Ввод», введите второе имя и снова нажмите «Ввод».
- Зарегистрируйте эти имена из строкового ввода в char
naming
в структуреstudent
. - Распечатайте имена на последовательном мониторе.
- Используйте эти имена в основной программе.
Проблема в том, что каждый раз, когда я вводил имена, я получал рандомизированные результаты.
Мой целевой результат:
Program Starts
Insert 2 students name:
First student: Adam //При вводе ->gt; Адам
Second student: Eve //При вводе ->gt; Канун
First student: John //При вводе ->gt; Джон
Second student: Amy //При вводе ->> Эми
//последовательности должны повторяться
...но произошло то, что последовательности имен были рандомизированы. Например:
Program Starts
Insert 2 students name:
First student: Adam
First student: Eve
Second student: John
First student: Amy
//последовательности будут продолжать рандомизироваться
Может ли кто-нибудь указать, что я упустил?
Программа:
typedef struct
{
char naming[20];
}student;
student record[]{
{""},
{""},
};
String readString;
String str="";
// процедура настройки запускается один раз, когда вы нажимаете кнопку сброса:
void setup() {
Serial.begin(9600); // инициализируем последовательную связь со скоростью 9600 бит в секунду
while (!Serial); // ждем открытия Serial Monitor
SerialUSB.println("Program Starts \n Insert 2 students name:"); // Название скетча
}
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()
{
//основная программа, использующая имя студента
}
Дополнительная информация:
1. Зачем использовать структуру? Потому что мне нужно обрабатывать/хранить больше данных для одного «студента» в моей основной программе. 2.В настоящее время используется Arduino Yun Mini, Arduino 1.8.7
Заранее спасибо!
1 ответ
Лучший ответ:
Хотя это ни в коем случае не выглядит элегантно, на данный момент у меня получилось вот что:
typedef struct
{
char naming[20];
} student;
student record[] {
{""},
{""},
};
int a = 0;
char buf[20];
// процедура настройки запускается один раз, когда вы нажимаете кнопку сброса:
void setup() {
Serial.begin(9600); // инициализируем последовательную связь со скоростью 9600 бит в секунду
while (!Serial); // ждем открытия Serial Monitor
Serial.println("Program Starts \n Insert 2 students name:"); // Название скетча
}
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': // Игнорировать CR
break;
case '\n': // Возврат на новую строку
rpos = pos;
pos = 0; // Сбрасываем индекс позиции, готовый к следующему разу
return rpos;
default:
if (pos < len - 1) {
buffer[pos++] = readch;
buffer[pos] = 0;
}
}
}
return 0;
}
По сути, используя int a
, программа определяет последовательность имен. Хотя последовательность не будет повторяться после второго ввода (т. е. 1-й>2-й>1-й>2-й), по крайней мере, последовательность больше не рандомизируется.
Кстати, спасибо за советы @chrisl!
- Arduino wrap или подкласс print() для работы с несколькими Serial
- Ведение журнала всех вызовов Serial.print на устройстве
- Как запрограммировать ардуино на чистом C/C++?
- Arduino Преобразование std:string в String
- Почему эта программа на C++ не может прочитать Serial.write() моего arduino?
- Как работает последовательная связь на Arduino?
- Как связаться с ESP8266 ESP01, отправив данные через программный сериал на Arduino Uno?
- RtcDateTime' не называет тип
измените
++i
наi++
, @Juraj@Juraj Нет, все то же самое, хотя я тоже пробовал
if(int i; i<2; i++)
, но безрезультатно..., @Samir Izmier Chongваш алгоритм чтения имен основан на непонимании того, как работает последовательный ввод, @Juraj
@Юрай, я был бы признателен, если бы ты указал мне любую информацию по этой теме., @Samir Izmier Chong
Проблема, о которой упомянул Юрай, заключается в том, что вы, кажется, думаете, что все данные из одного ввода имени будут поступать как большой кусок, так что цикл while завершится только после того, как будет прочитано полное имя. Это не относится к делу. Между произвольными байтами в потоке могут быть паузы, например введенные из ОС ПК. Цикл while часто завершается до того, как будет прочитано полное имя. Вы можете использовать что-то вроде функции readline здесь: https://majko.co.uk/blog/reading-serial-arduino ., @chrisl
@chrisl Спасибо за ссылку. Теперь я (отчасти) понимаю, как работает
Serial.read
, но я все еще не могу приостановить цикл до тех пор, пока не будет введено второе имя, и зарегистрировать его вrecord[i].naming
, таким образом, случайные последовательности, вызванные случайным выходом из цикла., @Samir Izmier ChongПочему вы используете SerialUSB в функции настройки, а Serial — в остальной части кода? Я не уверен, что происходит на Arduino только с одним последовательным интерфейсом при использовании SerialUSB, но на других платах (насколько я помню, например, Due) это совершенно разные интерфейсы. Хотя я не понимаю, как благодаря этому можно получить такой рандомизированный порядок., @chrisl
@chrisl Насчет SerialUSB вы правы; это то же самое, что и [
Serial
](http://forum.arduino.cc/index.php?topic=402933.0). Что касается рандомизированного порядка, мне самому интересно, что ¯\_(ツ)_/¯, @Samir Izmier Chong