Wile (!serial) как это работает?

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Прошу прощения за такой глупый вопрос, но я запутался.
При подключении тройка модуля GPS к Mega2560 предлагается такой код:
Setup:
void setup()
{
  // открываем последовательный порт для мониторинга действий в программе
  // и передаём скорость 9600 бод
  Serial.begin(9600);
  // ждём, пока не откроется монитор последовательного порта
  // для того, чтобы отследить все события в программе
  while (!Serial) {
  }
  Serial.print("Serial init OK\r\n");
  // открываем Serial-соединение с GPS-модулем на скорости 115200 бод
  GPS_SERIAL.begin(115200);
  // печатаем строку
  Serial.println("GPS init is OK on speed 115200");
  // изменяем скорость обещение GPS-модуля с управляющей платой на 9600 бод
  // используем NMEA-команду «$PMTK251,9600*17\r\n»
  GPS_SERIAL.write("$PMTK251,9600*17\r\n");
  // закрываем Serial-соединение с GPS-модулем
  GPS_SERIAL.end();
  // открываем Serial-соединение с GPS-модулем на скорости 9600 бод
  GPS_SERIAL.begin(9600);
  // печатаем строку
  Serial.print("GPS init is OK on speed 9600");
}
Если сериал не открыт функция возвращает False со знаком "!" это будет True. - код выполнится.
Если сериал открыт функция возвращает True со знаком "!" это будет False. - код невыполнится.
А как мы данные увидим в мониторе если код выполняется когда он закрыт??? -А-А-А-А-А-А-А-А
Помогите, где я не правильно понял?
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
@prohor-nastya,
пока (портНеОткрыт == истина) {
крутимПустойЦикл;
}
выходимИзПустогоЦиклаИПродолжаемВыполнениеПрограммы;
Ну да,
я не могу понять как мы видим в мониторе порта например, это :
Serial.print("Serial init OK\r\n");
если он не открыт, а когда он открыт мы выходим из цикла...
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Цикл будет продолжаться пока порт не будет открыт, сколько бы времени это не заняло. Каждый раз по завершению цикла порт на открытие проверяется заново.
 

kostyamat

★★★★★★✩
29 Окт 2019
1,097
630

@prohor-nastya,
Если сериал не открыт функция возвращает False со знаком "!" это будет True. - код выполнится
Это же условие, а не возврат значения или присвоение. Тут это работает не так.
Тут выражение !Serial аналогично "крутимся пока Serial == false". А вот то же выражение в
bool val = false;
return !val
вернет инверсию переменной val, не изменяя ее значение, то есть true.
A присвоение
val = !val
изменит саму переменную на противоположное логическое значение (переключит на оборот, инвертирует). Так что код правильный :)
 
Изменено:

Александр Симонов

★★★★✩✩✩
2 Авг 2018
727
207
Ну да,
я не могу понять как мы видим в мониторе порта например, это :
Serial.print("Serial init OK\r\n");
если он не открыт, а когда он открыт мы выходим из цикла...
Из какого цикла по-твоему мы выходим по достижении условия Serial, и куда идём дальше?
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Конкретней, какая строчка будет выполняться следующей после выхода из цикла?
Вот этот полный код.
Ну если условие не выполняется то выходим из цикла и после выхода из цикла выполняется void loop()...?

GPS:
// библиотека для работы с GPS устройством
#include <TroykaGPS.h>
 
// библиотека для работы программного Serial
#include <SoftwareSerial.h>
 
// создаём объект для работы с программным Serial
// и передаём ему пины TX и RX
SoftwareSerial mySerial(4, 5);
 
// serial-порт к которому подключён GPS-модуль
#define GPS_SERIAL    mySerial
 
// создаём объект класса GPS и передаём в него объект GPS_SERIAL
GPS gps(GPS_SERIAL);
 
// задаём размер массива для времени, даты, широты и долготы
#define MAX_SIZE_MASS 16
// массив для хранения текущего времени
char strTime[MAX_SIZE_MASS];
// массив для хранения текущей даты
char strDate[MAX_SIZE_MASS];
// массив для хранения широты в градусах, минутах и секундах
char latitudeBase60[MAX_SIZE_MASS];
// массив для хранения долготы в градусах, минутах и секундах
char longitudeBase60[MAX_SIZE_MASS];
 
void setup()
{
  // открываем последовательный порт для мониторинга действий в программе
  // и передаём скорость 9600 бод
  Serial.begin(9600);
  // ждём, пока не откроется монитор последовательного порта
  // для того, чтобы отследить все события в программе
  while (!Serial) {
  }
  Serial.print("Serial init OK\r\n");
  // открываем Serial-соединение с GPS-модулем на скорости 115200 бод
  GPS_SERIAL.begin(115200);
  // печатаем строку
  Serial.println("GPS init is OK on speed 115200");
  // изменяем скорость обещение GPS-модуля с управляющей платой на 9600 бод
  // используем NMEA-команду «$PMTK251,9600*17\r\n»
  GPS_SERIAL.write("$PMTK251,9600*17\r\n");
  // закрываем Serial-соединение с GPS-модулем
  GPS_SERIAL.end();
  // открываем Serial-соединение с GPS-модулем на скорости 9600 бод
  GPS_SERIAL.begin(9600);
  // печатаем строку
  Serial.print("GPS init is OK on speed 9600");
}
 
void loop()
{
  // если пришли данные с gps-модуля
  if (gps.available()) {
    // считываем данные и парсим
    gps.readParsing();
    // проверяем состояние GPS-модуля
    switch(gps.getState()) {
      // всё OK
      case GPS_OK:
        Serial.println("GPS is OK");
        // выводим координаты широты и долготы
        // 1. в градусах, минутах и секундах
        // 2. градусах в виде десятичной дроби
        Serial.println("GPS Coordinates: ");
        gps.getLatitudeBase60(latitudeBase60, MAX_SIZE_MASS);
        gps.getLongitudeBase60(longitudeBase60, MAX_SIZE_MASS);
        Serial.print("Latitude\t");
        Serial.print(latitudeBase60);
        Serial.print("\t\t");
        Serial.println(gps.getLatitudeBase10(), 6);
        Serial.print("Longitude\t");
        Serial.print(longitudeBase60);
        Serial.print("\t\t");
        Serial.println(gps.getLongitudeBase10(), 6);
        // выводим количество видимых спутников
        Serial.print("Sat: ");
        Serial.println(gps.getSat());
        // выводим текущую скорость
        Serial.print("Speed: ");
        Serial.println(gps.getSpeedKm());
        // выводим высоту над уровнем моря
        Serial.print("Altitude: ");
        Serial.println(gps.getAltitude());
        // выводим текущее время
        Serial.print("Time: ");
        gps.getTime(strTime, MAX_SIZE_MASS);
        gps.getDate(strDate, MAX_SIZE_MASS);
        Serial.write(strTime);
        Serial.println();
        // выводим текущую дату
        Serial.print("Date: ");
        Serial.write(strDate);
        Serial.println("\r\n");
        // каждую переменную дату и времени можно выводить отдельно
  /*    Serial.print(gps.getHour());
        Serial.print(gps.getMinute());
        Serial.print(gps.getSecond());
        Serial.print(gps.getDay());
        Serial.print(gps.getMonth());
        Serial.print(gps.getYear());
  */   
        break;
      // ошибка данных
      case GPS_ERROR_DATA:
        Serial.println("GPS error data");
        break;
      // нет соединение со спутниками
      case GPS_ERROR_SAT:
        Serial.println("GPS no connect to satellites!!!");
        break;
    }
  }
}
 

Roden

✩✩✩✩✩✩✩
19 Апр 2019
31
5
@prohor-nastya, нет... В цикле выполняется тело цикла, то что в скобках {} сразу после while, так как в твоём случае они пустые, у тебя цикл будет крутиться пока !Serial не будет равен false, после этого тело цикла выполняться не будет и перейдёт на следующую строку сразу под циклом, на Serial.print.
Советую для начала изучить основы программирования на С++...
 

AlexGyver

★★★★★★✩
Команда форума
30 Июл 2018
357
564
Эта конструкция вертит пустой цикл, пока не запустится Serial. Данный костыль нужен для нормального старта и работы с Serial на платах со встроенным USB, на базе меги 32u4 например (Leonardo, Micro)
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Ребята, я просто слепень... Я не увидел вторую закрытую скобку цикла и у меня все сломалось. Спасибо большое. Странно, что я вроде отписался, но сообщения нет. Походу по кнопке отправить промахнулся в смартфоне... Слепень он и есть...🤓🤓🤓
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Эта конструкция вертит пустой цикл, пока не запустится Serial. Данный костыль нужен для нормального старта и работы с Serial на платах со встроенным USB, на базе меги 32u4 например (Leonardo, Micro)
Вот по этому поводу тоже возник вопрос, зачем вставлять эту конструкцию если прошиваешь Мегу 2560... На микро понятно, а на Меге зачем это нужно?

Мое личное предположение, что пока активируется порт, уже чего-нибудь выполнится и не увидим данных?
 

Александр Симонов

★★★★✩✩✩
2 Авг 2018
727
207
Вот по этому поводу тоже возник вопрос, зачем вставлять эту конструкцию если прошиваешь Мегу 2560... На микро понятно, а на Меге зачем это нужно?
Код универсальный, под несколько контроллеров.
 

AlexGyver

★★★★★★✩
Команда форума
30 Июл 2018
357
564
@prohor-nastya, автор исходника просто откуда то его скопировал, не разбираясь. Либо универсал под любую плату
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Обычно с таким кодом встречается комментарий , что это необходимо для леонардо. А тот кто коммуниздил код коммент потер как класс