e-paper с esp32
- Войдите на сайт для отправки комментариев
Электронная бумага может работать быстро. Проблема у меня была. Сделал GPS навигатор для полетов в ленобласти сначала на TFT. Видно хорошо только вечером, когда летать остается уже мало времени. Купил у китайцев OLED. Видно хорошо, но только в пасмурную плохую погоду. Купил e-ink ? и тут проблема, в ни в нано ни в мега не влезает. А если впихнуть, работает по черепашьи.
Моментально все проблемы ушли при замене процессора Атмел на ESP32 (32разряда, 80МГц). Дальнейшие эксперименты показали, что применение электронной бумаги с функцией частичного обновления экрана позволяют сделать обновление данных незаметным. Теперь чем ярче солнце, тем ярче экран. Но и в сумерках неплохо видно. Появилась новая проблема - полет ночью, но это не часто.
Для тех, кто считает e-ink ленивым изделием, можно убедиться, что это не совсем верно, на примере короткого видео https://youtu.be/TYofynIQDss .
Вот текст примера. Использован дисплей 2,7" 264x176. Координаты для векторного рисования контуров взяты с карты гугл. Это, как уже отмечал, некоторые объекты Ленинградской области, нужные мне для ориентации. Вы можете рисовать свои. GPS приемник настроен на скорость 115200.
//====программировалось в среде Ардуино==== //BMP180 куплено в китае за очень недорого //ESP32DEVKIT V1 куплено в китае за деньги // дешевого 8-разрядного процессора //библиотеки от https://github.com/adafruit //автор-исполнитель ValeryLem lvj416@mail.ru //======от января 2020г. г.Ленинград======= //**************************************************************** /* uint32_t brown_reg_temp = READ_PERI_REG(RTC_CNTL_BROWN_OUT_REG); //save WatchDog register WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector WiFi.mode(WIFI_MODE_STA); // turn on WiFi WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, brown_reg_temp); //enable brownout detector */ //экземпляр парсера GPS #include <TinyGPS++.h> TinyGPSPlus gps;//создание экземпляра парсера, использован GN701 //экземпляр декодера датчика давления #include <Adafruit_BMP085.h> Adafruit_BMP085 bmp;//создание экземпляра дешифратора для BMP180 //соединить с выводами SDA и SCL I2C, датчик 3.3В,от 5В сгорит!! #include <GxEPD.h> // б-ка для работы с E-INK #include <GxGDEW027W3/GxGDEW027W3.h> // 2.7" b/w pixel pitch 0,217mm #include <GxIO/GxIO_SPI/GxIO_SPI.h> // б-ка SPI #include <GxIO/GxIO.h> //интерфейс SPI для e-ink 2.77" //CS/оранж DC/зеленый RST/белый //DIN/синий CLK/желтый BUSY/сирень GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/ 15, /*RST=*/ 2); //rst-13 GxEPD_Class display(io, /*RST=*/ 2, /*BUSY=*/ 4); //экземпляр (UART2) парсера #include "HardwareSerial.h" HardwareSerial gps_serial(2); #define RXD2 16 // вход парсера для GPS, установлена скорость 115200 #define TXD2 17 // см. также void setup() // кнопки управления #define KeyFn 27 // pin кнопка уровня давления аэродрома или доп.функция #define KeyScale 26 // pin масштаб, вместе с нажатой кнопкой Fn-предыдущая цель #define KeyTarget 25 // pin смена экрана, вместе с нажатой Fn- следующая цель //вспомогательные константы #define hourOffset 3 // час., часовой пояс Ленинграда #define h 176 // pix высота 1 38mm (0.217*176=38) #define w 263 // pix ширина 1 экрана для частичного обновления #define xc2 176 // абсцисса центра2 - ось вращения схемы #define lenArrow 87 // pix длина указателей направления полета и цели #define approach 5 // km радиус/расстояние перехода на масштаб приближения #define apprScale 16 // kL, масштаб приближения #define logLen 80 // длина записи логгера #define BiglogLen 263 // длина записи логгера #define logOffset 157 // уровень печати времени #define BigOffset 160 // уровень печати времени #define refresh 1000 // мс. 1c между обновлениями экрана #define clean 1000000 // мс. ~3 min между очисткой #define align 5 // створ пролета - дорожка на схеме, градусов //#define SmallFont & #define SmallFont1 &FreeSerif9pt7b//&FreeSerifBold9pt7b #define SmallFont2 &FreeSans9pt7b #define BigFont &FreeSans12pt7b //#define CoFont &FreeSerifItalic12pt7b #define CoFont &FreeSerifBoldItalic12pt7b //#define BigFont &FreeSerif12pt7b //#define BigFont &FreeMonoBold9pt7b //#define SmallFont &FreeMono9pt7b #define TinyFont &Tiny3x3a2pt7b //координаты для симуляции пролета //#define A_plane 59.76, 29.60 //Gostilicy //#define A_plane 60.01, 29.70 //b pole //#define A_plane 59.95, 31.03 //oresek //#define A_plane 59.81, 30.30 //pulkovo #define A_plane 59.63,29.53 //selco //#define A_plane 59.71, 29.03 // копорье //#define A_plane 59.88,29.88 // петегоф //#define A_plane 59.65,28.99 // куммолово #include <Fonts/FreeMono9pt7b.h> #include <Fonts/FreeMonoBold9pt7b.h> // шрифты так себе #include <Fonts/FreeSans9pt7b.h> #include <Fonts/FreeSerifitalic9pt7b.h> #include <Fonts/FreeSerifBold9pt7b.h> #include <Fonts/FreeSerif9pt7b.h> #include <Fonts/FreeSerif18pt7b.h> #include <Fonts/FreeSerif12pt7b.h> #include <Fonts/FreeSans12pt7b.h> #include <Fonts/FreeSerifItalic12pt7b.h> #include <Fonts/FreeSerifBoldItalic12pt7b.h> #include <Fonts/Tiny3x3a2pt7b.h> //вольтметр const int VoltPin = 34; int VoltValue = 0;// бит АЦП //========= переменные ============ volatile float alt, lati, longi; volatile int flyTo,fi, kL, fiA, fiTo;//-32000+32000 volatile float oldtime, cleantime,initP;//, fiA;//направление полета; volatile int ekran, counter; volatile int distanceTo;//, fiTo; //расст до цели и азимут на нее volatile bool fndown,scaledown,targetdown,up,//up - направлеие масштаба info, show;// флажки управления кнопками и пр. int logBuff [logLen];//0-199 int BiglogBuff [BiglogLen];//0-199 // координаты для рисования контуров объектов ******************* // надо точнее - пишите больше после запятой float Zaliv[67][2]= { 59.67,28.31, 59.66,28.38, 59.67,28.42, 59.70,28.43, 59.73,28.44, 59.77,28.44, 59.82,28.48, 59.84,28.54, 59.82,28.63, 59.80,28.67, 59.78,28.71, 59.77,28.72, 59.77,28.77, 59.80,28.78, 59.78,28.81, 59.78,28.85, 59.80,28.87, 59.80,28.91, 59.81,28.97, 59.84,29.02, 59.87,29.06, 59.91,28.99, 59.96,29.07, 59.98,29.12, 59.99,29.21, 59.98,29.33, 59.96,29.42, 59.96,29.54, 59.94,29.60, 59.93,29.64, 59.93,29.67, //начало дамбы 59.93,29.68, 59.94,29.68, 59.94,29.70, 59.93,29.70, 59.93,29.74, 59.93,29.77, 59.90,29.84, 59.89,29.89, //петергоф 59.88,29.95, 59.86,30.02, 59.86,30.10, 59.86,30.15, 59.88,30.17, 59.92,30.26, 59.94,30.18, 59.98,30.20, 59.99,30.16, 59.99,30.07, 60.01,29.97, 60.04,29.96, //конец дамбы 60.06,29.94, 60.09,29.92, 60.11,29.94, 60.15,29.93, 60.17,29.80, 60.19,29.69, 60.19,29.55, 60.16,29.43, 60.16,29.14, 60.20,29.00, 60.28,28.91, 60.30,28.84, 60.31,28.82, 60.26,28.65, 60.45,28.42, 60.54,28.44 }; float ZalVoda[55][2]={ 59.80,28.74, 59.80,28.80, 59.83,28.87, 59.83,28.93, //59.85,28.92, 59.85,28.98, 59.86,28.95, 59.86,29.01, 59.88,28.97, 59.88,29.03, 59.91,28.92, 59.91,29.98, 59.94,28.87, 59.94,28.93, 59.96,28.92, 59.96,28.98, 60.01,29.12, 60.01,29.18, 60.00,29.32, 60.00,29.38, 59.98,29.50, 59.98,29.56, 59.945,29.73, 59.945,29.79, 59.92,29.83, 59.92,29.89, 59.90,29.93, 59.90,29.99, 59.88,30.05, 59.88,30.11, //59.90,30.18, 59.90,30.11, 59.92,30.13, 59.92,30.19, //59.94,30.19, 59.94,30.12, 59.96,30.11, 59.96,30.17, 59.98,29.96, 59.98,30.02, 60.02,29.89, 60.02,29.95, 60.06,29.87, 60.06,29.93, 60.09,29.83, 60.09,29.89, 60.12,29.85, 60.12,29.91, 60.15,29.76, 60.15,29.82, 60.17,29.57, 60.17,29.63, 60.14,29.33, 60.14,29.39, 60.14,29.08, 60.14,29.14 }; float Ladoga[28][2]= { 61.15,29.96, 60.81,30.53, 60.57,30.68, 60.39,30.87, 60.27,30.93, 60.19,30.97, 60.17,31.05, 60.11,31.09, 60.06,31.07, 60.03,31.13, 60.01,31.10, 59.96,31.05, 59.93,31.07, 59.93,31.14, 59.91,31.16, 59.92,31.21, 59.94,31.23, 59.94,31.33, 59.90,31.40, 59.97,31.56, 60.15,31.54, 60.25,32.08, 60.12,32.27, 60.40,32.69, 60.72,32.80, 61.13,32.50, 61.58,30.92, 61.17,29.97 }; float Neva[10][2]={ //от ладоги до залива 59.92,30.26, 59.94,30.31, 59.96,30.38, 59.95,30.41, 59.92,30.39, 59.85,30.49, 59.79,30.62, 59.77,30.75, 59.83,30.94, 59.93,30.99 }; float Sneva[2][2]={ 59.94,30.31, 59.96, 30.22 }; float Mneva [3][2]={ 59.95,30.34, 59.98,30.30, 59.97, 30.20 }; //**************************************************** float coorKot[18][2]={ //остров котлин 59.98,29.688, 60.00,29.69, 60.02,29.68, 60.03,29.63, 60.03,29.64, 60.03,29.675, 60.023,29.71,60.03,29.758, 60.02,29.78, 60.00,29.78, 59.99,29.80, 59.98,29.80, 59.97,29.78, 59.98,29.77, 59.98,29.75, 59.99,29.75, 60.00,29.72, 59.98,29.688 }; //зона полигона ВС РФ запрещены полеты float poligon[1][2]{59.86,29.744}; short poligR [1][2]; // контуры некоторых дорог /* drawShape(RoadKron, 23, A_plane,1);// 1 - толщина линии drawShape(RoadLadoz, 13, A_plane,1); drawShape(RoadIzora, 20, A_plane,1);//59.74, 29.63); drawShape(RoadSbor,12,A_plane,1); drawShape(RoadVolh,6,A_plane,1); drawShape(RoadKopor,5,A_plane,1); drawShape(RoadZsd,9,A_plane,1); drawShape(RoadSista,21,A_plane,1); drawShape(RoadTallin,26, A_plane,1); drawShape(RoadVolos,18, A_plane,1); drawShape(RoadLuga, 21, A_plane,1); drawShape(RoadLadoga,3, A_plane,1); drawShape(RoadMurino,8, A_plane,1); drawShape(RoadMosk,16, A_plane,1); */ //петергоф-гостилицы-сосновый бор float RoadSbor[12][2]={ 59.88,20.88, 59.87,29.85, 59.87,29.83, 59.86,29.80, 59.82,29.72, 59.79,29.70, 59.78,29.64, 59.73,29.61, 59.72,29.52, 59.72,29.43, 59.76,29.23, 59.88,29.09}; //волхонка float RoadVolh[6][2]={ 59.84,30.03, 59.83,30.07, 59.81,30.11, 59.79,30.15, 59.74,30.31, 59.73,30.35}; //на копорье float RoadKopor[5][2]={ 59.76,29.23, 59.74,29.20, 59.73,29.13, 59.70,29.05, 59.69,28.81}; //Лад озеро float RoadLadoz[13][2]={ 59.98,30.51, 60.04,30.64, 60.06,30.74, 60.09,30.78, 60.10,30.81, 60.09,30.86, 60.08,30.89, 60.08,30.93, 60.08,30.95, 60.09,30.97, 60.09,31.01, 60.08,31.04, 60.08,31.07}; //через кронштадт float RoadKron[23][2]={ 59.92,29.66, 59.95,29.677, 59.98,29.689, 60.00,29.70, 60.02,29.73, 60.02,29.78, 60.02,29.73, 60.027,29.84, 60.033,29.90, 60.037,29.95, 60.04,30.00, 60.058,30.14, 60.09,30.26, 60.09,30.37, 60.06,30.39, 60.04,30.44, 59.98,30.51, 59.96,30.55, 59.89,30.52, 59.85,30.50, 59.83,30.44, 59.81,30.37, 59.81,30.33,}; //систа тосно павлово на неве float RoadSista[21][2]={ 59.81,28.99, 59.71,29.03, 59.67,29.17, 59.64,29.19, 59.58,29.30, // бегуницы 59.49,29.36, 59.44,29.47, 59.46,29.61, 59.40,29.66, 59.36,29.83, 59.34,29.96, 59.35,30.06, 59.38,30.14, 59.40,30.35, 59.45,30.58, 59.43,30.70, 59.54,30.87, 59.60,31.18, 59.74,31.07, 59.76,30.98, 59.81,30.92}; //на волосово float RoadVolos[18][2]={ 59.87,29.96, 59.83,29.94, 59.81,29.93, 59.79,29.91, 59.75,29.89, 59.72,29.85, 59.67,29.85, 59.64,29.82, 59.63,29.77, 59.59,29.70, 59.57,29.65, 59.56,29.59, 59.52,29.56, 59.49,29.54, 59.44,29.47, 59.38,29.50, 59.28,29.52, 59.21,29.63}; // таллинское ш. float RoadTallin[26][2]={ 59.80,30.15, 59.72,30.08, 59.70,29.98, 59.67,29.85, 59.66,29.76,//глухово 59.66,29.71, 59.65,29.69, 59.65,29.66, 59.63,29.60, 59.63,29.57,//анташи 59.63,29.53, 59.62,29.50, 59.60,29.46, 59.58,29.32, 59.57,29.28,//гомонтово 59.56,29.19, 59.55,29.10, 59.54,29.08, 59.52,29.06, 59.49,29.02,//б.озертицы 59.48,28.92, 59.46,28.89, 59.45,28.85, 59.43,28.79, 59.40,28.72,//тикопись 59.40,28.59//кингисепп }; // на лугу float RoadLuga [21][2]={ 59.81,30.32, 59.77,30.33, 59.71,30.28, 59.67,30.23, 59.64,30.23, 59.61,30.19, 59.58,30.17, 59.53,30.16, 59.52,30.06, 59.45,30.00, 59.42,29.98, 59.34,29.96, 59.24,29.93, 59.16,29.91, 59.10,29.91, 59.02,29.95, 58.91,29.96, 58.85,29.92, 58.73,29.88, 58.62,29.83, 58.53,29.80}; // на москву float RoadMosk [16][2]={ 59.81,30.37, 59.77,30.46, 59.73,30.53, 59.71,30.58, 59.68,30.61, 59.64,30.68, 59.60,30.76, 59.55,30.87, 59.41,31.11, 59.35,31.24, 59.26,31.38, 59.18,31.54, 59.11,31.69, 58.80,31.46, 58.57,32.47, 58.38,32.99}; //ижора гостилицы-кировск float RoadIzora [20][2]={ 59.94,29.58, 59.89,29.54, 59.84,29.54, 59.80,29.56, 59.76,29.55, 59.74,29.59, 59.69,29.65, 59.61,29.67, 59.55,29.83, 59.54,29.90, 59.52,29.96, 59.50,30.27, 59.51,30.41, 59.57,30.67, 59.66,30.88, 59.68,30.95, 59.74,31.07, 59.80,31.11, 59.83,31.08, 59.88,30.98}; // мурин токсово матокса float RoadMurino[8][2]={ 60.04,30.44, 60.05,30.49, 60.11,30.50, 60.15,30.52, 60.18,30.55, 60.23,30.56, 60.27,30.54, 60.30,30.61}; // на ст.ладогу float RoadLadoga[3][2]={ 59.89,30.52, 59.90,31.06, 59.88,31.34}; // zsd float RoadZsd[9][2]={// от залива вниз 59.92,29.66, 59.88,29.67, 59.86,29.79, 59.81,29.85, 59.82,29.97, 59.81,30.07, 59.80,30.15, 59.83,30.27, 59.81,30.32}; //озеро лубенское char *nameOz[] = {"lubO"}; float coordOz[1][2] = {59.81,29.25}; // поселки const int targets = 37; char *nameVillage[37] = {//0...16 pointer to targets names , elements of array "gost", "selc", "kopo",//гостилицы сельцо копорье "pgof", "djat", "kork",//петергоф дятлицы коркино "krse", "ladO", "toks", "kolp", "gatc", "pulk",//колпино гатчина пулково "sist", "krgo", "bpol",//систопалкино кр.горка бычье поле "sert", "luga", "opol",//сертолово луга ополье "vsev", "pavs", "lnos",//всеволожск павловск лисий нос "kike", "ores", "gruz", //кикерино орешек грузино "begu", "zimi", "vyra", //бегуницы зимицы выра "tosn", //тосно //выводить только 28, дальше идут аэродромы // след. имена используется для указания аэродромов в void NextTarget(), // в этом массиве, ВПП на карту выводятся другим массивом координат "GST", "SLC", "BPL", "KUM", "LSN", "KRK", "PUT", "$GL", "PLK" }; //*********** координаты поселков ************** float corVill[37][2] = {//25- нас пункты, остальное -аэродромы 59.74,29.62, 59.63,29.53, 59.71,29.03, 59.88,29.88, 59.70,29.70, 59.25,31.27, 59.73,30.08, 60.12,31.07, 60.15,30.53, 59.75,30.60, 59.57,30.14, 59.81,30.30, 59.80,28.91, 59.97,29.33, 60.01,29.70, 60.14,30.20, 58.75,29.89, 59.43,28.82, 60.00,30.65, 59.68,30.44, 60.03,30.02, 59.47,29.61, 59.95,31.03, 60.33,30.42, 59.59,29.31, 59.55,29.10, 59.34,29.96, 59.53,30.88, // дополнение сделано для void NextTarget().Только первые 28 59.73,29.64, 59.63,29.53, 60.01,29.70,//выводить на печать по drawObject() 59.65,28.99, 60.03,30.01, 59.25,31.27, 59.83,31.47, 60.02,30.80, 59.80,30.22 }; //**************************************************** char *nameLanding[9] = {//нас. пункты с посадочными площадками //гостилицы селцо б.поле,куммолово лисий нос коркино путилово //пулково "GST", "SLC", "BPL", "KUM", "LSN", "KRK", "PUT", "$GL", "PLK" }; //**************коорд.центра аэродрома********* float coordLanding[9][2] = {//positions of targets double 59.724963,29.641068, 59.617034,29.541359, 60.014575,29.702647, 59.654785,28.996225, 60.033818,30.016687, 59.243987,31.269417, 59.836530,31.479950, 60.021379,30.785946, 59.800163,30.26262 }; //******взлетно-посадочные полосы выс.точность******* // рисуются всегда массива имен не имеют float coordVPP [9][4] = {// пары начало конец впп, имена см. выше 59.731233,29.635060, 59.719602,29.646451, 59.619156,29.549889, 59.614817,29.531216, 60.014277,29.711025, 60.015185,29.691236, 59.662989,29.002489, 59.645998,28.990378, 60.030636,30.025338, 60.037173,30.008979, 59.248172,31.268936, 59.230258,31.270444, 59.842542,31.476742, 59.825052,31.485490, 60.018899,30.795336, 60.024642,30.773490, 59.801865,30.205765, 59.787607,30.300965 }; //=============================================================================================== void setup(){ Serial.begin(115200); bmp.begin(); gps_serial.begin(115200, SERIAL_8N1, RXD2, TXD2);// аппаратный интерфейс GPS парсера display.init(115200); VoltValue = analogRead(VoltPin);//5V=3333 4v=2674; 2333=3.5V KeysSetup(); // кнопки управления kL=2; // нач.масштаб 90 км на экран ekran=0; // режим 0- показать все display.setRotation(3); // команда экран - вверх ногами горизонтально display.setTextColor(0); // рисовать черным display.setFont(SmallFont1); // мелкий шрифт для kL=2 oldtime=millis(); // отсчет для обновления экрана show=true; // флаг моргалки display.fillScreen(0); display.update(); // fndown=true; counter=10; // обход задержки ResetAlt(); // приземлить высоту потом показать карту counter=0; // восстановление задержки fndown=false; // for (int i=0; i <= logLen-1; i++) logBuff[i]=-20; for (int i=0; i <= BiglogLen-1; i++) BiglogBuff[i]=-20;//BiglogBuff [BiglogLen] flyTo=0; up=true; counter=0;//reset altitude } //================================================================================================ void loop(){ Keys(); if (updateNeeded()) { ResetAlt();//не сработает 5 с NextScale(); NextTarget(); PrevTarget(); Ekrans(); displayMap(); fndown=false; } } //_______________________________________________________________________________________________ //********************* варианты экранов************** // экран 0 все, экран 1 села заменены на аэродромы void displayMap(){ // фиктивные коорд A_plane будут заменены на реальные при видимости спутников //постоянно на экране: display.fillRect(0, 0, w, h-1, 0);//залить черным все display.fillRect(0, 0, w, h-1, 1);//залить белым все //miniCompass();//доп.компас //putText(); drawFlyTrack();//вычисляется ТЕКУЩИЙ КУРС (global fi) fiA drawObject(poligon,1, A_plane,3);// 5- диаметр 5 рисовать всегда-запр.зона largeComp(A_plane); drawVPP(coordVPP,9,A_plane); // это посадочные полосы putRoads(); putWater(); tstBattery(); if (kL>2) display.setFont(SmallFont2); else display.setFont(SmallFont1); if (show) {// моргает по show см stopBlink drawArrowTarg(A_plane,flyTo); } if (distanceTo<approach) {//переход на масшта приближения kL=apprScale; up=false;//lfkmit только деление масштаба if (!info) {//флаг разового показа текста о смене масштаба approInfo(); info=true;//флаг исполнения } } StopBlinkAlign(); if (ekran==0) { drawObject(corVill,28, A_plane, 0);//0-нас пункт, заканчваются на 28, дальше - аэродромы drawObject(coordOz, 1, A_plane, 2);// putText(); grid(); buffLog(); putLog(); } else {//убраны поселки, только Аэродромы со своими координатами. NB- это координаты точки drawObject(coordLanding, 9, A_plane, 1);// 1- аэродромы центр - середина VPP //} //if (cleanNeeded()) display.update(); //else display.updateWindow(0, 0, w, h, true); //grid(); bigGrid(); //buffLog(); bufBiglog(); //putLog(); putBiglog(); } miniCompass();//доп.компас освобождает себе место display.updateWindow(0, 0, w, h, true); } //**************** время по спутнику***************** char *timesat (void) { byte minuta,secunda; static char times[9]; byte se, ho; if (gps.time.isValid()){//get time ho=gps.time.hour()+hourOffset; for (byte i=0; i<hourOffset;i++) if (ho==(i+24)) ho=i;//leningrad timing minuta=gps.time.minute(); se=gps.time.second(); } else {ho=0;minuta=0;se=0;} // учет широты Ленинграда for (byte i=0; i<hourOffset; i++) if (ho==(i+24)) ho=i;//leningrad timing sprintf(times, "%02d:%02d:%02d", ho,minuta,se) ; return times; } //****************вывод числа спутников**************** byte GetSats(void){ byte nSat; if (gps.satellites.isValid()) nSat = gps.satellites.value(); // кол спутников else nSat = 0; //иначе заменить на 0 return nSat; } //********рисование объектов относительно самолета***** void drawObject(float coord[][2], byte n, float cx, float cy, byte ro) {//коорд объекта, число их в массиве, координанаты самолета , тип объекта //0 - нас.пункт 1- аэродром 2-озеро 3- запрет полетов int c, x0, y0, dx, dy,s; //r-rot, l- отступ справа word d;//вектор float fi0;//угол c=0; s=33;//длина текста для смещения влево // замена фиктивных координат на текущие if (gps.location.isValid()) {cx=lati; cy= longi;} do { d= kL* TinyGPSPlus::distanceBetween(coord[c][0],coord[c][1],cx,cy)/1000;//расстояние if (d<101)// если внутри масштабного диаметра-рисовать { fi0= TinyGPSPlus::courseTo(cx,cy,coord[c][0],coord[c][1]);//градусы fi0=fi0-fiA;//fiA - направление полета, выч в drawFlyTrack(void) if (fi0<0) fi0=fi0+360; x0=d*sin(fi0*0.01745)+xc2; y0=h/2-d*cos(fi0*0.01745);//позиция switch (ro) { case 0: display.drawCircle(x0,y0,kL,0); break; case 1: display.drawCircle(x0,y0,kL,0); break; case 2: display.fillCircle(x0,y0,kL,0); break; case 3: display.fillCircle(x0,y0,kL,0); break; } if (ro==1) dx=x0+10; else dx=x0+3; dy=y0+3;//смещение по краям экрана if (dy>h) dy=h; if ((w-dx)<s) dx= w-s; display.setCursor(dx, dy); if (ro==0) display.print(nameVillage[c]); if (ro==1) display.print(nameLanding[c]); if (ro==2) display.print(nameOz[c]); } c++; } while (c<n); smartDelay(0); } //************** рисовать компас ************* void largeComp (float cx,float cy) { float fiq; char NN,SS,WW,EE; int x0,y0; display.drawCircle(xc2,h/2,h/2,0); display.drawCircle(xc2,h/2,h/2+1,0); NN='X'; SS='X'; //WW='X'; //EE='X'; NN='N';SS='S';// WW='W',EE='E'; if (gps.location.isValid()) {cx=lati; cy= longi; NN='N';SS='S'; WW='W',EE='E';} fiq= TinyGPSPlus::courseTo(cx,cy,89.9999,30.99);//сев полюс на широте ленинграда fiq=fiq-fiA;//fiA - направление полета, вычисл в drawFlyTrack(void) if (fiq<0) fiq=fiq+360; x0=82*sin(fiq*0.01745)+(xc2-6); y0=94-82*cos(fiq*0.01745);//позиция смещено влево вниз на 6 display.setCursor(x0,y0);//чтобы буква N ползла по контуру круга display.print(NN); fiq=fiq+180; x0=82*sin(fiq*0.01745)+(xc2-6); y0=94-82*cos(fiq*0.01745);//позиция display.setCursor(x0,y0); display.print(SS); } //*****************рисовать контуры*************** void drawShape(float coord[][2], int n, float cx, float cy, byte thin) //принимает массив пар координат из n-точек с заданным центром cx,cy //параметр толщины thin передается в др подпрограмму { int c=0; word cc,d1,d2; //длины векторов float fi1,fi2; //углы // замена фиктивных координат на текущие if (gps.location.isValid()) {cx=lati; cy= longi;} do { d1= kL* TinyGPSPlus::distanceBetween(coord[c][0],coord[c][1],cx,cy)/1000; d2= kL* TinyGPSPlus::distanceBetween(coord[c+1][0],coord[c+1][1],cx,cy)/1000; //if (d1<101 & d2<101) if (d1<=h/2 & d2<=h/2)// замена { fi1= TinyGPSPlus::courseTo(cx,cy,coord[c][0],coord[c][1]); fi2= TinyGPSPlus::courseTo(cx,cy,coord[c+1][0],coord[c+1][1]); fi1=fi1-fiA; if (fi1<0) fi1=fi1+360; fi2=fi2-fiA; if (fi2<0) fi2=fi2+360; lineBetween(d1,fi1,d2,fi2,thin); } c++; } while (c<n-1); smartDelay(0); } //*********************************************** void drawDash(float coord[][2], int n, float cx, float cy, byte thin) { //принимает массив пар координат из n-точек с заданным центром cx,cy //с удвоением thin по требованию { int c=0; word cc,d1,d2; //длины векторов float fi1,fi2; //углы // замена фиктивных координат на текущие if (gps.location.isValid()) {cx=lati; cy= longi;} do { d1= kL* TinyGPSPlus::distanceBetween(coord[c][0],coord[c][1],cx,cy)/1000; d2= kL* TinyGPSPlus::distanceBetween(coord[c+1][0],coord[c+1][1],cx,cy)/1000; //if (d1<101 & d2<101) if (d1<=h/2 & d2<=h/2)// замена { fi1= TinyGPSPlus::courseTo(cx,cy,coord[c][0],coord[c][1]); fi2= TinyGPSPlus::courseTo(cx,cy,coord[c+1][0],coord[c+1][1]); fi1=fi1-fiA; if (fi1<0) fi1=fi1+360; fi2=fi2-fiA; if (fi2<0) fi2=fi2+360; lineBetween(d1,fi1,d2,fi2,thin); } c=c+2; } while (c<n-2); smartDelay(0); } } //****рисовать ВПП с реальными углами посадки **** void drawVPP(float coord[][4],byte n,float cx, float cy){ //начало конец полосы, номер аэродрома, коорд самолета // замена фиктивных координат на текущие float d1,d2; //курс длины векторов float fi1,fi2; //углы радианы !! byte c=0;// переменная цикла аэродромов if (gps.location.isValid()) {cx=lati; cy=longi;}//замена коорд из ф-ции drawArrowTarg do { d1= kL* TinyGPSPlus::distanceBetween(coord[c][0],coord[c][1],cx,cy)/1000; d2= kL* TinyGPSPlus::distanceBetween(coord[c][2],coord[c][3],cx,cy)/1000; //if (d1<101 && d2<101)// от старой версии, надо бы заменить на h/2 if (d1<h && d2<h)// от старой версии, надо бы заменить на h/2 { fi1= TinyGPSPlus::courseTo(cx,cy,coord[c][0],coord[c][1]); fi2= TinyGPSPlus::courseTo(cx,cy,coord[c][2],coord[c][3]); fi1=fi1-fiA;//fiA - направление полета, выч в drawFlyTrack(void) if (fi1<0) fi1=fi1+360; fi2=fi2-fiA; if (fi2<0) fi2=fi2+360; lineBetween(d1,fi1,d2,fi2,2);// двойная полоса } c++; } while (c<n); smartDelay(0); } //************************************************ void lineBetween(word len0, float fi0, word len1, float fi1, byte thin) { int x0,y0,x1,y1; x0=len0*sin(fi0*0.01745)+xc2; y0=88-len0*cos(fi0*0.01745); x1=len1*sin(fi1*0.01745)+xc2; y1=88-len1*cos(fi1*0.01745); display.drawLine(x0,y0,x1,y1,0); if (thin>1) { display.drawLine(x0+1,y0+1,x1+1,y1+1,0);}// второй контур if (thin>2) { display.drawLine(x0-1,y0,x1-1,y1,0);}// третий контур } //********************************************************** //**полоса направления полета и уравление поворотом экрана** void drawFlyTrack(void){//две параллельных if (gps.course.isValid()) { fiA=gps.course.deg();//global } else fiA=0; word x1=cos_X((fi+90),8);//ширина пути word y1=sin_X((fi+90),8); word x2=cos_X((fi+align),lenArrow);//87 word y2=sin_X((fi+align),lenArrow); display.drawLine(x1, y1, x2 , y2,0); x1=cos_X((fi-90),8); y1=sin_X((fi-90),8); x2=cos_X((fi-align),lenArrow); y2=sin_X((fi-align),lenArrow); display.drawLine(x1, y1, x2 , y2,0); } void miniCompass(){//компас int ff;//угол поворота ff=0; display.fillCircle(100, 20, 20,1); display.drawCircle(100, 20, 20,0); ff=ff-fiA; if (ff<0) ff=ff+360; int x1=cos_NX(ff,20); int y1=sin_NX(ff,20); int x2=cos_NX(ff+90,5); int y2=sin_NX(ff+90,5); int x3=cos_NX(ff-90,5); int y3=sin_NX(ff-90,5); display.fillTriangle(x1, y1, x2 , y2, x3, y3, 0); //display.drawTriangle(x1, y1, x2 , y2, x3, y3, 0); x1=cos_NX(ff+180,20); y1=sin_NX(ff+180,20); x2=cos_NX(ff+90,5); y2=sin_NX(ff+90,5); x3=cos_NX(ff-90,5); y3=sin_NX(ff-90,5); display.drawTriangle(x1, y1, x2 , y2, x3, y3, 0); //display.fillTriangle(x1, y1, x2 , y2, x3, y3, 0); } //****************вспомог.sin/cos**************** //тригонометрия от центра (90,20) int cos_NX (int f, int s){ //int xTr=s*sin(f*0.01745)+100; int xTr = s* cos((f+270) * 0.0175)+ 100; return xTr; } //*********************************************** int sin_NX (int f, byte s){ //int yTr =s*cos(f*0.01745)+20; int yTr = s* sin((f+270) * 0.0175)+ 20; return yTr; } //************************************************ //*********стрелка указатель на цель*********** void drawArrowTarg(float la, float lo, byte c){ //направление самолет-номер выбр объекта //word fiTo; global var угол на выбранный объект //float lati,longi - global var lati =la;//широта симуляции полета При видимости спутников замещается реальной longi=lo;//долгота симуляции полета if (gps.location.isValid()) { lati=gps.location.lat(); longi= gps.location.lng(); } fiTo= TinyGPSPlus::courseTo(lati,longi,corVill[c][0],corVill[c][1]); distanceTo=TinyGPSPlus::distanceBetween(lati,longi,corVill[c][0],corVill[c][1])/1000; fiTo=fiTo-fiA; if (fiTo<0) fiTo=fiTo+360; int x1=cos_X(fiTo,lenArrow); int y1=sin_X(fiTo,lenArrow); int x2=cos_X(fiTo+5,lenArrow-20); int y2=sin_X(fiTo+5,lenArrow-20); int x3=cos_X(fiTo-5,lenArrow-20); int y3=sin_X(fiTo-5,lenArrow-20); if (gps.location.isValid()) display.fillTriangle(x1, y1, x2 , y2, x3, y3, 0); //если данные не полные - треугольник пустой else display.drawTriangle(x1, y1, x2 , y2, x3, y3, 0); int x=cos_X(fiTo,distanceTo*kL); int y=sin_X(fiTo,distanceTo*kL); if ((x>-1&&x<w-1) && (y>-1&&y<h-1)){// x= 0...263 y= 0...167 !!! это координаты точки на экане display.fillCircle(x,y, 5 ,0);//кружок на цели display.drawLine(x, y, xc2, h/2,0); } else display.drawLine(x1, y1, xc2, h/2,0); smartDelay(0); } //****************вспомог.********************** //тригонометрия от установленной точки int cos_X (int f, int s){ int xTr = s* cos((f+270) * 0.0175)+ xc2;//176 return xTr; } int sin_X (int f, byte s){ int yTr = s* sin((f+270) * 0.0175)+ h/2;//88 return yTr; } //************************************************ void KeysSetup (void) { // пины кнопок-входы с подтяжкой pinMode(KeyFn, INPUT_PULLUP); pinMode(KeyScale, INPUT_PULLUP); pinMode(KeyTarget, INPUT_PULLUP); fndown =false; // флажки управления кнопками scaledown =false; targetdown=false; info =false; // флаг для screen approach } //****************обработка кнопок***************** void Keys(void){ if (digitalRead(KeyFn)==LOW){ smartDelay(5); //дребезг if (digitalRead(KeyFn)==LOW); fndown =true; } if (digitalRead(KeyScale)==LOW){ smartDelay(5); //дребезг устранен if (digitalRead(KeyScale)==LOW);scaledown =true; } if (digitalRead(KeyTarget)==LOW){ smartDelay(5); //дребезг устранен if (digitalRead(KeyTarget)==LOW);targetdown =true; } } // степень заполнения экрана void Ekrans(void){ if (targetdown==true){ ekran++; if (ekran>1) ekran=0;//0-все, 1-аэродромы targetdown=false; } } //**************изменение масштаба************** void NextScale(){//2...3...4 // 2-4-8: 2pix/km 176/2=88-58-44km // approach - 16: 11km/screen // bool up = global if (scaledown ==true && fndown==false){ if (up) {kL=kL*2; if (kL==16) up=false; goto m0;} if (!up){kL=kL/2; if (kL==2) up=true;} m0: display.fillRect(0, 0, w, h-1, 0); display.fillRect(0, 0, w, h-1, 1); display.setTextSize(2); display.setCursor(60, 40); display.print("VISIBLE"); display.setCursor(65, 70); display.print("diameter"); display.setCursor(85, 110); Serial.print("kL: ");Serial.println(kL); switch (kL) { case 2: display.print("80 km"); break; case 4: display.print("40 km"); break; case 8: display.print("20 km"); break; case 16: display.print("10 km"); break; } //display.update(); display.updateWindow(0, 0, w, h-1, 1); display.setTextSize(0); smartDelay(200); displayMap(); scaledown = false; } } //*****************выбор цели полета************** void NextTarget(){ if (targetdown==true && fndown==true){ flyTo++; if (flyTo>(targets-1)) flyTo=0; // учет 0-ого элемента массива display.fillRect(0, 0, w, h-1, 1); display.setTextSize(2); display.setCursor(50, 70); display.print("TARGET : "); display.setCursor(90, 120); display.print(nameVillage[flyTo]); //display.update(); display.updateWindow(0, 0, w, h-1, 1); display.setTextSize(0); smartDelay(200); displayMap(); targetdown=false; fndown=false; } } //**************выбор цели полета**************** void PrevTarget(){ if (scaledown==true && fndown==true){ flyTo--; if (flyTo<0) flyTo=targets-1; display.fillRect(0, 0, w, h-1, 1); display.setTextSize(2); display.setCursor(50, 70); display.print("TARGET : "); display.setCursor(90, 120); display.print(nameVillage[flyTo]); //display.update(); display.updateWindow(0, 0, w, h-1, 1); display.setTextSize(0); smartDelay(200); displayMap(); scaledown=false; fndown=false; } } //*************установить высоту(давление) аэродрома********* void ResetAlt(){ if (fndown==true) counter++; else {counter=0;fndown=false;} // задержка 4 с if (counter>3 && fndown==true && targetdown==false && scaledown==false) { display.fillRect(0, 0, w, h-1, 0); display.fillRect(0, 0, w, h-1, 1); display.setTextSize(2); display.setCursor(70, 70); display.print("Altitude"); display.setCursor(90, 110); display.print("Reset"); initP = bmp.readPressure();// замена начального давления на текущее alt=bmp.readAltitude(initP); //display.update(); display.updateWindow(0, 0, w, h-1, 1); display.setTextSize(0); smartDelay(200); displayMap(); fndown=false; counter=0; } } //************************************************ void approInfo(){ int r=h/apprScale; display.fillRect(0, 0, w, h-1, 1); display.setTextSize(2); display.setCursor(60, 50); display.print("SCALE "); display.setCursor(20, 80); display.print(r);display.print(" km/screen"); display.setCursor(5, 120);display.print("approach < "); display.print(approach); display.print("km"); display.updateWindow(0, 0, w, h, 1); display.setTextSize(0); smartDelay(500); } void tstBattery(){ //батарея разряжена? float volt; volt=analogRead(VoltPin); volt=volt*5/3300;//резистивный делитель if ((show)&&(volt<3.75)){ display.setFont(BigFont); display.setCursor(88, 160); display.print("LOW BATTERY"); } } //************************************************ void putRoads(){ drawShape(RoadKron, 23, A_plane,1);// 1 - толщина линии drawShape(RoadLadoz, 13, A_plane,1); drawShape(RoadIzora, 20, A_plane,1);//59.74, 29.63); drawShape(RoadSbor,12,A_plane,1); drawShape(RoadVolh,6,A_plane,1); drawShape(RoadKopor,5,A_plane,1); drawShape(RoadZsd,9,A_plane,1); drawShape(RoadSista,21,A_plane,1); drawShape(RoadTallin,26, A_plane,1); drawShape(RoadVolos,18, A_plane,1); drawShape(RoadLuga, 21, A_plane,1); drawShape(RoadLadoga,3, A_plane,1); drawShape(RoadMurino,8, A_plane,1); drawShape(RoadMosk,16, A_plane,1); } //************************************************* void putWater(){ drawShape(Zaliv, 67, A_plane,3); drawDash (ZalVoda,55, A_plane,2); drawShape(coorKot, 18, A_plane,2); drawShape(Ladoga, 28, A_plane,3); drawShape(Neva, 10, A_plane,3); drawShape(Sneva, 2, A_plane,2); drawShape(Mneva, 3, A_plane,2); } //************************************************* void putText(){ static float volt, oldH, dH; display.setFont(BigFont); display.setCursor( 0, 15);display.print("h:"); display.print(alt,0);// см.updateNeeded() dH=alt-oldH; if (dH>-0.5 && dH<0) dH=0; display.setCursor( 0, 35);display.print("dH"); display.print(dH,0); oldH=alt; display.setCursor( 0, 55); if (ekran==0) display.print("All/"); else display.print("land/"); switch (kL) { case 2: display.print("80"); break; case 4: display.print("40"); break; case 8: display.print("20"); break; case 16: display.print("10"); break; } display.setCursor( 0, 75);display.print(nameVillage[flyTo]);display.print("-");display.print(distanceTo); display.setCursor( 0, 95);display.print("azi:");display.print(fiA); display.setCursor( 0,115);display.print("v:"); display.print(gps.speed.kmph(),0); display.setCursor( 0,135);display.print("t"); display.print(timeRest()); display.setFont(SmallFont1);//display.setCursor(229, 11) display.setCursor(229, 11);volt=analogRead(VoltPin);volt=volt*5/3300;display.print(volt); //display.setCursor( 83,160);display.print("h0"); //display.setFont(CoFont); if (ekran==0) { display.setCursor( 83,160);display.print("gnd"); display.setCursor(222,174);display.print("sat");display.print(gps.satellites.value()); display.setCursor( 0,174);display.print(lati,2);display.print(":");display.print(longi,2); display.setCursor( 0,154);display.print(timesat());} } //************************************************ bool cleanNeeded() {// каждые clean мсек static bool clr; clr=false; //очищать мусор if ((millis()-cleantime ) >clean) {// обновлять экран каждые 10мин cleantime=millis(); clr=true; } smartDelay(0); return (clr); } //************************************************ bool updateNeeded (){ static bool renew;//=false; renew = false; //static float oldH,deltaH; //180km/h = 50 m/s //изменение координаты на 0.01 degree = 1100 m ( по карте GOOGLE ) //изменения при отклонении на 1 км от прежнего положения = 20с для 180 км.час if ((millis()-oldtime) >refresh) {// обновлять экран каждые 1(2.5) sec //for (int i = 0; i < 3; i++) { // alt=alt+bmp.readAltitude(initP);//усреднить данные по высоте //} //alt=alt/3; alt=bmp.readAltitude(initP); renew=true; oldtime=millis(); } smartDelay(0); return (renew); } //********************************* char *timeRest(void){//ремени осталось до цели, час:мин float v; if (gps.speed.isValid()) v=gps.speed.kmph(); else v=0; float ho;// часы float mi;// минуты десятичные static char Time[6]; byte hx,mx; if (v>10) { hx= (int) (distanceTo/v); mx= round((distanceTo/v-hx)*100)/100*60; } else {hx=99;mx=99;} sprintf(Time, "%02d:%02d", hx,mx) ; return Time; } //********************************* void StopBlinkAlign(void){//цель в створе - не моргать if ((fiTo<=align) || (fiTo>=(360-align))) show=true; else show=!show; } //********************************************** static void smartDelay(unsigned long ms) { //чттобы впустю не время не тратить на простой delay() unsigned long start = millis(); do { while (gps_serial.available()) gps.encode(gps_serial.read()); } while (millis() - start < ms); } //*********************** log****************** void putLog (void) { for (int i=0; i <= logLen-1; i++){ display.writePixel(i,logOffset-logBuff[i], 0); display.writePixel(i,logOffset-logBuff[i]+1, 0); } } //*********************** log****************** void buffLog (void) { for (int i=0; i < logLen-1; i++) logBuff[i]=logBuff[i+1]; //logBuff logBuff[logLen-1]=alt; } // void grid (void){ static int hil = logOffset-20*6; display.setFont(SmallFont1); display.setCursor(53, hil-1); display.print("120"); display.drawLine(logLen,hil,logLen,logOffset,0); for (int i=logOffset; i > hil-1; i=i-20) display.drawLine(0,i,logLen,i,0);//drawLine(logLen-10,i,logLen,i,0); // 156 } //*********************** log****************** void putBiglog (void) { for (int i=0; i <= BiglogLen-1; i++){ display.writePixel(i,BigOffset-BiglogBuff[i], 0); display.writePixel(i,BigOffset-BiglogBuff[i]+1, 0); } } //*********************** log****************** void bufBiglog (void) { for (int i=0; i < BiglogLen-1; i++) BiglogBuff[i]=BiglogBuff[i+1]; //logBuff BiglogBuff[BiglogLen-1]=alt/2.5; } // void bigGrid (void){ static int hiNo; display.setFont(SmallFont1); display.drawLine(w-1,0,w-1,BigOffset,0); hiNo=0; for (int i=BigOffset; i > 1; i=i-20) { display.drawLine(0,i,w-1,i,0); display.setCursor(0,i); display.print(hiNo); hiNo=hiNo+50; } } /* void loop(){//проверка работы парсера while (gps_serial.available()) { // read from gps, write to serial debug port Serial.print(char(gps_serial.read())); gps.encode(gps_serial.read()); } } */
Облагородил и перенес в "Программирование".
valeryLem, на будущее, код вставляйте, как описано в http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
Не смог найти ссылок на то, как и что делать. Не смог отредактировать. Да и у кого спросить - ХЗ.
Не смог найти ссылок на то, как и что делать. Не смог отредактировать. Да и у кого спросить - ХЗ.
Це в "Песочнице". А самый первый пост не редактируется.
Спасибо, добрый человек!.