Возможно проблема с millis

Тема в разделе "Arduino & Shields", создана пользователем VladimirMu4enik, 11 авг 2020.

Метки:
  1. Здравствуйте. Года 2,5 - 3 назад собрал приборчик. И года 2 им прекрасно пользовался. Идея его проста как мычание: взять строчку NMEA, вытащить оттуда цифры и рисовать график. Но вдруг что-то с прибором случилось и теперь не выдерживается задержка в 15 секунд. Я взял новую Мегу 2560, прошил тем же скетчем но результат такой же. Посмотрите пожалуйста, может я что в коде криво написал? Хотя... оно же работало! А прибор нужен мне. причём он то нормально работает секунд 10, то срывается. Что делать то? У меня фантазии кончились. Заранее спасибо за ответ.

    Код (C++):

    // библиотека для работы с дисплеем
    #include <UTFT.h>
    // создаём объект класса UTFT
    // и передаём идентификатор модели дисплея и номера управляющих пинов
    UTFT myGLCD(CTE32HR, 38, 39, 40, 41);
    // объявления встроенного шрифта
    extern uint8_t BigFont[];
    #include <Wire.h>

    /* Подключение
        Контакт Платы Ардуино - Контакт платы экрана
        А5 -  SCL
        A4 - SDA
        Vcc - +5B
        GND - GND
        вход NMEA на ARDUINO UNO 0(RX)
        вход NMEA на ARDUINO MEGA 0(RX)
        setCursorm(номер знакоместа, номер строки)
    */


    int ledPin = 13;                  // LED test pin
    char byteNMEA;
    int ledpin [13];

    const int chislotochek = 290; //количество точек на курсограмме. Получается из: размер по вертикали в точках (320) - offsetY(30) = 290
    const int offsetY = 30;
    const int offset = 60;  //смещение края графика от края экрана в точках. Таким образом он будет по середине
    const int speedA = 15000;  //30000 = 30 секунд - временной интервал между снятием показаний, он же скорость протяжки графика
    int massiv[chislotochek]; //массив для хранения данных о курсе.
    short int sotni = 0;  //переменная для хранения старшего разряда курса
    short int desiatki = 0; //переменная для хранения среднего разряда курса
    short int edinicy = 0;  //переменная для хранения младшего разряда курса
    short int doli = 0; //переменная для хранения десятых долей курса
    short int kursA = 333; //переменная для хранения данных о курсе, только целая часть, без запятой. Именно эти цифры будут хранится в массиве
    float kursB = 333.3;  //переменная для хранения данных о курсе. Именно с неё будет выводится цифры на экран.
    float tochka = 0; //помощь в сборе данных о курсе
    uint32_t previousMillis = 0;
    uint32_t currentMillis;

    //int zaderjka;

    void setup()
    {
      Serial.setTimeout(1000);
      // инициализируем дисплей с вертикальной ориентацией
      myGLCD.InitLCD();
      // очищаем экран
      myGLCD.clrScr();
      // выбираем большой шрифт
      myGLCD.setFont(BigFont);
      // устанавливаем красный цвет «чернил» для печати и рисования
      myGLCD.setColor(VGA_RED);
      pinMode (2, INPUT);
      pinMode(ledPin, OUTPUT);       // Initialize LED pin
      //  pinMode(rxPin, INPUT);
      //  pinMode(txPin, OUTPUT);
      Serial.begin(4800);
      for (int i = 0; i < chislotochek; i++) massiv[i] = 0; //забиваем нулями массив, то бишь инициализация
    }

    void loop()
    {
      // Первые 3 символа не интересуют меня, то есть будь то "$HE" или "$HC" - пофиг.
      //а вот следующие типа HDT или HDG будут интересовать с точки зрения того, что это предложения гиро или нет.
      myGLCD.setFont(BigFont);
      myGLCD.setColor(VGA_AQUA);
      myGLCD.print("HEADING:", LEFT, 1);
      myGLCD.print("0", 0, 300, 0);
      myGLCD.print("360", 430, 300, 0);

    nabor:
      Serial.flush();
      sreaddata(); //функция сохраняет своё значание в глобальной переменной byteNMEA
      if (byteNMEA != '$') goto nabor; //тут символ "$" интересует только в контексте того, что ищем начало предложения, есле не оно - пропускаем и читаем дальше
      Serial.print(byteNMEA); //если оно, то выводим его на дисплей и далее выводим просто ещё 2 символа
      // то есть по логике это должны быть или HE или HC
      Serial.print(sreaddata());
      Serial.println(sreaddata());
      sreaddata(); //читаем дальше
      if (byteNMEA != 'H') goto nabor; //типа если не символ Н то возможно это предложение не гиро, начинаем всё с начала
      Serial.print (byteNMEA); //выводим сивол на дисплей
      sreaddata (); //читаем дальше
      if (byteNMEA != 'D') goto nabor; //типа если не символ D то возможно это предложение не гиро, начинаем всё с начала
      Serial.print (byteNMEA); //выводим сивол на дисплей
      sreaddata ();
      if (byteNMEA != 'T')  if (byteNMEA != 'G') goto nabor; //если символ не равен Т ИЛИ не равен G то всё с начала;
      Serial.print (byteNMEA); //выводим сивол на дисплей
      Serial.print (sreaddata ()); //тут по идее должна быть запятая
      /*далее по идее должены идти цифры в стиле 123,4. ща будем собирать всё это сначала по переменным: sotni, desiatki, edenicy, doli
        тут надо учесть, что одни гиро дают курс в формате 099,9 а другие в формате 99,9.
        так что логика такая:
        пихаем первую цифру в разряд десятки, вторую цифру в разряд единицы. Потом берём третий знак и если он не цифра а точка то всё пучком
        иначе сдвигаем всё на 1 разряд, то есть из десятков в сотни, единиц в десятки.
        Затем собираем всё это в кучу и помещаем это по переменным: kursA, kursB
        Тут на место цифр пролазиют буквы, так что их тоже проверяем и если не цифра - начинаем с начала
      */

      sotni = sreaddata ();
      desiatki =  sreaddata ();
      edinicy = sreaddata ();
      tochka = sreaddata ();
      doli = sreaddata ();
      // проверка на то, что там именно цифры а не какая-то хуйня
      if (sotni < 48 || sotni > 57) goto nabor; //расшифровка: если переменная sotni меньше 48 ИЛИ больше 57 ТОГДА идём в начало
      if (desiatki < 48 || desiatki > 57) goto nabor;
      if (edinicy < 48 || edinicy > 57) goto nabor;
      if (tochka != 46) goto nabor; //если не точка....
      if (doli < 48 || doli > 57) goto nabor;

      //преобразование кода числа в число
      tochka = sotni - 48;
      sotni = tochka;
      tochka = desiatki - 48;
      desiatki = tochka;
      tochka = edinicy - 48;
      edinicy = tochka;
      tochka = doli - 48;
      doli = tochka;
      //собираем переменные kursA и kursB
      kursA = (sotni * 100) + (desiatki * 10) + edinicy;
      tochka = (sotni * 1000) + (desiatki * 100) + (edinicy * 10) + doli;
      kursB = tochka / 10;

      myGLCD.printNumF(kursB, 0, 130, 0, ',', 1);
    // попытка затереть 2 символа после цифр курса которые зависают после перехода с трёх значных цифр на двух значные
    //  myGLCD.print("  ", LEFT, 1);

      currentMillis = millis();
      if (currentMillis - previousMillis < speedA)   goto nabor;
      previousMillis = currentMillis;


      deleteplotgraph();
      sdvig ();
      massiv[0] = kursA;
      plotgraph();

      myGLCD.setColor(VGA_YELLOW);
      myGLCD.drawPixel(kursA + offset, 30);
    }

    int sreaddata ()
    {
    metka:   byteNMEA = Serial.read();
      if (byteNMEA == -1) goto metka;
      return byteNMEA;
    }

    void sdvig () //сдвиг всех элементов на 1 позицию вниз. То есть 1 элемент с первой позиции на вторую. 249 элемент на 250 позицию.
    {
      int source = chislotochek - 1;
      int destination = chislotochek;
      for (int i = 0; i < chislotochek; i++) {
        massiv[destination] = massiv[source];
        source--;
        destination--;
      }
    }

    void plotgraph()  //вывод всех точек на экран из массива
    {
      myGLCD.setColor(VGA_YELLOW);
      short int i;
      short int Y = 0;
      for (i = 0; i < chislotochek; i++) {
        myGLCD.drawPixel(massiv[i] + offset, Y + offsetY);
        Y++;
      }
    }

    void deleteplotgraph()  //стирание всех точек на экране из массива
    {
      myGLCD.setColor(VGA_BLACK);
      short int i;
      short int Y = 0;
      for (i = 0; i < chislotochek; i++) {
        myGLCD.drawPixel(massiv[i] + offset, Y + offsetY);
        Y++;
      }
    }
     
  2. Airbus

    Airbus Радиохулиган Модератор

    Зачем темы—клоны создавать?
     
  3. gfox

    gfox Нерд

    Возможно ошибка в обработке NMEA, со всеми этими goto вы упускаете что-то.
     
  4. Попробовал использовать библиотеку Алекса Гайвера и всё заработало. Странно, он же тоже эту же функцию использует