Вывод случайных чисел/последовательности

Программа, которую я пытаюсь создать:

  1. Введите первое имя, нажмите «Ввод», введите второе имя и снова нажмите «Ввод».
  2. Зарегистрируйте эти имена из строкового ввода в char naming в структуре student.
  3. Распечатайте имена на последовательном мониторе.
  4. Используйте эти имена в основной программе.

Проблема в том, что каждый раз, когда я вводил имена, я получал рандомизированные результаты.

Мой целевой результат:

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

Заранее спасибо!

, 👍0

Обсуждение

измените ++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


1 ответ


Лучший ответ:

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!

,