Здравствуйте. Года 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++; } }
Попробовал использовать библиотеку Алекса Гайвера и всё заработало. Странно, он же тоже эту же функцию использует